找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机入门经验分享6-利用STC单片机的ADC采集电压

  [复制链接]
跳转到指定楼层
楼主
ID:74187 发表于 2018-10-13 09:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
利用STC单片机的ADC采集电压


在实际开发中,AD,DA用的相当多,这一节,我们写一个程序,将采集到的电压数值显示在数码管上,程序如下:
  1. /*******************************************************************************
  2. * 文件名: ADC转换器使用
  3. * 描  述: 电池电压
  4. * 功  能:中断方式 11.059200MHZ
  5. * 作  者:大核桃
  6. * 版本号:1.0.1(2017.05.23)
  7. *******************************************************************************/
  8. #include "stc15w.h"//头文件
  9. #include "intrins.h"


  10. /*******************************************************************************
  11. * 文件名: 重定义
  12. * 描  述:   
  13. * 功  能:
  14. * 作  者:大核桃
  15. * 版本号:1.0.1(2017.05.23)
  16. *******************************************************************************/
  17. typedef unsigned char uint8;
  18. typedef unsigned int  uint16;
  19. typedef unsigned long uint32;

  20. #define ADC_POWER   0x80            //ADC电源控制位
  21. #define ADC_FLAG    0x10            //ADC完成标志
  22. #define ADC_START   0x08            //ADC起始控制位
  23. #define ADC_SPEEDLL 0x00            //540个时钟

  24. /*******************************************************************************
  25. * 文件名:全局变量定义区域
  26. * 描  述:
  27. * 功  能:
  28. * 作  者:大核桃
  29. * 版本号:1.0.1(2015.03.03)
  30. *******************************************************************************/
  31. uint8 val,ch;
  32. uint16 temp;
  33. /*******************************************************************************
  34. * 文件名:共阳数码管真值表
  35. * 描  述:
  36. * 功  能:
  37. * 作  者:大核桃
  38. * 版本号:1.0.1(2015.03.03)
  39. *******************************************************************************/
  40. code uint8 LedChar[] = {
  41.         0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
  42.         0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xc1
  43. };

  44. /*******************************************************************************
  45. * 文件名:单独位定义
  46. * 描  述:   
  47. * 功  能:
  48. * 作  者:大核桃
  49. * 版本号:1.0.1(2017.05.23)
  50. *******************************************************************************/
  51. sbit LED0 = P1^0;//第1组LED
  52. sbit LED1 = P1^1;//第2组LED
  53. sbit LED2 = P1^2;//第3组LED                                 
  54. sbit LED3 = P1^3;//第4组LED
  55. sbit LED4 = P1^4;//第5组LED
  56. sbit LED5 = P3^2;//第6组LED
  57. sbit LED6 = P0^0;//第7组LED
  58. sbit LED7 = P0^1;//第8组LED

  59. sbit LEDS1 = P3^3;//数码管1
  60. sbit LEDS2 = P3^4;//数码管2
  61. sbit LEDS3 = P3^6;//数码管3
  62. sbit LEDS4 = P3^7;//数码管4

  63. /*******************************************************************************
  64. * 文件名:函数前置声明
  65. * 描  述:   
  66. * 功  能:
  67. * 作  者:大核桃
  68. * 版本号:1.0.1(2017.05.23)
  69. *******************************************************************************/
  70. void Mcu_Port_Init();
  71. void LedScan();
  72. void Delay500ms(); //24MHZ
  73. void Time0_Init();//定时器0
  74. void InitADC(void);

  75. /*******************************************************************************
  76. * 文件名
  77. * 描  述: 主函数  
  78. * 功  能:入口
  79. * 作  者:大核桃
  80. * 版本号:1.0.1(2017.05.23)
  81. *******************************************************************************/
  82. void main(void)
  83. {                                       
  84.         Mcu_Port_Init();//IO上电初始化
  85.         Time0_Init();
  86.         InitADC();
  87.         while(1);
  88. }

  89. /*******************************************************************************
  90. * 文件名:void LedScan()
  91. * 描  述: LED刷新
  92. * 功  能:
  93. * 作  者:大核桃
  94. * 版本号:1.0.1(2017.05.23)
  95. *******************************************************************************/
  96. void LedScan()
  97. {
  98.         static uint8 i = 0;

  99.         P2 = 0Xff;
  100.         switch(i)
  101.         {
  102.                 case 0: LEDS4 = 0;LEDS1 = 1;P2 = 0x7f & LedChar[16];i++;break;
  103.                 case 1: LEDS1 = 0;LEDS2 = 1;P2 = LedChar[val / 10 % 10];i++;break;
  104.                 case 2: LEDS2 = 0;LEDS3 = 1;P2 = LedChar[val % 10];i++;break;
  105.                 case 3: LEDS3 = 0;LEDS4 = 1;P2 = LedChar[17];i = 0;break;

  106.                 default:break;
  107.         }
  108. }

  109. /*******************************************************************************
  110. * 文件名:void InitADC(void)
  111. * 描  述: //初始化 AD 转换
  112. * 功  能:
  113. * 作  者:大核桃
  114. * 版本号:1.0.1(2015.03.03)
  115. *******************************************************************************/
  116. void InitADC(void)
  117. {
  118.         P1ASF = 0xE0; //设置 P1 口为模拟口
  119.         ADC_RES = 0; //清除结果寄存器
  120.         CLK_DIV |= 0x20; //ADRJ 为 1,ADC_RES 存放高两位结果,ADC_RESL 存放低 8 位结果
  121.     //ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START;
  122.         ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START;                    //ADC上电并延时
  123. }

  124. /*******************************************************************************
  125. * 文件名:void adc_isr() interrupt 5 using 1
  126. * 描  述: 中断服务程序
  127. * 功  能:
  128. * 作  者:大核桃
  129. * 版本号:1.0.1(2015.03.03)
  130. *******************************************************************************/
  131. void adc_isr() interrupt 5 using 1
  132. {
  133.         EADC = 1; //允许ADC转换中断
  134.         ET0 = 0;  //关闭定时器0中断

  135.         ADC_CONTR &= !ADC_FLAG; //清除ADC中断标志
  136.         temp = ADC_RES;
  137.         temp <<= 8;
  138.         temp |= ADC_RESL;

  139.         ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | 5;
  140.         EADC = 0;//关闭ADC转换
  141.         ET0 = 1;  //打开定时器0中断        

  142. }

  143. /*******************************************************************************
  144. * 文件名:void VoltageCheckRefresh()
  145. * 描  述: 电压检测
  146. * 功  能:
  147. * 作  者:大核桃
  148. * 版本号:1.0.1(2015.03.03)
  149. *******************************************************************************/
  150. void VoltageCheckRefresh()
  151. {
  152.         val = (uint8)((temp)* 2 * 10 * 3.3 / 1023);                        
  153. }

  154. /*******************************************************************************
  155. * 文件名:void Time0_Init()
  156. * 描  述: 定时器0初始化
  157. * 功  能:10毫秒@11.0592MHz
  158. * 作  者:大核桃
  159. * 版本号:1.0.1(2017.05.23)
  160. *******************************************************************************/
  161. void Time0_Init(void)
  162. {
  163.         AUXR &= 0x7F;                //定时器时钟12T模式
  164.         TMOD &= 0xF0;                //设置定时器模式
  165.         TMOD |= 0X01;      //确保不干扰其他配置
  166.         TH0 = (65536 - 1000) / 256;                //设置定时初值
  167.         TL0 = (65536 - 1000) % 256;                //设置定时初值
  168.         ET0 = 1;
  169.         TR0 = 1;                //定时器0开始计时
  170.         EA = 1;               
  171. }
  172. /*******************************************************************************
  173. * 文件名:
  174. * 描  述: 中断函数
  175. * 功  能:1毫秒@11.0592MHz
  176. * 作  者:大核桃
  177. * 版本号:1.0.1(2017.05.23)
  178. *******************************************************************************/
  179. void ET0_IRQHandler() interrupt 1
  180. {
  181.         static uint8 tmr5ms = 0;

  182.         TH0 = (65536 - 1000) / 256;                //设置定时初值
  183.         TL0 = (65536 - 1000) % 256;                //设置定时初值

  184.         EADC = 0; //不允许ADC转换中断
  185.         tmr5ms++;
  186.         if(tmr5ms >= 5)
  187.         {
  188.                 tmr5ms = 0; //定时器5MS溢出一次
  189.                 VoltageCheckRefresh();
  190.         }

  191.         LedScan();
  192.         EADC = 1; //允许ADC转换中断
  193.                         
  194. }
  195. /*******************************************************************************
  196. * 文件名:void Mcu_Port_Init()
  197. * 描  述: io初始化
  198. * 功  能:
  199. * 作  者:大核桃
  200. * 版本号:1.0.1(2017.05.23)
  201. *******************************************************************************/
  202. void Mcu_Port_Init()
  203. {
  204.         IE = 0xa8;//允许AD转换
  205.         //将P0口低二位配置为推挽输出
  206.         //234567位配置位高阻输入
  207.         P0M1 = 0xFC;//1111 1100
  208.         P0M0 = 0X03;//0000 0011
  209.         //P0 = 0X01;//第6个
  210.         //P0 = 0X02;//第7个
  211.         //高3位配置高阻输入,用作模拟口
  212.         //其他配置推挽输出,驱动LED
  213.         P1M1 = 0xE0;//1110 0000
  214.         P1M0 = 0X1F;//0001 1111
  215.         //P2口配置准双向口
  216.         P2M1 = 0X00;
  217.         P2M0 = 0X00;
  218.         P2 = 0Xff; //上电为1111 1111

  219. //        //P54,P55口为推挽输出
  220.         P5M1 = 0X00;
  221.         P5M0 = 0X00;
  222.         P5 = 0xFF;

  223.         //P37,P36,3.2,P3.3 P3.4口为推挽输出
  224.         P3M1 = 0X00;
  225.         P3M0 = 0XFC;
  226.         P3 = 0X23; //0010 0111//第5个LED端口
  227.         
  228.         LED0 = 0;//第1组LED,如果使能请置为1
  229.         LED1 = 0;
  230.         LED2 = 0;
  231.         LED3 = 0;
  232.         LED4 = 0;
  233.         LED5 = 0;
  234.         LED6 = 0;
  235.         LED7 = 0;        
  236. }

  237. /*******************************************************************************
  238. * 文件名:void Delay500ms()                //@11.0592MHz
  239. * 描  述:Y5内核延时
  240. * 功  能:
  241. * 作  者:大核桃
  242. * 版本号:1.0.1(2017.05.23)
  243. *******************************************************************************/
  244. void Delay500ms()                //@11.0592MHz
  245. {
  246.         unsigned char i, j, k;

  247.         _nop_();
  248.         _nop_();
  249.         i = 22;
  250.         j = 3;
  251.         k = 227;
  252.         do
  253.         {
  254.                 do
  255.                 {
  256.                         while (--k);
  257.                 } while (--j);
  258.         } while (--i);
  259. }
复制代码


在数码管上显示的数值如下图所示,注意这是测试的锂电池的电压:
      

实际万用表测量的结果是4.01V,数码管显示的结果跟万用表的结果相差0.01V,我们用的ADC是10位的分辨率,参考电压是3.3V,那么一个LSB是3.3/1024 = 0.00322265625,那么0.01V,差不多3个LSB,考虑到我们的参考电压也是有少许误差存在的,所以这个结果还是比较合理的,如果使用独立的参考电压,误差应该会更小。



代码奉献上。
5.AD转换器的使用.rar (202.97 KB, 下载次数: 418)





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

使用道具 举报

沙发
ID:419077 发表于 2018-11-1 14:13 | 只看该作者
谢谢楼主的分享,看了你的程序,之前没弄懂的也搞清楚了
回复

使用道具 举报

板凳
ID:284702 发表于 2018-11-10 22:26 | 只看该作者

谢谢楼主的分享,先下载学习。
回复

使用道具 举报

地板
ID:185188 发表于 2018-11-12 10:07 | 只看该作者
学习一下,谢谢楼主
回复

使用道具 举报

5#
ID:412814 发表于 2018-11-12 18:11 | 只看该作者
谢谢楼主,资料挺有用的,学习了。
回复

使用道具 举报

6#
ID:105786 发表于 2018-12-1 16:59 | 只看该作者
谢谢楼主的分享,先下载备用。以后学习学习。
回复

使用道具 举报

7#
ID:426455 发表于 2018-12-5 09:31 | 只看该作者
谢谢分享,学习了
回复

使用道具 举报

8#
ID:439493 发表于 2018-12-5 19:55 | 只看该作者
谢谢楼主的分享,先下载备用。以后学习学习。
回复

使用道具 举报

9#
ID:45334 发表于 2018-12-12 08:50 | 只看该作者
非常不错,感谢分享
回复

使用道具 举报

10#
ID:421232 发表于 2018-12-12 17:11 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

11#
ID:161785 发表于 2018-12-26 15:11 | 只看该作者
这个太好了,正在学习。谢谢。
回复

使用道具 举报

12#
ID:455671 发表于 2018-12-26 17:15 | 只看该作者
感觉自己啥都不会啊
回复

使用道具 举报

13#
ID:412814 发表于 2019-1-25 14:46 | 只看该作者
正好学习到这个内容,谢谢楼主。
回复

使用道具 举报

14#
ID:8190 发表于 2019-2-22 14:45 | 只看该作者
学习一下,谢谢楼主
回复

使用道具 举报

15#
ID:49198 发表于 2019-4-4 09:49 | 只看该作者
每天都有好东西学习,很不错,刚学习软件,受益匪浅
回复

使用道具 举报

16#
ID:306176 发表于 2019-4-8 16:05 | 只看该作者
楼主牛逼啦
回复

使用道具 举报

17#
ID:305511 发表于 2019-4-11 21:57 | 只看该作者
需要好好学习学习!!!
回复

使用道具 举报

18#
ID:552244 发表于 2019-6-2 18:37 来自手机 | 只看该作者
谢谢,怎么感觉好复杂呢,不懂的原因吧。
回复

使用道具 举报

19#
ID:482511 发表于 2019-6-11 06:57 来自手机 | 只看该作者
谢谢,很好资料。
回复

使用道具 举报

20#
ID:410674 发表于 2019-7-18 08:56 | 只看该作者
很厉害啊,正在学习
回复

使用道具 举报

21#
ID:580104 发表于 2019-7-18 17:15 | 只看该作者
谢谢楼主的分享,先学习下。
回复

使用道具 举报

22#
ID:375542 发表于 2019-7-25 15:34 | 只看该作者
谢谢楼主分享,刚好准备做这个,学习一下
回复

使用道具 举报

23#
ID:613800 发表于 2019-10-12 02:33 | 只看该作者
有测试波形的方法吗?
回复

使用道具 举报

24#
ID:151689 发表于 2019-11-19 18:43 | 只看该作者
你好,你能写个完整的STC单片机内置ADC按键检测程序,用中断方式,谢谢
回复

使用道具 举报

25#
ID:674134 发表于 2019-12-25 23:48 | 只看该作者
本来一直不明白10位精度的低八位和高八位模拟量怎么合起来,res=ADC_RES*4+ADC_RESL;这种公式怎么理解
回复

使用道具 举报

26#
ID:679983 发表于 2020-1-2 20:14 | 只看该作者
学习了,不错
回复

使用道具 举报

27#
ID:472300 发表于 2020-3-27 23:31 | 只看该作者
你好,查询方式中获取值  GetADCResult(5) 中为什么要循环十次呢。
回复

使用道具 举报

28#
ID:311661 发表于 2020-4-17 09:32 | 只看该作者
很好的资料。学习了。谢谢楼主
回复

使用道具 举报

29#
ID:769165 发表于 2020-6-4 10:12 | 只看该作者
谢谢分享 正好要用到这些
回复

使用道具 举报

30#
ID:405264 发表于 2020-9-15 15:01 | 只看该作者
遇到问题,谢谢楼主分享
回复

使用道具 举报

31#
ID:546 发表于 2020-9-20 17:08 | 只看该作者
楼主写的程序格式看上去很舒服,
回复

使用道具 举报

32#
ID:761159 发表于 2020-12-15 15:17 | 只看该作者
不错,正在学习
回复

使用道具 举报

33#
ID:356562 发表于 2021-2-12 08:30 | 只看该作者
正在学习STC芯片的AD,很好的资料。
回复

使用道具 举报

34#
ID:157057 发表于 2021-4-10 00:07 | 只看该作者
Eliezer_Li 发表于 2019-12-25 23:48
本来一直不明白10位精度的低八位和高八位模拟量怎么合起来,res=ADC_RES*4+ADC_RESL;这种公式怎么理解

谢谢楼主的分享,先下载备用。以后学习学习。
回复

使用道具 举报

35#
ID:686513 发表于 2021-8-26 16:16 | 只看该作者
  谢谢楼主的分享,先下载学习。
回复

使用道具 举报

36#
ID:295726 发表于 2022-5-17 17:48 | 只看该作者
好东西!可惜我还没有学到这里。
回复

使用道具 举报

37#
ID:1049825 发表于 2022-10-31 18:38 | 只看该作者
虽然还看不懂,但我相信这个很有用,收藏先.
回复

使用道具 举报

38#
ID:1071848 发表于 2023-4-15 17:58 | 只看该作者
谢谢楼主,资料挺有用!!!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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