找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2271|回复: 1
收起左侧

单片机双积分AD-数码管 Proteus仿真程序

[复制链接]
ID:312135 发表于 2020-1-4 12:14 | 显示全部楼层 |阅读模式
使用两个运放组成积分电路,比较器电路,结合单片机定时器计数,测量ADC,并使用protues仿真实现
视频连接:https://www.bilibili.com/video/av81800813/

51hei.png

单片机源程序如下:
  1. #include<reg52.h>
  2. //#include<absacc.h>
  3. //#include<intrins.h>
  4. #define uint unsigned int
  5. #define uchar unsigned char
  6. #define GPIO_DIG P0      //传送数据的端口设为P0,以上端口根据实际硬件电路图可做修改

  7. sbit S4=P2^3;
  8. sbit S3=P2^2;         //使能信号
  9. sbit S2=P2^1;         //读写控制信号
  10. sbit S1=P2^0;         //数据命令选择端口

  11. sbit P30=P3^0;
  12. sbit P31=P3^1;
  13. sbit P33=P3^3;
  14. uint ss,vin;
  15. uchar lo,kl = 0;

  16. //--定义全局变量--//
  17. unsigned char code DIG_CODE[10]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
  18. //0、1、2、3、4、5、6、7、8、9的显示码
  19. unsigned char DisplayData[4];
  20. //用来存放要显示的4位数的值

  21. /****************10MS延时函数******************************/
  22. void Delay10ms()                //@12.000MHz
  23. {
  24.         unsigned char i, j;

  25.         i = 20;
  26.         j = 113;
  27.         do
  28.         {
  29.                 while (--j);
  30.         } while (--i);
  31. }


  32. /****************1MS延时函数******************************/

  33. void delay(unsigned int n)
  34. {
  35.     unsigned int i,j;
  36.     for(j=n;j>0;j--)
  37.     for(i=112;i>0;i--);
  38. }


  39. void led_byte(unsigned int byte_data)                //以十进制的方式显示一个字符变量
  40. {

  41.           DisplayData[0] = ~DIG_CODE[(byte_data % 10000 /1000)];                            //求千位数   
  42.           DisplayData[0] |= 0x80;         //小数点
  43.           DisplayData[1] = ~DIG_CODE[(byte_data%1000/100)];                            //求百位数   
  44.           DisplayData[2] = ~DIG_CODE[(byte_data%100/10)];                          //求十位数   
  45.           DisplayData[3] = ~DIG_CODE[(byte_data%10)];                             //求个位数
  46. }

  47. /*******************************************************************************
  48. * 函 数 名         : DigDisplay
  49. * 函数功能                   : 使用数码管显示
  50. * 输    入         : 无
  51. * 输    出         : 无
  52. *******************************************************************************/
  53. void DigDisplay()
  54. {
  55.         unsigned char i;

  56.         led_byte(vin);
  57.         for(i=0;i<4;i++)
  58.         {
  59.                 switch(i)         //位选,选择点亮的数码管,
  60.                 {
  61.                         case(0):
  62.                                 S1=0;S2=1;S3=1;S4=1; break;//显示第0位
  63.                         case(1):
  64.                                 S1=1;S2=0;S3=1;S4=1; break;//显示第1位
  65.                         case(2):
  66.                                 S1=1;S2=1;S3=0;S4=1; break;//显示第2位
  67.                         case(3):
  68.                                 S1=1;S2=1;S3=1;S4=0; break;//显示第3位
  69.                 }
  70.                 GPIO_DIG=DisplayData[i];//发送段码
  71.                 delay(10);                                         //扫描间隔时间设定
  72.                 GPIO_DIG=0x00;//消隐
  73.         }
  74. }
  75. /**************数码管显示*************************/


  76. void my_t0(void) interrupt 1  //定时器0中断用于固定时间对输入待测电压进行积分
  77. {
  78.           TR0 = 0;    //T0中断关                                               ///
  79.           TH0 = 0;
  80.           TL0 = 0;
  81.           lo++;                                                                                ///
  82.           TF0 = 0;   //清除T0中断标志                                          ///
  83.           TR0 = 1;    //T0中断开
  84. }

  85. void my_int0(void) interrupt 0          //外部中断 用于反积分过程结束检测
  86. {
  87.           EX0 = 0;    //INT0中断关
  88.           TR0 = 0;    //T0中断关
  89.           TF0 = 0;   //清除T0中断标志
  90.           ss = TH0 * 256 + TL0;
  91.                   if(ss == 5) ss = vin;  //解决数据缓存溢出BUG
  92.           else  {
  93. //                ss = ss/10 + lo*6553 ;  //计算电压
  94. //          ss = ss/10 + lo*6553 + 37;  //补偿系统误差
  95.                        
  96.                         if((ss % 10000 /1000) < 4)
  97.           vin = ss/10 + lo*6553 + ss/1000;  //补偿系统误差
  98.                         else
  99.                                    vin = ss/10 + lo*6553 + ss/2000;
  100.                 }
  101.           TH0 = 0;
  102.           TL0 = 0;
  103.           kl = 1;                                        
  104.                 lo = 0;               
  105.                 ss = 0;
  106.           EA = 0;
  107. }

  108. void main()
  109. {
  110.   char i = 0;
  111.         P33 = 0;
  112.         P31 = 0;                            ///
  113.         P30 = 1;
  114.         kl = 0;
  115.         EA =  1;   //中断开
  116.         ET0 = 1;   //定时计数0中断开       
  117.         //IP  = 1;    //定时0中断最高优先级 =2
  118.         TMOD = 0x01;        //定时0,1模式1 2个16位定时/计数器
  119.         EX0 = 1;    //INT0中断开

  120.         TCON=0x01;  //INT0负边缘触发或低电平触发在此好象作用相同
  121.         IT0 = 1;

  122.         while(1)
  123.         {

  124.                 if(kl == 1 && i == 20)
  125.                 {
  126.                         ss = 0;
  127.                         lo = 0;
  128.         //                vin = 0;
  129.                           TR0 = 0;
  130.                                 P31 = 0;
  131.                                 P33 = 0;
  132.                                 P30 = 1;   //选择放电                                                ///
  133.                                 delay(100);               
  134.                        
  135.                            kl = 0;
  136.                                 P30 = 0;
  137.                                 P33 = 0;
  138.                                 P31 = 1;    //选择输入电压
  139.                                 Delay10ms();
  140.                        
  141.                                 TH0 = 0;
  142.                                 TL0 = 0;       
  143.                                 P31 = 0;
  144.                                 P33 = 1;     //选择比较电压
  145.                                 TF0 = 0;   //清除T0中断标志
  146.                                 TR0 = 1;   //定时计数0起动
  147.                           EX0 = 1;
  148.                                 EA =  1;
  149.                 }
  150.             i++;
  151.                 if(i==21) i=0;  //彻底完成第一次转换后进行下一次转换,防止互相干扰
  152.                  // delay(1);
  153.                
  154.                
  155.                 delay(1);
  156.     DigDisplay();
  157.                        
  158.         }
  159. }
复制代码
51hei.png
所有资料51hei提供下载:
单片机双积分AD-数码管.rar (89.47 KB, 下载次数: 48)

评分

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

查看全部评分

回复

使用道具 举报

ID:658684 发表于 2021-3-22 15:48 | 显示全部楼层
你好,可以问问你这个双积分程序的思路么?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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