找回密码
 立即注册

QQ登录

只需一步,快速开始

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

ADC0809+51单片机采集0-5v模拟量

[复制链接]
ID:724208 发表于 2020-4-7 20:14 | 显示全部楼层 |阅读模式
纯原创,此篇只在51黑电子论坛发过,所以不用担心重复。

内容:已知有ADC0809模数转换器,有一模拟电压0—5V,电压高低有电位器控制。
功能:1.使用51单片机完成设计。
                  2.使用0809上的IN3采集模拟电压值。
                 3.将采集到的电压值用3位数码管显示,整数位占1位,显示小数点,小数占两位。
                 4.0809转换的结果以区间的方式用8LED显示。
      原理图:
1.png
      代码如下:
  1. /**************************************/
  2. /*                  功能:ADC转换与显示               */
  3. /*                    AD芯片:ADC0809                  */
  4. /*                    控制器:AT89C52                   */
  5. /*                  主时钟频率:12MHz                  */
  6. /*                     作者:温尔暖                      */
  7. /*                   QQ:648232352                    */
  8. /**************************************/

  9. /******************调用头文件*******************/
  10. #include "reg52.h"
  11. #include "intrins.h"

  12. /*****************定义地址**********************/
  13. sbit KEY   = P1^0;            //按键
  14. sbit ADD_C = P1^2;
  15. sbit ADD_B = P1^3;
  16. sbit ADD_A = P1^4;            // 选输入口

  17. sbit CLK =   P1^5;            // 时钟
  18. sbit START = P1^6;            // 转换启动信号
  19. sbit EOC =   P1^7;            // 转换结束信号
  20. sbit OE =    P1^1;            // 输出允许信号

  21. /*****************定义全局变量********************/
  22. int flag = 0;

  23. /*****************数码管段码**********************/
  24. unsigned char code DUAN[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};    //不带小数点
  25. unsigned char code DUAN1[] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0x80};   //带小数点

  26. /*****************电压值区间******************/
  27. float JS[] = {0,62.5,125,187.5,250,312.5,375,437.5,500};
  28. /*******************读ADC*******************/
  29. void read_adc(void)
  30. {
  31.                 START = 0;
  32.                 _nop_();
  33.                 START = 1;
  34.                 _nop_();
  35.                 START = 0;
  36.                 while(EOC==0);
  37.                 OE=1;
  38. }

  39. /*****************AD值区间计算*********************/
  40. int LED_JS(float AD)
  41. {
  42.         int t0 = 0;
  43.         int i = 0;
  44.         for(; i<8 ;i++)
  45.         {
  46.                 if(AD >= JS[i])
  47.                         if(AD <= JS[i+1])
  48.                                 t0 = i;
  49.         }
  50.         return t0+1;
  51. }

  52. /*****************不精确延时**********************/
  53. void delay_ms(int i)
  54. {
  55.         int j=0;
  56.         while(i--)
  57.         {
  58.                 for(j=0;j<120;j++);
  59.         }
  60. }

  61. /*****************数码管显示**********************/
  62. void display1(unsigned char ADC1_PORT)
  63. {
  64.         int AD1 = ADC1_PORT * 500.0/255.0;
  65.         P2 = 0xFD;   P0 = DUAN1[AD1/100];     delay_ms(5);     // 位选:P2^1  个位
  66.         P2 = 0xFB;   P0 = DUAN[(AD1/10)%10];  delay_ms(5);     // 位选:P2^2  小数点后一位
  67.         P2 = 0xF7;   P0 = DUAN[AD1%10];       delay_ms(5);     // 位选:P2^3  小数点后两位
  68. }

  69. /*****************LED显示**********************/
  70. void display2(unsigned char ADC2_PORT)
  71. {
  72.         float AD2 = ADC2_PORT * 1.96;
  73.         P2 = 0xFF;                  // 清屏
  74.   switch(LED_JS(AD2))
  75.         {
  76.                 case 1: P0 = 0xff; break;
  77.                 case 2: P0 = 0xfe; break;
  78.                 case 3: P0 = 0xfc; break;
  79.                 case 4: P0 = 0xf8; break;
  80.                 case 5: P0 = 0xe0; break;
  81.                 case 6: P0 = 0xc0; break;
  82.                 case 7: P0 = 0x80; break;
  83.                 case 8: P0 = 0x00; break;
  84.                 default:P0 = 0xef;
  85.         }
  86. }

  87. /*******************初始化*******************/
  88. void init()
  89. {
  90.         
  91.         ADD_C=0;
  92.         ADD_B=1;
  93.         ADD_A=1;           // 选择第三通道
  94.         
  95.         CLK=0;             //时钟
  96.         START=1;           // 内部寄存器清零
  97.         EOC=1;             // 转换结束
  98.         OE=0;              // 使能
  99.         
  100.         TMOD=0x02;      // 0000_0010 8位 0~255
  101.         TH0=200;
  102.         TL0=200;        // 装载初值
  103.         EA=1;           // 开总中断
  104.         ET0=1;          // 开定时器中断
  105.         TR0=1;          // 开定时器
  106. }

  107. /****************mAin函数*******************/
  108. void main()
  109. {
  110.         init();         // 初始化
  111.         while(1)
  112.         {
  113.                 if(KEY == 0)               // 检测到按键
  114.                 {
  115.                         delay_ms(5);             // 防抖
  116.                         if(KEY == 0)
  117.                         {
  118.                                 while(!KEY);           // 等松手
  119.                                 flag ++;               // 加1
  120.                                 flag &= 0x01;          // 与0x01相与 保证每次进入flag都为0或1
  121.                         }
  122.                 }
  123.                
  124.                 if(flag == 0)
  125.                 {
  126.                         read_adc();
  127.                         display1(P3);
  128.                         OE=0;
  129.                 }
  130.                
  131.                 if(flag == 1)
  132.                 {               
  133.                         read_adc();
  134.                         display2(P3);
  135.                         OE=0;
  136.                 }
  137.         }
  138. }

  139. /****************中断服务程序*******************/
  140. void TIM0_Serves() interrupt 1         // 用于产生CLK
  141. {
  142.         CLK = !CLK;
  143. }
复制代码
2.png




评分

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

查看全部评分

回复

使用道具 举报

ID:299034 发表于 2020-4-11 23:14 | 显示全部楼层
看到Proteus还以为有人能使用在Proteus中带ADC的单片机仿真。。QWQ
害,感谢楼主分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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