找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于单片机+ADC0809的多路数字电压表设计

  [复制链接]
跳转到指定楼层
楼主
本电路主要采用STC89C51单片机芯片和ADC0809芯片来完成一个简单的电压表,可以对多路在0—5V的模拟直流电压进行测量,并通过一个LCD160显示。制作的全部文件都在压缩包里面,谢谢大家的支持!


制作出来的实物图如下:


电路原理图如下:


八路电压表元件清单
1)    9*15万用板
2)    stc89c51单片机
3)    ADC0809
4)    40脚座
5)    28脚座(宽)
6)    1602液晶
7)    16p母座
8)    16p排针
9)    10uF电解电容
10)    30pF瓷片电容*2
11)    10k电阻*2
12)    1k电阻
13)    按键*3
14)    鳄鱼夹*9(8红1黑)
15)    3p接线端子*3
16)    红黑并线1米
17)    103排阻
18)    103电位器蓝*8
19)    12MHz晶振
20)    自锁开关
21)    DC002接口
22)    导线若干
23)    焊锡若干
24)    USB电源线


以下是程序:
  1. #include<reg52.h>                                   //包含头文件
  2. #include <math.h>
  3. #include "uart.h"
  4. #include "display.h"
  5. #define uint unsigned int
  6. #define uchar unsigned char                   //宏定义
  7. sbit ale=P2^6;
  8. sbit start=P2^7;
  9. sbit eoc=P3^2;
  10. sbit oe=P3^3;                                           //定义adc0809的控制引脚
  11. sbit adda=P2^0;
  12. sbit addb=P2^1;
  13. sbit addc=P2^2;                                           //adc0809的地址引脚
  14. //sbit rs=P2^3;
  15. //sbit rw=P2^4;
  16. //sbit en=P2^5;                                           //液晶的控制引脚
  17. sbit key1=P3^4;
  18. sbit key2=P3^5;
  19. unsigned long voltdata[8];
  20. uint realvolt,i,j,k,l,t,sum,a[5];         //定义全局变量
  21. unsigned char CH;
  22. uchar add;                                                                         //地址变量
  23. uchar TxBuf[8];                //四个显示的位
  24. unsigned char t0Count;
  25. unsigned char flagAu=1;
  26. uchar code t1[]={"DC Voltmeter:IN "};
  27. uchar code t2[]={" (0~20V):  .  V "};
  28. uchar code t3[]={"      Hello!    "};
  29. uchar code t4[]={"     Welcome!   "};                 //初始化显示

  30. /*
  31. 函数说明
  32. */
  33. void addselect()                //量程选择
  34. {
  35.   CH++;                                                //通道号加
  36.   if(CH>7)                                        //最大到7                  符号&:按位与符号,二进制的对应位如果都为1,那么结果的对应位就为1,否则为0
  37.   CH=0;                                                //清零,一共八个通道0 1 2 3 4 5 6 7,对应二进制是0000.0001.0010.0011.0100.0101.0110.0111
  38.   adda=CH&0x01;                                //例如5通道计算方法:将通道对应的二进制0101&0001,结果就是0001,赋值给adda(引脚只能接受最低位的数据,只有1和0),那么adda引脚就是高电平
  39.   addb=(CH&0x02)>>1;                //然后将通道5的二进制0101&0010,结果就是0000(因为所有位都不同),然后整组数据右移一位,赋值给addb,那么addb引脚就是低电平
  40.   addc=(CH&0x04)>>2;                 //然后将通道5的二进制0101&0100,结果就是0100,然后整组数据右移两位,赋值给addc,那么addc引脚就是高电平,最后芯片的通道选择引脚的状态就是101,则选择的就是通道5了
  41.   delay(5);                                        //短延时
  42. }
  43. uint adtrans()                         //AD转换
  44. {
  45.         addselect();
  46.         sum=0;                     //滤波开始
  47.         for (i=0;i<5;i++)           
  48.         {
  49.                 ale=1;
  50.                 ale=0;
  51.                 start=1;                         //启动AD转换。
  52.                 start=0;
  53.                 while(eoc==0);                 //等待转换结束。
  54.                 oe=1;
  55.                 a[i]=P1;             //出入转换结果。
  56.                 delay(5);                  ////每隔5usAD转换并采集一次数据,将得到的数值存入数组中
  57.         }
  58.         for (j=0;j<4;j++)                                
  59.                 for(i=0;i<4-j;i++)
  60.                         if(a[i]>a[i+1])
  61.                         {
  62.                                 t=a[i];
  63.                                 a[i]=a[i+1];
  64.                                 a[i+1]=t;
  65.                         }
  66.         for(i=1;i<4;i++)
  67.         {
  68.                 sum+=a[i];
  69.         }                                  //采用冒泡法比较,取中间3个数值
  70.         voltdata[CH]=sum/3;
  71.         
  72.         delay(1);
  73.         oe=0;
  74.         voltdata[CH]=4*(100*voltdata[CH])/51;                   //处理运算结果。
  75.         //voltdata[CH]是读取到的ad值,乘以100是让小数点后移两位,乘以4是量程扩大四倍也就是5*4=20V,然后除以51(和乘以0.0196一样)得到实际的电压值
  76.         //8位AD最小分辨率就是0.0196V
  77.         return voltdata[CH];
  78. }
  79. void disvolt()                                //显示函数        
  80. {
  81.         realvolt=voltdata[add];
  82.         writelcd_cmd(0x80);
  83.         writelcd_dat('1'+add);
  84.         TxBuf[1]=realvolt/1000+0x30;
  85.         TxBuf[2]=realvolt/100%10+0x30;
  86.         TxBuf[4]=realvolt/10%10+0x30;
  87.         TxBuf[5]=realvolt%10+0x30;                 //将电压值分成4个一位数,方便显示
  88.         writelcd_cmd(0x82);           //显示电压值
  89.         writelcd_dat(TxBuf[1]);
  90.         writelcd_dat(TxBuf[2]);
  91.         writelcd_cmd(0x85);
  92.         writelcd_dat(TxBuf[4]);
  93.         writelcd_dat(TxBuf[5]);
  94.         realvolt=voltdata[add+1];
  95.         writelcd_cmd(0x88);
  96.         writelcd_dat('1'+add+1);
  97.         TxBuf[1]=realvolt/1000+0x30;
  98.         TxBuf[2]=realvolt/100%10+0x30;
  99.         TxBuf[4]=realvolt/10%10+0x30;
  100.         TxBuf[5]=realvolt%10+0x30;                 //将电压值分成4个一位数,方便显示
  101.         writelcd_cmd(0x8a);           //显示电压值
  102.         writelcd_dat(TxBuf[1]);
  103.         writelcd_dat(TxBuf[2]);
  104.         writelcd_cmd(0x8d);
  105.         writelcd_dat(TxBuf[4]);
  106.         writelcd_dat(TxBuf[5]);

  107.         realvolt=voltdata[add+2];
  108.         writelcd_cmd(0xc0);
  109.         writelcd_dat('1'+add+2);
  110.         TxBuf[1]=realvolt/1000+0x30;
  111.         TxBuf[2]=realvolt/100%10+0x30;
  112.         TxBuf[4]=realvolt/10%10+0x30;
  113.         TxBuf[5]=realvolt%10+0x30;                 //将电压值分成4个一位数,方便显示
  114.         writelcd_cmd(0xc2);           //显示电压值
  115.         writelcd_dat(TxBuf[1]);
  116.         writelcd_dat(TxBuf[2]);
  117.         writelcd_cmd(0xc5);
  118.         writelcd_dat(TxBuf[4]);
  119.         writelcd_dat(TxBuf[5]);
  120.         realvolt=voltdata[add+3];
  121.         writelcd_cmd(0xc8);
  122.         writelcd_dat('1'+add+3);
  123.         TxBuf[1]=realvolt/1000+0x30;
  124.         TxBuf[2]=realvolt/100%10+0x30;
  125.         TxBuf[4]=realvolt/10%10+0x30;
  126.         TxBuf[5]=realvolt%10+0x30;                 //将电压值分成4个一位数,方便显示
  127.         writelcd_cmd(0xca);           //显示电压值
  128.         writelcd_dat(TxBuf[1]);
  129.         writelcd_dat(TxBuf[2]);
  130.         writelcd_cmd(0xcd);
  131.         writelcd_dat(TxBuf[4]);
  132.         writelcd_dat(TxBuf[5]);
  133. }
  134. void anjian()                                //按键扫描函数
  135. {

  136.         if(key1==0)                                //第一个按键按下
  137.         {
  138.                  delay(20);
  139.                 if(key1==0)
  140.                 {
  141.                  if(add==0)
  142.                  add=4;
  143.                  else
  144.                  add=0;
  145.                  flagAu=0;
  146.                  while(key1==0);
  147.                 }
  148.         }
  149.         if(key2==0)
  150.         {
  151.                  delay(20);
  152.                 if(key2==0)
  153.                 {
  154.                  
  155.              flagAu=1;
  156.                  while(key2==0);
  157.                 }
  158.         }
  159.                                          //切换档位
  160.         TxBuf[6]=CH+0x31;

  161. }
  162. void init()                                         //初始化函数
  163. {

  164.         add=0;                                
  165.                 addselect();
  166.         lcd_init();                                //液晶显示初始化
  167.     write_string(0x80,"1:  .  V2:  .  V");
  168.         write_string(0xc0,"3:  .  V4:  .  V");
  169.         TxBuf[0]='


  170. ;
  171.         TxBuf[3]='.';
  172.         TxBuf[7]='\0';
  173. }
  174. void main()                                  //主程序
  175. {
  176.         init();                                  //调用初始化函数
  177.         Uart_init();
  178.         while(1)                          //进入while循环
  179.         {   
  180.                 anjian();                  //扫描按键
  181.                 adtrans();                  //ad函数
  182.                 disvolt();                  //显示电压
  183.         }                           
  184. }
  185. void timer0() interrupt 1
  186. {
  187.   TH0=0x4c;
  188.   TL0=0x00;
  189.   t0Count++;
  190.   if(t0Count>=40)
  191.   {
  192.    t0Count=0;
  193.    if(flagAu==1)
  194.    {
  195.     if(add==0)
  196.         add=4;
  197.         else
  198.         add=0;
  199.    }
  200.   }
  201. }
复制代码

全部资料51hei下载地址:
基于单片机的多路数字电压表 C51 ADC0809.7z (518.83 KB, 下载次数: 313)


评分

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

查看全部评分

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

使用道具 举报

沙发
ID:479854 发表于 2019-3-3 08:03 | 只看该作者
第一次发帖,写得不太好,请大家支持,谢谢大家Thanks♪(・ω・)ノ!
回复

使用道具 举报

板凳
ID:236382 发表于 2021-2-25 20:48 | 只看该作者
楼主,想请教一下,仿真图里ADC0808的clock端口有给500KHZ时钟信号,但是我看你的原理图里,是直接把clock端口连接了单片机的30引脚,这样可以正常运行吗?在原理图中需要重新绘制时钟信号吗?
回复

使用道具 举报

地板
ID:902145 发表于 2021-4-20 20:39 | 只看该作者
Mr.Haovia 发表于 2021-2-25 20:48
楼主,想请教一下,仿真图里ADC0808的clock端口有给500KHZ时钟信号,但是我看你的原理图里,是直接把clock ...

我也想问一下楼主这个
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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