找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7928|回复: 7
收起左侧

单片机+ADC0808的8路数据采集控制系统设计 含仿真与源码

[复制链接]
ID:345053 发表于 2018-6-4 23:28 | 显示全部楼层 |阅读模式
设计了一个关于单片机数据采集控制系统的作品,采用数模转换和模数转换的技术,实现了8路数据采集功能和输出模拟信号的功能

单片机数据采集控制系统

摘要:设计了一个关于单片机数据采集控制系统的作品,采用数模转换和模数转换的技术,实现了8路数据采集功能和输出模拟信号的功能


1 课题意义
单片机数据采集控制系统不只是应用于工业领域,如钢铁、电力、化工,还广泛用于食品,医药、建筑、科研等行业。
在一些工业现场中,设备长时间运行容易出现故障,为了监控这些设备,通常利用数据采集装置采集他们运行时的数据并送给PC机,通过运行在PC机上的特定软件对这些数据进行分析,以此判断当前运行设备的状况,进而采取相应措施。
实时采集来自生产线的产量数据或是不良品的数量、或是生产线的故障类型(如停线、缺料、品质),并传输到数据库系统中;接收来自数据库的信息:如生产计划信息、物料信息等;传输检查工位的不良品名称及数量信息;连接检测仪器,实现检测仪器数字化,数据采集仪自动从测量仪器中获取测量数据,进行记录,分析计算,对测量结果进行自动判断。
2 总体设计方案
11.png

2.1 设计思路
设计基本要求:
1)可实现8路数据的采集,假设8路信号均为0-5V的电压信号;
2)采集数据可通过数码管显示,显示格式为:[通道号] 电压值,如 [01] 4.5
3)具有异常数据声音报警功能:对第一路数据可设置正常数据的上限值和下限值,当采集的数据出现异常,发出报警信号。
4)可输出频率为1kHZ的方波,三角波。
根据上述要求,设计思路如下
选择单片机与A/D转换芯片结合的方法实现本设计。使用 的基本元器件是:AT89C51单片机,ADC0808模数转换芯片,DAC0832数模转换芯片,74ls373地址锁存器,74ls13译码器,74ls148编码器,8位数码管,按键,电容,电阻,晶振,蜂鸣器等。   
数字电压测量电路由A/D转换、数据处理及显示控制等组成。A/D转换由集成电路ADC0808完成。ADC0809具有8路拟输入端口,地址线(IN0-IN7脚)可决定对哪一路模拟输入作A/D换。ALE脚为地址锁存控制,当输入为高电平时,对地址信号进行锁存。START脚为测试控制,当输入一个2uS宽高电平脉冲时,就开始A/D转换。EOC脚为A/D转换结束标志,当A/D转换结束时,7脚输出高电平。OE脚为A/D转换数据输出允许控制,当OE脚为高电平时,A/D转换数据从该端口输出。CLK脚为0809的时钟输入端。单片机的P0.0~P0.7、P3端口作8为数码管显示控制。P2端口作A/D转换数据读入用,P3.0端口用作0809的A/D转换控制。通过对单片机p1.5-1.7口置低电平控制数码管亮灯,p3.1口置低电平时蜂鸣器报警。
模拟信号输出电路由D/A转换、数据处理及显示控制等组成。D/A转换集成电路有DAC0832完成。DAC0832具有8个数字入端口,地址线(D0-D7脚)有8个端口的数字输入作D/A转换。Cs和WR端控制ADC0832转换。RFB端负责输出模拟信号。
2.1.1 方案
  A/D转换器的种类很多,就位数来说,可以分为8位、10位、12位和16位等。位数越高其分辨率就越高,价格也就越贵。A/D转换器型号很多,而其转换时间和转换误差也各不相同。   
(1)逐渐逼近式A/D转换器:它是一种速度快、精度较高、成本较低的直接式转换器,其转换时间在几微秒到几百微秒之间。
(2)双积分A/D转换器:它是一种间接式的A/D转换器,优点是抗干扰能力强,精度比较高,缺点是数度很慢,适用于对转换数度要求不高的系统。   
(3)并行式A/D转换器:它又被称为flash(快速)型,它的转换数度很高,但她采用了很多个比较器,而n位的转换就需要2n-1个比较器,因此电路规模也极大,价格也很贵,只适用于视频A/D转换器等数度特别高的领域。   
方案确立
鉴于上面三种方案,在价格、转换速度等多种标准考量下,在本设计选用的是逐渐逼近式A/D转换器——ADC0808。
2.2 设计方框图
3 设计原理分析
AT89C51芯片是主控电路负责控制模拟电路0832和采集电路0808的工作。模拟信号经过采集电路后转化为数字信号反馈到主控电路AT89C51中,主控电路AT89C51将反馈的模拟信号在显示电路中显示出来。警报电路通过主控电路AT89C51比较数据后的结果决定是否进行警报工作。
  • ADC/DAC功能选择模块:
通过P1^0端口进行控制,当P1^0端口置高电平时进行ADC转换,当P1^0端口置低电平时进行DAC转换。P1^0端口控制了74LS373的使能端电平,进而控制ADC/DAC功能选择。
while(1)
                {
      if(P1_0==1)//判断DAC和ADC
                ADCC();  //ADC转换
                else
                   DAC();//DCA转换            
                }            
  • DAC功能模块:
模拟信号通过模拟信号输入端口IN0-IN7输入到ADC0808芯片中,OUT0-7数字信号输出端口将数字信号输送到74LS237锁存器中,再把信号送到P2端口;
  • 信道选择功能模块:
数字键盘0-7把低电平输出到74LS148编码器中,再通过编码器输出相应的信号控制ADC0808的模拟信道选择地址。
  • 显示功能模块:
P1^5-P1^7端口通过输出信号到74LS138译码器中,译码器输出信号到数码管位选段从而控制显示。P0^0-P0^7端口送数字信号经过74LS373锁存器到数码管显示区中进行相应的数字显示。
  1. for(i=0;i<8;i++)
  2.   {  
  3.      P1_4=1;  
  4.      P1_7=a1[i];//送位选码
  5.               P1_6=b1[i];
  6.               P1_5=c1[i];
  7.               P0=buf[i];  //数据显示  
  8.      delay(2);//亮一段时间   
  9.      P1_4=0;//熄灭掉,否则会形成亮段码干扰                  
  10.   }
复制代码

  • 警报功能模块:
通过比较P2端接受的数字信号和上下限的大小,P3^1输出相应的电平控制蜂鸣器。P3^1输出的低电平蜂鸣器工作,输出高电平蜂鸣器不工作。
P3_1=1; //蜂鸣器不鸣
                if(vv>=MAX)
                {
                P3_1=0;//蜂鸣器响
                }
                if(vv<=MIN)
                {
                P3_1=0;//蜂鸣器响
                }
  • DAC功能模块:
P0^0-P0^7端口输出数字信号经过锁存器74LS373到DAC0832的信号接受端D0-D7中。Cs和WR端控制ADC0832转换。RFB端负责输出模拟信号。
  1. void DAC()
  2. {            
  3.     P3_1=1;
  4.               while(1)   //三角波
  5.    {
  6.     if(P3_7==1)
  7.                 {
  8.                  unsigned char i;
  9.                  for(i=0;i<250;i++)
  10.                  {
  11.                  DAC0832=i;
  12.                  }
  13.                                for(i=250;i>1;i--)
  14.                  {
  15.                  DAC0832=i;
  16.                  }
  17.                 }
  18.               else                                          //方波
  19.               {
  20.               unsigned char i;
  21.               for(i=0;i<250;i++)
  22.               {
  23.                  DAC0832=250;
  24.               }
  25.               for(i=0;i<250;i++)
  26.               {
  27.                  DAC0832=0;
  28.               }
  29.               }
  30.               if(P1_0!=0) //判断是否终止DAC
  31.               break;                            //终止DAC
  32.               }
  33. }
复制代码

3.1 时钟电路的设计
  时钟电路由一个12MHZ晶振和两个30pF电容C1和C2组成。
3.2 控制电路的设计
    控制电路有AT89C51芯片的I/O通过输出高低电平到各个器件的使能端中进行相应的控制。
4 测试
测试方法:分功能逐一测试;
测试过程:
  • 先测试ADC转换功能是否可以执行。在模数转换中发现模数转换结果与测试所用测试电压不一致,在仿真中发现转换结果输送到单片机中只有一瞬间,严重影响单片机AT89C51数据接受。通过添加一个74LS273锁存器对传输结果进行保持,解决上述问题。测试结果:在模数转换中模数转换结果与测试所用测试电压一致。
  • 测试显示功能。通过观察显示的结果与测试数据是否相同。针对显示闪烁,对显示程序中的延时进行调整。测试通过。测试结果:通过观察显示的结果与测试数据相同。
  • 测试信道选择功能。通过对比所选择的信号是否与测试信号一一对应。测试通过。测试结果:
                        通过对比所选择的信号与测试信号一一对应。
  • 测试警报功能。通过不断的调整输入模拟信号来测试警报系统是否会在设定的先下限定中发出警报。测试通过。测试结果模拟信号在超过设定的先下限定中发出警报,正常状态下不发出警报。
  • DAC功能测试。通过示波器观察输出信号与编程所需信号是否一致。测试通过。结果:通过示波器观察输出信号与编程所需信号一致。

5 总结
本课题的主要功能是模拟信号采集并转换功能和数模转换功能。模拟信号采集和转换功能可以应用在医疗中用于采集人体的微电流在转换信号输出于PC端进行观看。数模功能可以应用在扬声器中。
整个设计通过后继的完善应该可以以达到将模拟信号采集后进行转换为数字信号,将对应信息显示在数码管中进行观察。将数字信号超出设置的上下限信号会发出警报,提醒工作人员。同时也可以将收集到的信号进行判断,后输出相应波形的模拟信号。其中8路的信号采集通道可以通过按键进行选择,信号报警上下限也可以通过按键进行调整。
参考文献
[1] 李继凯.数字电子技术与应用 科学出版社,2016
[2] 杨立生.单片机原理与应用项目教程[M].武汉:武汉大学出版社,2015
[3] 阎石.数字电子技术基础(第三版). 北京:高等教育出版社,1989
[4] 廖常初.现场总线概述[J].电工技术,1999.6
附录
              

单片机源程序如下:
  1. #include <reg51.h>
  2. #include <absacc.h>
  3. #define DAC0832 XBYTE[0XFFFE]                //        DAC0832的地址
  4. unsigned char code zixing[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//0-9
  5. unsigned char code zixing1[]={0xbF,0x86,0xdB,0xcF,0xe6,0xeD,0xfD,0x87,0xfF,0xeF};         //0-9
  6. unsigned char buf[]={0x3f,0x3f,0x00,0x00,0x00,0x00,0x00,0x00} ;           //显示缓冲区
  7. unsigned char c1[]={1,1,1,1,0,0,0,0};  //数码管选位
  8. unsigned char b1[]={1,1,0,0,1,1,0,0};          //数码管选位
  9. unsigned char a1[]={1,0,1,0,1,0,1,0};        //数码管选位
  10. unsigned char ad_data;//定义成全局变量,以便主函数和中断函数都能引用
  11. unsigned char i,j;  
  12. unsigned char TD;  
  13. unsigned int MAX;
  14. unsigned int MIN;
  15. unsigned int dig,dd;
  16. unsigned int Aa,Bb,Cc,xuhao,df;
  17. long int vv;
  18. sbit P3_0=P3^0;
  19. sbit P3_1=P3^1;
  20. sbit P3_4=P3^4;
  21. sbit P3_7=P3^7;
  22. sbit P1_0=P1^0;
  23. sbit P1_1=P1^1;
  24. sbit P1_2=P1^2;
  25. sbit P1_3=P1^3;
  26. sbit P1_4=P1^4;
  27. sbit P1_5=P1^5;
  28. sbit P1_6=P1^6;
  29. sbit P1_7=P1^7;
  30. void delay(unsigned int time); //子程序声明  
  31. void ADC();
  32. void xianshi();
  33. void xianding();
  34. void jingbao();
  35. void ADCC();
  36. void DAC();
  37. void main()
  38. {    EA=1;               
  39.       EX0=1;
  40.           EX1=1;
  41.       ET0=1;
  42.           ET1=1;
  43.       IT0=1;
  44.           IT1=1;
  45.       PX0=1;
  46.       MAX=40; //电压上限赋初值
  47.       MIN=10; //电压下限赋初值        
  48.           while(1)
  49.           {
  50.       if(P1_0==1)//判断DAC和ADC
  51.           ADCC();  //ADC转换
  52.           else
  53.              DAC();//DCA转换        
  54.           }                                                                                            
  55. }//main end
  56. void delay(unsigned int time)        //延时
  57. {   
  58.    unsigned int i,j;
  59.    for(i=0;i<time;i++)
  60.    for(j=0;j<60;j++) ;
  61.   }
  62. void ADC()                //模数转换程序
  63. {        
  64.     TD=P3;
  65.           Aa=Bb=Cc=0;
  66.         if(P1_3==1)
  67.         {
  68.          Cc=4;
  69.         }
  70.         if(P1_2==1)
  71.         {
  72.          Bb=2;
  73.         }
  74.         if(P1_1==1)
  75.         {
  76.          Aa=1;
  77.         }
  78.         xuhao=Aa+Bb+Cc;//信道序号
  79.     buf[1]=zixing[xuhao];//将数字转换成字型码放入显示缓冲区                           
  80.     ad_data=P2;//读取转换完成的数字量
  81.         vv=(5*ad_data/255.0)*10;//扩大10以便显示出小数点后的1位数         
  82.                                                 //除以255.0时先转换成浮点数,而乘10后,又将乘积的结果浮点数转换成整型数
  83.         dig=vv%10;//取模要余数得出低位   
  84.         buf[3]=zixing[dig];//将数字转换成字型码放入显示缓冲区   
  85.         dig=vv/10;//求商
  86.     buf[2]=zixing1[dig]; //将数字转换成字型码放入显示缓冲区
  87. }
  88. void xianshi()                 //数码管显示程序
  89. {

  90.   for(i=0;i<8;i++)  
  91.   {   
  92.      P1_4=1;   
  93.      P1_7=a1[i];//送位选码
  94.          P1_6=b1[i];
  95.          P1_5=c1[i];
  96.          P0=buf[i];  //数据显示   
  97.      delay(2);//亮一段时间   
  98.      P1_4=0;//熄灭掉,否则会形成亮段码干扰              
  99.   }   
  100. }
  101. void jingbao()        //警报程序
  102. {
  103.             P3_1=1; //蜂鸣器不鸣
  104.           if(vv>=MAX)
  105.           {
  106.           P3_1=0;//蜂鸣器响
  107.           }
  108.           if(vv<=MIN)
  109.           {
  110.           P3_1=0;//蜂鸣器响
  111.           }
  112. }
  113. void up() interrupt 0         //上限电压调整中断
  114. {        
  115.     if(P3_4==1)
  116.     {
  117.     MAX++;
  118.         }
  119.         else
  120.         {
  121.         MAX--;
  122.         }
  123. }
  124. void down() interrupt 2           //下限电压调整中断
  125. {
  126.     if(P3_4==1)
  127.     {
  128.     MIN++;
  129.         }
  130.         else
  131.         {
  132.         MIN--;
  133.         }
  134. }
  135. void xianding()           //上下限警报电压扫描程序
  136. {     
  137.       dd=MAX/10;                 //求商
  138.           buf[4]=zixing1[dd]; //将数字转换成字型码放入显示缓冲区
  139.           dd=MAX%10;                 //取模要余数得出低位
  140.           buf[5]=zixing[dd]; //将数字转换成字型码放入显示缓冲区
  141.           dd=MIN/10;                 //求商
  142.           buf[6]=zixing1[dd]; //将数字转换成字型码放入显示缓冲区
  143.           dd=MIN%10;                 //取模要余数得出低位
  144.           buf[7]=zixing[dd]; //将数字转换成字型码放入显示缓冲区
  145. }
  146. void ADCC()
  147. {                     
  148.           while(1)
  149.           {           
  150.           P3_0=0;        
  151.           P3_0=1;
  152.       P3_0=0; //ADC0808转换开始
  153.           if(TD!=P3) //检测adc转换信道是否发生变化
  154.           {
  155.           ADC();//模数转换程序
  156.           }              
  157.           if(ad_data!=P2) //检测adc转换信号是否发生变化
  158.           {        
  159.           ADC();   //模数转换程序
  160.           }
  161.           xianding();  //上下限警报电压设置程序
  162.           jingbao();   //警报程序
  163.           xianshi();   //数码管显示程序
  164.           if(P1_0!=1)//判断是否终止ADC
  165.           break;          //终止ADC
  166.       }                                                                                                              
  167. }
  168. void DAC()
  169. {        
  170.     P3_1=1;
  171.         while(1)   //三角波
  172.    {  
  173.     if(P3_7==1)
  174.           {
  175.            unsigned char i;
  176.            for(i=0;i<250;i++)
  177.            {
  178.            DAC0832=i;
  179.            }
  180.                    for(i=250;i>1;i--)
  181. ……………………

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

0.png

所有资料51hei提供下载:
8路数据采集控制系统.zip (801.18 KB, 下载次数: 147)

评分

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

查看全部评分

回复

使用道具 举报

ID:253209 发表于 2018-6-5 23:21 | 显示全部楼层
感谢分享,,正好需要,Keil5编译成功了
51hei.png
回复

使用道具 举报

ID:8455 发表于 2018-6-6 17:00 | 显示全部楼层
多谢分享,学习下。
回复

使用道具 举报

ID:566495 发表于 2019-6-19 10:11 | 显示全部楼层
很棒正好需要
回复

使用道具 举报

ID:612661 发表于 2019-9-17 16:51 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:612661 发表于 2019-9-17 16:55 | 显示全部楼层
感谢分享,正好需要
回复

使用道具 举报

ID:612661 发表于 2019-9-18 09:13 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:936097 发表于 2021-6-10 16:16 | 显示全部楼层
你好我用这个程序在WORD这报错怎么办呢
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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