找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

帖子
查看: 11625|回復(fù): 18
收起左側(cè)

單片機(jī)+LCD12864數(shù)字示波器程序+Proteus仿真

  [復(fù)制鏈接]
ID:517871 發(fā)表于 2019-5-9 17:25 | 顯示全部樓層 |閱讀模式
基于51單片機(jī)和Proteus仿真的數(shù)字示波器
數(shù)字示波器.png 51hei.png

單片機(jī)源程序如下:
#include <AT89X52.h>
#include <intrins.h>
//12864控制引腳定義
sbit DI = P2 ^ 2; //數(shù)據(jù)\指令選擇引腳
sbit RW = P2 ^ 1; //讀\寫選擇引腳
sbit E= P2 ^ 0;   //讀\寫使能引腳
sbit CS1 = P2 ^ 4;    //片選1引腳
sbit CS2 = P2 ^ 3;    //片選2引腳
sbit BUSY= P1 ^ 7;    //忙標(biāo)志位
//按鍵控制定義
sbit Y1 = P3 ^ 0;
sbit Y2 = P3 ^ 1;
sbit X1 = P3 ^ 3;
sbit X2 = P3 ^ 7;
//ADC0832控制引腳
sbit START=P3^4;
sbit OE=P3^6;
sbit EOC=P3^5;

unsigned int ADdata;    //AD采集值
unsigned int Ldata;
unsigned char ye,lei,shu;
unsigned char ADViewdata[91]; //AD顯示數(shù)據(jù)存儲(chǔ)區(qū)

char code FrameData[]={                     //提示字符存儲(chǔ)區(qū)                                                                                                                                         
0x00,0x00,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x01,0x00,
0x01,0x00,0x11,0x10,0x11,0x08,0x21,0x04,0x41,0x02,0x81,0x02,0x05,0x00,0x02,0x00,    //示
0x00,0x20,0x20,0x20,0x10,0x20,0x13,0xFE,0x82,0x22,0x42,0x24,0x4A,0x20,0x0B,0xFC,
0x12,0x84,0x12,0x88,0xE2,0x48,0x22,0x50,0x22,0x20,0x24,0x50,0x24,0x88,0x09,0x06,                //波               
0x00,0x00,0x3E,0x7C,0x22,0x44,0x22,0x44,0x3E,0x7C,0x01,0x20,0x01,0x10,0xFF,0xFE,
0x02,0x80,0x0C,0x60,0x30,0x18,0xC0,0x06,0x3E,0x7C,0x22,0x44,0x22,0x44,0x3E,0x7C,    //器
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    //" "
};
//AD轉(zhuǎn)換軟件
void ADCChage()
{
  START=1;
  START=0;
  while(EOC==0)  //等待轉(zhuǎn)換完成
{
   OE=1;
}
  ADdata = P0;   //讀取AD數(shù)據(jù)
        OE=0;
}
//檢查12864液晶狀態(tài)                              
void CheckState()
{
  DI=0;
        RW=1;
        do
        {
          E=1;
          E=0;
   //僅當(dāng)?shù)?位為0時(shí)才可操作(判別busy信號(hào))
        }while(BUSY==1);
}
//向12864寫入一個(gè)字節(jié)的命令
void WriteCommand(unsigned char cmd)         
{
        CheckState();         //檢查當(dāng)前的12864狀態(tài)
        DI = 0;
        RW = 0;
        P1 = cmd;             //送出相應(yīng)的命令
        E = 1;
        E = 0;
}  
//向12864寫入一個(gè)字節(jié)的數(shù)據(jù)
void WriteData(unsigned char dat)               
{
   CheckState();   //檢查當(dāng)前的12864狀態(tài)
   DI = 1;
   RW = 0;
   P1 = dat;       //送出相應(yīng)的數(shù)據(jù)
   E = 1;
   E = 0;
}
//12864液晶的選擇控制引腳
void LCMCSControl(unsigned int csl)
{
  if(csl==1)    //根據(jù)參數(shù)不同判斷當(dāng)前的12864控制引腳狀態(tài)
  {
    CS1=0,
    CS2=1;
  }
  if(csl==2)
  {
    CS1=1,
    CS2=0;
  }
  if(csl==3)
  {
    CS1=0,
    CS2=0;
  }
}
//12864顯示函數(shù)
void LCMView()
{
  LCMCSControl(Ldata);     //先發(fā)送控制命令
  WriteCommand(ye);
  WriteCommand(lei);
  WriteData(shu);         //然后發(fā)送數(shù)據(jù)
}
//12864的清屏函數(shù)
void CleanScreen()                                                
{
        unsigned char page,i;
        LCMCSControl(3);
        for(page=0xb8;page<=0xbf;page++)
        {   
                WriteCommand(page);
                WriteCommand(0x40);
                for(i=0;i<64;i++)
    {
                  WriteData(0x00);
    }
        }
        LCMCSControl(1);
  lei=0x40;
        for(ye=0xb8;ye<0xbf;ye++)
        {
         shu=0xff;
         LCMView();
        }
        ye=0xb8;
        for(lei=0x40;lei<=0x7f;lei++)
        {
          shu=0x80;
          LCMView();
        }
        ye=0xbf;
        for(lei=0x40;lei<=0x7f;lei++)
        {
          shu=0x01;
          LCMView();
        }
  LCMCSControl(2);
  ye=0xb8;
        for(lei=0x40;lei<=0x5b;lei++)
  {
          shu=0x80;
          LCMView();
        }
        ye=0xbf;
        for(lei=0x40;lei<=0x5b;lei++)
        {
          shu=0x01;
          LCMView();
        }
        lei=0x5b;
        for(ye=0xb9;ye<=0xbe;ye++)
        {
         shu=0xff;
         LCMView();
        }
}
//12864的初始化函數(shù)
void InitLCM(void)   
{        
  WriteCommand(0xc0);
        WriteCommand(0x3f);
}
//50us的延時(shí)函數(shù)
void Delay50us(unsigned int t)
{
unsigned char j;  
for(;t>0;t--)   
  for(j=19;j>0;j--);
}
//刷新12864液晶
void RefreshLCM()
{
  unsigned char i;
  for(i=0xb9;i<=0xbe;i++)
  {
    ye=i;
          shu=0x00;
          LCMView();
        }
}
//主函數(shù)
void main()
{
    unsigned int r,j,q,k;
    unsigned int Xaxis =0;
    unsigned int Yaxis = 1;
    unsigned char l;
    unsigned char d1,d2,d3,d4,d5;
    CleanScreen();
    InitLCM();
          LCMCSControl(2);
          l=0xb8;
          for(k=0;k<4;k++,l=l+0x02)         //首先顯示右側(cè)的提示
          {
            ye=l;
            lei=0x70;
            for(r=0;r<16;r++)
      {
        shu=FrameData[2*r+1+32*k];
              LCMView();
              lei++;
            }
            ye=l+0x01;
            lei=0x70;
            for(r=0;r<16;r++)
      {
        shu=FrameData[2*r+32*k];
              LCMView();
              lei++;
            }
        }
  while(1)
  {
    while(X2==0)      //調(diào)節(jié)X軸
    {
      while(X2==0);
      Xaxis = Xaxis + 1;
    }
    while(X1==0)
    {
      while(X1==0);
      if(Xaxis!=0)
      {
        Xaxis = Xaxis - 1;
      }
    }
    while(Y1==0)     //調(diào)節(jié)Y軸
    {
      while(Y1==0);
      Yaxis = Yaxis + 1;
    }
    while(Y2==0)
    {
      while(Y2==0);
      if(Yaxis!=1)
      {
        Yaxis=Yaxis-1;
      }
    }
    for(j=0;j<90;j++) //AD采樣最大值
    {
      ADCChage();
      ADViewdata[j]=ADdata;
      if(ADViewdata[j]>ADViewdata[91])
      {
        ADViewdata[91]=ADViewdata[j];
      }
      Delay50us(Xaxis);
    }
    while(ADdata!=ADViewdata[91])    //如果采集值不相等,則繼續(xù)
    {
      ADCChage();
    }
    for(j=0;j<90;j++)      //連續(xù)采樣90次
    {
       ADCChage();
       ADViewdata[j]=ADdata;
       Delay50us(Xaxis);
    }
    lei=0x41;
    for(r=0,j=0;r<90;r++,j++)
          {
             if(j<63)
      {
        Ldata=1;
      }
            if(j==63)
      {
        lei=0x40;
      }
            if(j>=63)
      {
        Ldata=2;
      }
            RefreshLCM();     //刷新當(dāng)前顯示
            if(ADViewdata[j>=127])//正電壓
            {                             
        ADdata=(ADViewdata[j]-127)*0.196/Yaxis;  //計(jì)算電壓值
        if(ADdata<=7)      
        {
          ye=0xbb;
          shu=(0x80>>ADdata);
        }
              else if(ADdata<=15)
        {
          ye=0xba;
          shu=(0x80>>(ADdata-8));
        }
        else if(ADdata<=23)
        {
          ye=0xb9;
          shu=(0x80>>(ADdata-16));
         }
        else if(ADdata<=31)
        {
          ye=0xb9;
          shu=(0x80>>(ADdata-24));
        }
            }
            if(ADViewdata[j]<127)     //負(fù)電壓
            {
                ADdata=(127-ADViewdata[j])*0.196/Yaxis;    //計(jì)算電壓值
          if(ADdata<=7)
          {
              ye=0xbc;
              shu=(0x01<<(ADdata));
          }
          else if(ADdata<=15)
          {
              ye=0xbd;
              shu=(0x01<<(ADdata-8));
          }
          else if(ADdata<=23)
          {
              ye=0xbe;
              shu=(0x01<<(ADdata-16));
          }
                else if(ADdata<=31)
          {
              ye=0xbe;
              shu=(0x01<<(ADdata-24));
          }
            }
      if(r==0)//判斷正負(fù)
            {
              d1=shu;
              d2=ye;
             }
             if(r!=0)
            {
              d3=shu;
              d4=ye;
              if(ye==d2)  //如果相等,則判斷是否顯示完成
              {
                if(shu>d1)
                {
                  d5=shu;
                  d5=d5>>1;
                  while(d5!=d1)
                  {
              d5=d5>>1;
                    shu=shu|(shu>>1);
            }
                }
                if(shu<d1)
                {
                  d5=shu;
                  d5=d5<<1;
                  while(d5!=d1)
                 {
              d5=d5<<1;
              shu=shu|(shu<<1);
           }
                }
              }
        if(ye<d2)
              {  
                for(q=0;q<7;q++)
                {
                        shu=shu|(shu<<1);
                      }
                    LCMView();
                     ye++;
                    while(ye<d2)
        {
          shu=0xff;
          LCMView();
          ye++;
        }
                    if(ye==d2)
        {
                        shu=0x01;
                                          if(shu<d1)
                  {
                    d5=shu;
                    d5=d5<<1;
                    while(d5!=d1)
                    {
                d5=d5<<1;
                shu=shu|(shu<<1);
               }
                   }
                                          }
        }
              if(ye>d2)
              {
                for(q=0;q<7;q++)
                {
                        shu=shu|(shu>>1);
                      }
                    LCMView();
                     ye--;
                    while(ye>d2) {shu=0xff,LCMView(),ye--;}
                    if(ye==d2)
        {
                        shu=0x80;
                                          if(shu>d1)
                  {
                    d5=shu;
                    d5=d5>>1;
                    while(d5!=d1)
                    {
                d5=d5>>1;
                shu=shu|(shu>>1);
               }
                   }
                                }
      }
          }
          if(r!=0)
          {
            d1=d3;
            d2=d4;
          }
    LCMView();
    if(lei!=0x7f)
    {
      lei++;
    }
   }
        }
}
        
Keil代碼與Proteus7.5版本的dsn文件下載:
基于51單片機(jī)和Proteus仿真的數(shù)字示波器.zip (81.01 KB, 下載次數(shù): 420)
回復(fù)

使用道具 舉報(bào)

ID:262 發(fā)表于 2022-3-21 23:42 | 顯示全部樓層
1101721 發(fā)表于 2022-3-21 20:09
參考價(jià)值不大,沒(méi)有proteus圖就純代碼還是錯(cuò)誤的

有仿真 但是必須得Proteus7.5才能打開,程序是能出一個(gè)三角波 其他沒(méi)多看
回復(fù)

使用道具 舉報(bào)

ID:537018 發(fā)表于 2019-5-15 17:56 | 顯示全部樓層
厲害!
回復(fù)

使用道具 舉報(bào)

ID:539208 發(fā)表于 2019-5-15 19:32 | 顯示全部樓層
好東西值得收藏與學(xué)習(xí)好東西值得收藏與學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

ID:596590 發(fā)表于 2019-8-9 08:36 | 顯示全部樓層
主程序直接到底,看的有點(diǎn)頭痛,不過(guò)畢竟是好東西,功能挺強(qiáng)大的。
回復(fù)

使用道具 舉報(bào)

ID:639790 發(fā)表于 2019-11-30 20:15 | 顯示全部樓層
認(rèn)真學(xué)習(xí),加油
回復(fù)

使用道具 舉報(bào)

ID:653323 發(fā)表于 2019-12-1 00:41 來(lái)自觸屏版 | 顯示全部樓層
不錯(cuò),學(xué)學(xué)
回復(fù)

使用道具 舉報(bào)

ID:651779 發(fā)表于 2019-12-1 10:34 來(lái)自觸屏版 | 顯示全部樓層
感謝樓主的慷慨大方
回復(fù)

使用道具 舉報(bào)

ID:668688 發(fā)表于 2020-1-29 20:48 | 顯示全部樓層
認(rèn)真學(xué)習(xí)中,加油
回復(fù)

使用道具 舉報(bào)

ID:688516 發(fā)表于 2020-1-29 22:57 來(lái)自觸屏版 | 顯示全部樓層
下載的文件手機(jī)不能打開嗎,親
回復(fù)

使用道具 舉報(bào)

ID:255258 發(fā)表于 2020-6-24 22:40 | 顯示全部樓層
我下載了,使用電腦打開的,非常好用
回復(fù)

使用道具 舉報(bào)

ID:664972 發(fā)表于 2020-7-2 09:47 | 顯示全部樓層
沒(méi)有仿真圖 打不開 程序也打不開 白白浪費(fèi)了黑幣
回復(fù)

使用道具 舉報(bào)

ID:328014 發(fā)表于 2020-7-2 13:43 | 顯示全部樓層
雅楠太難了 發(fā)表于 2020-7-2 09:47
沒(méi)有仿真圖 打不開 程序也打不開 白白浪費(fèi)了黑幣

有Proteus仿真7.5的版本  程序也可以用Keil4打開啊?我剛測(cè)試了
回復(fù)

使用道具 舉報(bào)

ID:478073 發(fā)表于 2020-7-29 08:37 | 顯示全部樓層
這個(gè)是很好的帖子,值得推廣!
回復(fù)

使用道具 舉報(bào)

ID:710460 發(fā)表于 2020-8-13 22:03 | 顯示全部樓層
我認(rèn)真看了樓主寫的程序,可讀性太差了;
像我這樣的新手,要讀懂你的程序太費(fèi)力。
程序沒(méi)有模塊化,部分功能最好是寫成函數(shù),這樣有助于提高可讀性
回復(fù)

使用道具 舉報(bào)

ID:446567 發(fā)表于 2020-8-14 08:59 | 顯示全部樓層
不錯(cuò),非常好的例子。
回復(fù)

使用道具 舉報(bào)

ID:918467 發(fā)表于 2021-10-26 13:38 | 顯示全部樓層
請(qǐng)問(wèn)有原理圖嗎
回復(fù)

使用道具 舉報(bào)

ID:440028 發(fā)表于 2022-1-6 08:44 | 顯示全部樓層
我感覺這個(gè)程序如果用到感溫上也不錯(cuò)
回復(fù)

使用道具 舉報(bào)

ID:1011007 發(fā)表于 2022-3-21 20:09 | 顯示全部樓層
參考價(jià)值不大,沒(méi)有proteus圖就純代碼還是錯(cuò)誤的
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表