標(biāo)題: 51單片機入門經(jīng)驗分享6-利用STC單片機的ADC采集電壓 [打印本頁]

作者: dabing89    時間: 2018-10-13 09:10
標(biāo)題: 51單片機入門經(jīng)驗分享6-利用STC單片機的ADC采集電壓
利用STC單片機的ADC采集電壓


在實際開發(fā)中,AD,DA用的相當(dāng)多,這一節(jié),我們寫一個程序,將采集到的電壓數(shù)值顯示在數(shù)碼管上,程序如下:
  1. /*******************************************************************************
  2. * 文件名: ADC轉(zhuǎn)換器使用
  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完成標(biāo)志
  22. #define ADC_START   0x08            //ADC起始控制位
  23. #define ADC_SPEEDLL 0x00            //540個時鐘

  24. /*******************************************************************************
  25. * 文件名:全局變量定義區(qū)域
  26. * 描  述:
  27. * 功  能:
  28. * 作  者:大核桃
  29. * 版本號:1.0.1(2015.03.03)
  30. *******************************************************************************/
  31. uint8 val,ch;
  32. uint16 temp;
  33. /*******************************************************************************
  34. * 文件名:共陽數(shù)碼管真值表
  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;//數(shù)碼管1
  60. sbit LEDS2 = P3^4;//數(shù)碼管2
  61. sbit LEDS3 = P3^6;//數(shù)碼管3
  62. sbit LEDS4 = P3^7;//數(shù)碼管4

  63. /*******************************************************************************
  64. * 文件名:函數(shù)前置聲明
  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. * 描  述: 主函數(shù)  
  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 轉(zhuǎn)換
  112. * 功  能:
  113. * 作  者:大核桃
  114. * 版本號:1.0.1(2015.03.03)
  115. *******************************************************************************/
  116. void InitADC(void)
  117. {
  118.         P1ASF = 0xE0; //設(shè)置 P1 口為模擬口
  119.         ADC_RES = 0; //清除結(jié)果寄存器
  120.         CLK_DIV |= 0x20; //ADRJ 為 1,ADC_RES 存放高兩位結(jié)果,ADC_RESL 存放低 8 位結(jié)果
  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. * 描  述: 中斷服務(wù)程序
  127. * 功  能:
  128. * 作  者:大核桃
  129. * 版本號:1.0.1(2015.03.03)
  130. *******************************************************************************/
  131. void adc_isr() interrupt 5 using 1
  132. {
  133.         EADC = 1; //允許ADC轉(zhuǎn)換中斷
  134.         ET0 = 0;  //關(guān)閉定時器0中斷

  135.         ADC_CONTR &= !ADC_FLAG; //清除ADC中斷標(biāo)志
  136.         temp = ADC_RES;
  137.         temp <<= 8;
  138.         temp |= ADC_RESL;

  139.         ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | 5;
  140.         EADC = 0;//關(guān)閉ADC轉(zhuǎn)換
  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;                //設(shè)置定時器模式
  165.         TMOD |= 0X01;      //確保不干擾其他配置
  166.         TH0 = (65536 - 1000) / 256;                //設(shè)置定時初值
  167.         TL0 = (65536 - 1000) % 256;                //設(shè)置定時初值
  168.         ET0 = 1;
  169.         TR0 = 1;                //定時器0開始計時
  170.         EA = 1;               
  171. }
  172. /*******************************************************************************
  173. * 文件名:
  174. * 描  述: 中斷函數(shù)
  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;                //設(shè)置定時初值
  183.         TL0 = (65536 - 1000) % 256;                //設(shè)置定時初值

  184.         EADC = 0; //不允許ADC轉(zhuǎn)換中斷
  185.         tmr5ms++;
  186.         if(tmr5ms >= 5)
  187.         {
  188.                 tmr5ms = 0; //定時器5MS溢出一次
  189.                 VoltageCheckRefresh();
  190.         }

  191.         LedScan();
  192.         EADC = 1; //允許ADC轉(zhuǎn)換中斷
  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轉(zhuǎn)換
  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.         //其他配置推挽輸出,驅(qū)動LED
  213.         P1M1 = 0xE0;//1110 0000
  214.         P1M0 = 0X1F;//0001 1111
  215.         //P2口配置準(zhǔn)雙向口
  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內(nèi)核延時
  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. }
復(fù)制代碼


在數(shù)碼管上顯示的數(shù)值如下圖所示,注意這是測試的鋰電池的電壓:
      

實際萬用表測量的結(jié)果是4.01V,數(shù)碼管顯示的結(jié)果跟萬用表的結(jié)果相差0.01V,我們用的ADC是10位的分辨率,參考電壓是3.3V,那么一個LSB是3.3/1024 = 0.00322265625,那么0.01V,差不多3個LSB,考慮到我們的參考電壓也是有少許誤差存在的,所以這個結(jié)果還是比較合理的,如果使用獨立的參考電壓,誤差應(yīng)該會更小。



代碼奉獻上。
5.AD轉(zhuǎn)換器的使用.rar (202.97 KB, 下載次數(shù): 423)






作者: WOBENJUNZHU    時間: 2018-11-1 14:13
謝謝樓主的分享,看了你的程序,之前沒弄懂的也搞清楚了
作者: topsjb    時間: 2018-11-10 22:26

謝謝樓主的分享,先下載學(xué)習(xí)。
作者: shidalin123    時間: 2018-11-12 10:07
學(xué)習(xí)一下,謝謝樓主
作者: jifengjianwu    時間: 2018-11-12 18:11
謝謝樓主,資料挺有用的,學(xué)習(xí)了。
作者: 1238    時間: 2018-12-1 16:59
謝謝樓主的分享,先下載備用。以后學(xué)習(xí)學(xué)習(xí)。
作者: 969168666    時間: 2018-12-5 09:31
謝謝分享,學(xué)習(xí)了
作者: friend114    時間: 2018-12-5 19:55
謝謝樓主的分享,先下載備用。以后學(xué)習(xí)學(xué)習(xí)。
作者: qsgang    時間: 2018-12-12 08:50
非常不錯,感謝分享
作者: 時光倒影    時間: 2018-12-12 17:11
謝謝樓主分享
作者: 民盛    時間: 2018-12-26 15:11
這個太好了,正在學(xué)習(xí)。謝謝。
作者: 去遠方    時間: 2018-12-26 17:15
感覺自己啥都不會啊

作者: jifengjianwu    時間: 2019-1-25 14:46
正好學(xué)習(xí)到這個內(nèi)容,謝謝樓主。
作者: zhyuxn123    時間: 2019-2-22 14:45
學(xué)習(xí)一下,謝謝樓主
作者: 懶散專業(yè)戶    時間: 2019-4-4 09:49
每天都有好東西學(xué)習(xí),很不錯,剛學(xué)習(xí)軟件,受益匪淺
作者: michael2018    時間: 2019-4-8 16:05
樓主牛逼啦
作者: 太陽黑子1    時間: 2019-4-11 21:57
需要好好學(xué)習(xí)學(xué)習(xí)。。
作者: songshengguo123    時間: 2019-6-2 18:37
謝謝,怎么感覺好復(fù)雜呢,不懂的原因吧。
作者: jpwu10    時間: 2019-6-11 06:57
謝謝,很好資料。
作者: sgly    時間: 2019-7-18 08:56
很厲害啊,正在學(xué)習(xí)
作者: 嘟嘟胖子    時間: 2019-7-18 17:15
謝謝樓主的分享,先學(xué)習(xí)下。
作者: 磨嘰大王    時間: 2019-7-25 15:34
謝謝樓主分享,剛好準(zhǔn)備做這個,學(xué)習(xí)一下
作者: qq1182560902    時間: 2019-10-12 02:33
有測試波形的方法嗎?
作者: zql111000    時間: 2019-11-19 18:43
你好,你能寫個完整的STC單片機內(nèi)置ADC按鍵檢測程序,用中斷方式,謝謝
作者: Eliezer_Li    時間: 2019-12-25 23:48
本來一直不明白10位精度的低八位和高八位模擬量怎么合起來,res=ADC_RES*4+ADC_RESL;這種公式怎么理解
作者: walter189    時間: 2020-1-2 20:14
學(xué)習(xí)了,不錯
作者: 奔兒霸    時間: 2020-3-27 23:31
你好,查詢方式中獲取值  GetADCResult(5) 中為什么要循環(huán)十次呢。
作者: 歌者    時間: 2020-4-17 09:32
很好的資料。學(xué)習(xí)了。謝謝樓主
作者: 編程小小白    時間: 2020-6-4 10:12
謝謝分享 正好要用到這些
作者: T禮物X    時間: 2020-9-15 15:01
遇到問題,謝謝樓主分享
作者: PCB_PCB    時間: 2020-9-20 17:08
樓主寫的程序格式看上去很舒服,
作者: 山東小哥    時間: 2020-12-15 15:17
不錯,正在學(xué)習(xí)
作者: wblqx    時間: 2021-2-12 08:30
正在學(xué)習(xí)STC芯片的AD,很好的資料。
作者: fefen0    時間: 2021-4-10 00:07
Eliezer_Li 發(fā)表于 2019-12-25 23:48
本來一直不明白10位精度的低八位和高八位模擬量怎么合起來,res=ADC_RES*4+ADC_RESL;這種公式怎么理解

謝謝樓主的分享,先下載備用。以后學(xué)習(xí)學(xué)習(xí)。

作者: zhth1979    時間: 2021-8-26 16:16
  謝謝樓主的分享,先下載學(xué)習(xí)。
作者: lileisgns    時間: 2022-5-17 17:48
好東西!可惜我還沒有學(xué)到這里。
作者: wyl138    時間: 2022-10-31 18:38
雖然還看不懂,但我相信這個很有用,收藏先.
作者: hzm19640731    時間: 2023-4-15 17:58
謝謝樓主,資料挺有用。!




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1