找回密码
 立即注册

QQ登录

只需一步,快速开始

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

AT89C2051内部比较器做AD转换器ADC

  [复制链接]
跳转到指定楼层
楼主
    放假研究恒温烙铁,继昨晚研究完1602液晶驱动后,今天继续研究利用AT89C2051内部的电压比较器做廉价的ADC转换器,查阅了一些资料,基本上有这么一些方法:
  1、常规RC电路,对电容充电时间进行计算,通过查表得到AD值。这种AD简单,但分辨率低,仅8位左右。
  2、常规RC电路,对电容充电时间进行计算,通过直接的自然对数反对数运算得到AD值,这种AD电路简单,分辨率高,但程序的运算量很大。2051这种低端单片机不适合此法。
  3、中国欧软采用的办法:外置恒流源,以得到线性的充电曲线,这样单片机的运算工作就会简单很多了。
电路图:

焊接好的电路板:



    程序:

  1. #include <reg51.h>
  2. sbit CMP_R=P3^6;
  3. sbit ADC = P1^1;
  4. unsigned char sled1,sled2,sled3,sled4,sztj;//串行LED扫描数据,状态机
  5. unsigned char temp,temp1,temp2;
  6. unsigned int advalue;
  7. bit timer1overflow;
  8. unsigned char code sledsg[]={0x28,0xEB,0x32,0xA2,0xE1,0xA4,0x24,0xEA,0x20,0xA0,
  9.                              0x60,0x25,0x3C,0x37,0x23,0x34,0x74,0x61,0x65,0x3D,
  10.         0x67,0x68,0x27,0x70,0x77,0x35,0x29,0xF7,0x7F,0xff};//LED段码
  11. void init(void) //初始化函数,就是开机首先要做的事情,init是自己起的名字
  12.      {
  13.   TMOD=0x11; //两个定时器工作于方式1
  14.   PX0=1;  //计时定时器中断优先
  15.   TR0=1;  //定时器0启动
  16.   ET0=1;
  17.   ET1=1;
  18.   EA=1;
  19.   }   //这段程序启动了芯片中的两个定时器
  20. void sledscan(void)      //时速LED模块扫描子程序,定时器调用
  21.      {
  22.   unsigned char datemp;
  23.   switch(sztj)      //切换状态机
  24.     {
  25.     case 0:       //第一状态
  26.     P3=0XFF;       //关闭显示
  27.     datemp=sledsg[sled3];
  28.     P1=0X01;
  29.     P1=P1|(datemp&0xfc);
  30.     P3=P3&(datemp|0xfc);
  31.     P3=P3&0x7f;
  32.     sztj=1;       //转移状态
  33.     break;       //状态结束
  34.     case 1:       //第二状态
  35.     P3=0XFF;       //关闭显示
  36.     datemp=sledsg[sled4];
  37.     P1=0X01;
  38.     P1=P1|(datemp&0xfc);
  39.     P3=P3&(datemp|0xfc);
  40.     P3=P3&0xdf;
  41.     sztj=2;       //转移状态
  42.     break;       //状态结束
  43.     case 2:       //第三状态
  44.     P3=0XFF;       //关闭显示
  45.     datemp=sledsg[sled1];
  46.     P1=0X01;
  47.     P1=P1|(datemp&0xdc);
  48.     P3=P3&(datemp|0xfc);
  49.     P3=P3&0xef;
  50.     sztj=3;
  51.     break;
  52.     case 3:
  53.     P3=0XFF;       //关闭显示
  54.     datemp=sledsg[sled2];
  55.     P1=0X01;
  56.     P1=P1|(datemp&0xfc);
  57.     P3=P3&(datemp|0xfc);
  58.     P3=P3&0xf7;
  59.     sztj=0;
  60.     break;
  61.     default:
  62.     sztj=0;       //异常时捕获状态机
  63.     break;
  64.     }
  65.   }
  66. void timer0 (void) interrupt 1 using 2  //定时器中断程序,定时时间到,自动运行此程序
  67.      {
  68.   TH0=(65536-10000)/256;    //这两行的数值代表每10000us运行一次此程序
  69.   TL0=(65536-10000)%256;    //置定时值,每次时间到都要重新置定时值
  70.   sledscan();      //扫描时速LED模块,122个周期
  71.   }
  72. void timer1 (void) interrupt 3 using 1  //定时器中断程序,定时时间到,自动运行此程序
  73.   {
  74.   TR1=0;
  75.   timer1overflow=1;
  76.   TH1=0XFF;
  77.   TL1=0XFF;
  78.   }
  79. void delay()
  80.   {
  81. while(--temp)
  82.    while(--temp1)
  83.      while(--temp2);//等待电容放电完毕
  84.   }
  85. void main()
  86.   {
  87.   init();
  88.   while(1)
  89.     {
  90. P3=0XFF;//关闭显示
  91. advalue=0;//变量复位
  92. ET0=0;//关闭中断,防止中断干扰
  93. TL1=0X00;
  94. TH1=0X00;
  95. TR1=1;
  96. ADC=1;//开始给电容充电
  97. while(CMP_R&&(!timer1overflow));//等待比较器结果
  98.     timer1overflow=0;
  99. TR1=0;
  100. ADC=0;
  101. ((unsigned char *)&advalue)[0]=TH1;
  102. ((unsigned char *)&advalue)[1]=TL1;
  103. advalue=advalue+1000;
  104. sled1=advalue/10000;//转成十进制
  105. sled2=advalue%10000/1000;
  106. sled3=advalue%1000/100;
  107. sled4=advalue%100/10;
  108. ET0=1;
  109. temp=4;
  110. delay();
  111. }
  112.   }
复制代码




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

使用道具 举报

沙发
ID:70769 发表于 2015-1-1 23:51 | 只看该作者
GOOD!!!
回复

使用道具 举报

板凳
ID:111188 发表于 2016-3-29 21:23 | 只看该作者
先下载看一下,不知道可不可用
回复

使用道具 举报

地板
ID:72088 发表于 2016-9-10 19:58 | 只看该作者
试过了吗,你们谁试过,精度如何
回复

使用道具 举报

5#
ID:72088 发表于 2017-2-15 13:01 | 只看该作者
利用定时器计时加横流充电,精度很高的,我制作过。
很容易达到4位精度
回复

使用道具 举报

6#
ID:230350 发表于 2017-9-1 02:48 | 只看该作者
新乡家电维修 发表于 2017-2-15 13:01
利用定时器计时加横流充电,精度很高的,我制作过。
很容易达到4位精度

用ISIS 7 Professional 仿真后怎么只显示四个 7777
回复

使用道具 举报

7#
ID:517951 发表于 2020-11-15 09:56 | 只看该作者
谢谢楼主分析代码,值得学习
回复

使用道具 举报

8#
ID:137736 发表于 2022-9-26 16:06 | 只看该作者
1305115329 发表于 2017-9-1 02:48
**** 作者被禁止或删除 内容自动屏蔽 ****

好象有人说模型中的89c2051无比较器,而后,有人做了个模型
回复

使用道具 举报

9#
ID:163139 发表于 2022-9-28 20:38 | 只看该作者

太棒了,我一直想制作一个
回复

使用道具 举报

10#
ID:977861 发表于 2022-10-3 13:03 | 只看该作者
学习了,谢谢你的付出
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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