找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3626|回复: 1
打印 上一主题 下一主题
收起左侧

单片机数字示波器仿真与程序分享,希望大家有用

[复制链接]
跳转到指定楼层
楼主
数字示波器仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. #include <AT89X52.h>
  2. #include <intrins.h>
  3. //12864控制引脚定义
  4. sbit DI = P2 ^ 2; //数据\指令选择引脚
  5. sbit RW = P2 ^ 1; //读\写选择引脚
  6. sbit E= P2 ^ 0;   //读\写使能引脚
  7. sbit CS1 = P2 ^ 4;    //片选1引脚
  8. sbit CS2 = P2 ^ 3;    //片选2引脚
  9. sbit BUSY= P1 ^ 7;    //忙标志位
  10. //按键控制定义
  11. sbit Y1 = P3 ^ 0;
  12. sbit Y2 = P3 ^ 1;
  13. sbit X1 = P3 ^ 3;
  14. sbit X2 = P3 ^ 7;
  15. //ADC0832控制引脚
  16. sbit START=P3^4;
  17. sbit OE=P3^6;
  18. sbit EOC=P3^5;

  19. unsigned int ADdata;    //AD采集值
  20. unsigned int Ldata;
  21. unsigned char ye,lei,shu;
  22. unsigned char ADViewdata[91]; //AD显示数据存储区

  23. char code FrameData[]={                     //提示字符存储区                                                                                                                                         
  24. 0x00,0x00,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x01,0x00,
  25. 0x01,0x00,0x11,0x10,0x11,0x08,0x21,0x04,0x41,0x02,0x81,0x02,0x05,0x00,0x02,0x00,    //示
  26. 0x00,0x20,0x20,0x20,0x10,0x20,0x13,0xFE,0x82,0x22,0x42,0x24,0x4A,0x20,0x0B,0xFC,
  27. 0x12,0x84,0x12,0x88,0xE2,0x48,0x22,0x50,0x22,0x20,0x24,0x50,0x24,0x88,0x09,0x06,                //波               
  28. 0x00,0x00,0x3E,0x7C,0x22,0x44,0x22,0x44,0x3E,0x7C,0x01,0x20,0x01,0x10,0xFF,0xFE,
  29. 0x02,0x80,0x0C,0x60,0x30,0x18,0xC0,0x06,0x3E,0x7C,0x22,0x44,0x22,0x44,0x3E,0x7C,    //器
  30. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  31. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    //" "
  32. };
  33. //AD转换软件
  34. void ADCChage()
  35. {
  36.   START=1;
  37.   START=0;
  38.   while(EOC==0)  //等待转换完成
  39. {
  40.    OE=1;
  41. }
  42.   ADdata = P0;   //读取AD数据
  43.         OE=0;
  44. }
  45. //检查12864液晶状态                               
  46. void CheckState()
  47. {
  48.   DI=0;
  49.         RW=1;
  50.         do
  51.         {
  52.           E=1;
  53.           E=0;
  54.    //仅当第7位为0时才可操作(判别busy信号)
  55.         }while(BUSY==1);
  56. }
  57. //向12864写入一个字节的命令
  58. void WriteCommand(unsigned char cmd)        
  59. {
  60.         CheckState();         //检查当前的12864状态
  61.         DI = 0;
  62.         RW = 0;
  63.         P1 = cmd;             //送出相应的命令
  64.         E = 1;
  65.         E = 0;
  66. }  
  67. //向12864写入一个字节的数据
  68. void WriteData(unsigned char dat)               
  69. {
  70.    CheckState();   //检查当前的12864状态
  71.    DI = 1;
  72.    RW = 0;
  73.    P1 = dat;       //送出相应的数据
  74.    E = 1;
  75.    E = 0;
  76. }
  77. //12864液晶的选择控制引脚
  78. void LCMCSControl(unsigned int csl)
  79. {
  80.   if(csl==1)    //根据参数不同判断当前的12864控制引脚状态
  81.   {
  82.     CS1=0,
  83.     CS2=1;
  84.   }
  85.   if(csl==2)
  86.   {
  87.     CS1=1,
  88.     CS2=0;
  89.   }
  90.   if(csl==3)
  91.   {
  92.     CS1=0,
  93.     CS2=0;
  94.   }
  95. }
  96. //12864显示函数
  97. void LCMView()
  98. {
  99.   LCMCSControl(Ldata);     //先发送控制命令
  100.   WriteCommand(ye);
  101.   WriteCommand(lei);
  102.   WriteData(shu);         //然后发送数据
  103. }
  104. //12864的清屏函数
  105. void CleanScreen()                                               
  106. {
  107.         unsigned char page,i;
  108.         LCMCSControl(3);
  109.         for(page=0xb8;page<=0xbf;page++)
  110.         {   
  111.                 WriteCommand(page);
  112.                 WriteCommand(0x40);
  113.                 for(i=0;i<64;i++)
  114.     {
  115.                   WriteData(0x00);
  116.     }
  117.         }
  118.         LCMCSControl(1);
  119.   lei=0x40;
  120.         for(ye=0xb8;ye<0xbf;ye++)
  121.         {
  122.          shu=0xff;
  123.          LCMView();
  124.         }
  125.         ye=0xb8;
  126.         for(lei=0x40;lei<=0x7f;lei++)
  127.         {
  128.           shu=0x80;
  129.           LCMView();
  130.         }
  131.         ye=0xbf;
  132.         for(lei=0x40;lei<=0x7f;lei++)
  133.         {
  134.           shu=0x01;
  135.           LCMView();
  136.         }
  137.   LCMCSControl(2);
  138.   ye=0xb8;
  139.         for(lei=0x40;lei<=0x5b;lei++)
  140.   {
  141.           shu=0x80;
  142.           LCMView();
  143.         }
  144.         ye=0xbf;
  145.         for(lei=0x40;lei<=0x5b;lei++)
  146.         {
  147.           shu=0x01;
  148.           LCMView();
  149.         }
  150.         lei=0x5b;
  151.         for(ye=0xb9;ye<=0xbe;ye++)
  152.         {
  153.          shu=0xff;
  154.          LCMView();
  155.         }
  156. }
  157. //12864的初始化函数
  158. void InitLCM(void)   
  159. {       
  160.   WriteCommand(0xc0);
  161.         WriteCommand(0x3f);
  162. }
  163. //50us的延时函数
  164. void Delay50us(unsigned int t)
  165. {
  166. unsigned char j;  
  167. for(;t>0;t--)   
  168.   for(j=19;j>0;j--);
  169. }
  170. //刷新12864液晶
  171. void RefreshLCM()
  172. {
  173.   unsigned char i;
  174.   for(i=0xb9;i<=0xbe;i++)
  175.   {
  176.     ye=i;
  177.           shu=0x00;
  178.           LCMView();
  179.         }
  180. }
  181. //主函数
  182. void main()
  183. {
  184.     unsigned int r,j,q,k;
  185.     unsigned int Xaxis =0;
  186.     unsigned int Yaxis = 1;
  187.     unsigned char l;
  188.     unsigned char d1,d2,d3,d4,d5;
  189.     CleanScreen();
  190.     InitLCM();
  191.           LCMCSControl(2);
  192.           l=0xb8;
  193.           for(k=0;k<4;k++,l=l+0x02)         //首先显示右侧的提示
  194.           {
  195.             ye=l;
  196.             lei=0x70;
  197.             for(r=0;r<16;r++)
  198.       {
  199.         shu=FrameData[2*r+1+32*k];
  200.               LCMView();
  201.               lei++;
  202.             }
  203.             ye=l+0x01;
  204.             lei=0x70;
  205.             for(r=0;r<16;r++)
  206.       {
  207.         shu=FrameData[2*r+32*k];
  208.               LCMView();
  209.               lei++;
  210.             }
  211.         }
  212.   while(1)
  213.   {
  214.     while(X2==0)      //调节X轴
  215.     {
  216.       while(X2==0);
  217.       Xaxis = Xaxis + 1;
  218.     }
  219.     while(X1==0)
  220.     {
  221.       while(X1==0);
  222.       if(Xaxis!=0)
  223.       {
  224.         Xaxis = Xaxis - 1;
  225.       }
  226.     }
  227.     while(Y1==0)     //调节Y轴
  228.     {
  229.       while(Y1==0);
  230.       Yaxis = Yaxis + 1;
  231.     }
  232.     while(Y2==0)
  233.     {
  234.       while(Y2==0);
  235.       if(Yaxis!=1)
  236.       {
  237.         Yaxis=Yaxis-1;
  238.       }
  239.     }
  240.     for(j=0;j<90;j++) //AD采样最大值
  241.     {
  242.       ADCChage();
  243.       ADViewdata[j]=ADdata;
  244.       if(ADViewdata[j]>ADViewdata[91])
  245.       {
  246.         ADViewdata[91]=ADViewdata[j];
  247.       }
  248.       Delay50us(Xaxis);
  249.     }
  250.     while(ADdata!=ADViewdata[91])    //如果采集值不相等,则继续
  251.     {
  252.       ADCChage();
  253.     }
  254.     for(j=0;j<90;j++)      //连续采样90次
  255.     {
  256.        ADCChage();
  257.        ADViewdata[j]=ADdata;
  258.        Delay50us(Xaxis);
  259.     }
  260.     lei=0x41;
  261.     for(r=0,j=0;r<90;r++,j++)
  262.           {
  263.              if(j<63)
  264.       {
  265.         Ldata=1;
  266.       }
  267.             if(j==63)
  268.       {
  269.         lei=0x40;
  270.       }
  271.             if(j>=63)
  272.       {
  273.         Ldata=2;
  274.       }
  275.             RefreshLCM();     //刷新当前显示
  276.             if(ADViewdata[j>=127])//正电压
  277.             {                             
  278.         ADdata=(ADViewdata[j]-127)*0.196/Yaxis;  //计算电压值
  279.         if(ADdata<=7)      
  280.         {
  281.           ye=0xbb;
  282.           shu=(0x80>>ADdata);
  283.         }
  284.               else if(ADdata<=15)
  285.         {
  286.           ye=0xba;
  287.           shu=(0x80>>(ADdata-8));
  288.         }
  289.         else if(ADdata<=23)
  290.         {
  291.           ye=0xb9;
  292.           shu=(0x80>>(ADdata-16));
  293.          }
  294.         else if(ADdata<=31)
  295.         {
  296.           ye=0xb9;
  297.           shu=(0x80>>(ADdata-24));
  298.         }
  299.             }
  300.             if(ADViewdata[j]<127)     //负电压
  301.             {
  302.                 ADdata=(127-ADViewdata[j])*0.196/Yaxis;    //计算电压值
  303.           if(ADdata<=7)
  304.           {
  305.               ye=0xbc;
  306.               shu=(0x01<<(ADdata));
  307.           }
  308.           else if(ADdata<=15)
  309.           {
  310.               ye=0xbd;
  311.               shu=(0x01<<(ADdata-8));
  312.           }
  313.           else if(ADdata<=23)
  314.           {
  315.               ye=0xbe;
  316.               shu=(0x01<<(ADdata-16));
  317.           }
  318.                 else if(ADdata<=31)
  319.           {
  320.               ye=0xbe;
  321.               shu=(0x01<<(ADdata-24));
  322.           }
  323.             }
  324.       if(r==0)//判断正负
  325.             {
  326.               d1=shu;
  327.               d2=ye;
  328.              }
  329.              if(r!=0)
  330.             {
  331.               d3=shu;
  332.               d4=ye;
  333.               if(ye==d2)  //如果相等,则判断是否显示完成
  334.               {
  335.                 if(shu>d1)
  336.                 {
  337.                   d5=shu;
  338.                   d5=d5>>1;
  339.                   while(d5!=d1)
  340.                   {
  341.               d5=d5>>1;
  342.                     shu=shu|(shu>>1);
  343.             }
  344.                 }
  345.                 if(shu<d1)
  346.                 {
  347.                   d5=shu;
  348.                   d5=d5<<1;
  349.                   while(d5!=d1)
  350.                  {
  351.               d5=d5<<1;
  352.               shu=shu|(shu<<1);
  353.            }
  354.                 }
  355.               }
  356.         if(ye<d2)
  357.               {  
  358.                 for(q=0;q<7;q++)
  359.                 {
  360.                         shu=shu|(shu<<1);
  361.                       }
  362.                     LCMView();
  363.                      ye++;
  364.                     while(ye<d2)
  365.         {
  366.           shu=0xff;
  367.           LCMView();
  368.           ye++;
  369.         }
  370.                     if(ye==d2)
  371.         {
  372.                         shu=0x01;
  373.                                           if(shu<d1)
  374.                   {
  375.                     d5=shu;
  376.                     d5=d5<<1;
  377.                     while(d5!=d1)
  378.                     {
  379.                 d5=d5<<1;
  380.                 shu=shu|(shu<<1);
  381. ……………………

  382. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
数字示波器.rar (74.51 KB, 下载次数: 57)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:710960 发表于 2020-4-10 15:38 | 只看该作者
看完以后学到了很多感谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表