利用STC單片機的ADC采集電壓
在實際開發中,AD,DA用的相當多,這一節,我們寫一個程序,將采集到的電壓數值顯示在數碼管上,程序如下:- /*******************************************************************************
- * 文件名: ADC轉換器使用
- * 描 述: 電池電壓
- * 功 能:中斷方式 11.059200MHZ
- * 作 者:大核桃
- * 版本號:1.0.1(2017.05.23)
- *******************************************************************************/
- #include "stc15w.h"//頭文件
- #include "intrins.h"
- /*******************************************************************************
- * 文件名: 重定義
- * 描 述:
- * 功 能:
- * 作 者:大核桃
- * 版本號:1.0.1(2017.05.23)
- *******************************************************************************/
- typedef unsigned char uint8;
- typedef unsigned int uint16;
- typedef unsigned long uint32;
- #define ADC_POWER 0x80 //ADC電源控制位
- #define ADC_FLAG 0x10 //ADC完成標志
- #define ADC_START 0x08 //ADC起始控制位
- #define ADC_SPEEDLL 0x00 //540個時鐘
- /*******************************************************************************
- * 文件名:全局變量定義區域
- * 描 述:
- * 功 能:
- * 作 者:大核桃
- * 版本號:1.0.1(2015.03.03)
- *******************************************************************************/
- uint8 val,ch;
- uint16 temp;
- /*******************************************************************************
- * 文件名:共陽數碼管真值表
- * 描 述:
- * 功 能:
- * 作 者:大核桃
- * 版本號:1.0.1(2015.03.03)
- *******************************************************************************/
- code uint8 LedChar[] = {
- 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
- 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xc1
- };
- /*******************************************************************************
- * 文件名:單獨位定義
- * 描 述:
- * 功 能:
- * 作 者:大核桃
- * 版本號:1.0.1(2017.05.23)
- *******************************************************************************/
- sbit LED0 = P1^0;//第1組LED
- sbit LED1 = P1^1;//第2組LED
- sbit LED2 = P1^2;//第3組LED
- sbit LED3 = P1^3;//第4組LED
- sbit LED4 = P1^4;//第5組LED
- sbit LED5 = P3^2;//第6組LED
- sbit LED6 = P0^0;//第7組LED
- sbit LED7 = P0^1;//第8組LED
- sbit LEDS1 = P3^3;//數碼管1
- sbit LEDS2 = P3^4;//數碼管2
- sbit LEDS3 = P3^6;//數碼管3
- sbit LEDS4 = P3^7;//數碼管4
- /*******************************************************************************
- * 文件名:函數前置聲明
- * 描 述:
- * 功 能:
- * 作 者:大核桃
- * 版本號:1.0.1(2017.05.23)
- *******************************************************************************/
- void Mcu_Port_Init();
- void LedScan();
- void Delay500ms(); //24MHZ
- void Time0_Init();//定時器0
- void InitADC(void);
- /*******************************************************************************
- * 文件名
- * 描 述: 主函數
- * 功 能:入口
- * 作 者:大核桃
- * 版本號:1.0.1(2017.05.23)
- *******************************************************************************/
- void main(void)
- {
- Mcu_Port_Init();//IO上電初始化
- Time0_Init();
- InitADC();
- while(1);
- }
- /*******************************************************************************
- * 文件名:void LedScan()
- * 描 述: LED刷新
- * 功 能:
- * 作 者:大核桃
- * 版本號:1.0.1(2017.05.23)
- *******************************************************************************/
- void LedScan()
- {
- static uint8 i = 0;
- P2 = 0Xff;
- switch(i)
- {
- case 0: LEDS4 = 0;LEDS1 = 1;P2 = 0x7f & LedChar[16];i++;break;
- case 1: LEDS1 = 0;LEDS2 = 1;P2 = LedChar[val / 10 % 10];i++;break;
- case 2: LEDS2 = 0;LEDS3 = 1;P2 = LedChar[val % 10];i++;break;
- case 3: LEDS3 = 0;LEDS4 = 1;P2 = LedChar[17];i = 0;break;
- default:break;
- }
- }
- /*******************************************************************************
- * 文件名:void InitADC(void)
- * 描 述: //初始化 AD 轉換
- * 功 能:
- * 作 者:大核桃
- * 版本號:1.0.1(2015.03.03)
- *******************************************************************************/
- void InitADC(void)
- {
- P1ASF = 0xE0; //設置 P1 口為模擬口
- ADC_RES = 0; //清除結果寄存器
- CLK_DIV |= 0x20; //ADRJ 為 1,ADC_RES 存放高兩位結果,ADC_RESL 存放低 8 位結果
- //ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START;
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START; //ADC上電并延時
- }
- /*******************************************************************************
- * 文件名:void adc_isr() interrupt 5 using 1
- * 描 述: 中斷服務程序
- * 功 能:
- * 作 者:大核桃
- * 版本號:1.0.1(2015.03.03)
- *******************************************************************************/
- void adc_isr() interrupt 5 using 1
- {
- EADC = 1; //允許ADC轉換中斷
- ET0 = 0; //關閉定時器0中斷
- ADC_CONTR &= !ADC_FLAG; //清除ADC中斷標志
- temp = ADC_RES;
- temp <<= 8;
- temp |= ADC_RESL;
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | 5;
- EADC = 0;//關閉ADC轉換
- ET0 = 1; //打開定時器0中斷
- }
- /*******************************************************************************
- * 文件名:void VoltageCheckRefresh()
- * 描 述: 電壓檢測
- * 功 能:
- * 作 者:大核桃
- * 版本號:1.0.1(2015.03.03)
- *******************************************************************************/
- void VoltageCheckRefresh()
- {
- val = (uint8)((temp)* 2 * 10 * 3.3 / 1023);
- }
- /*******************************************************************************
- * 文件名:void Time0_Init()
- * 描 述: 定時器0初始化
- * 功 能:10毫秒@11.0592MHz
- * 作 者:大核桃
- * 版本號:1.0.1(2017.05.23)
- *******************************************************************************/
- void Time0_Init(void)
- {
- AUXR &= 0x7F; //定時器時鐘12T模式
- TMOD &= 0xF0; //設置定時器模式
- TMOD |= 0X01; //確保不干擾其他配置
- TH0 = (65536 - 1000) / 256; //設置定時初值
- TL0 = (65536 - 1000) % 256; //設置定時初值
- ET0 = 1;
- TR0 = 1; //定時器0開始計時
- EA = 1;
- }
- /*******************************************************************************
- * 文件名:
- * 描 述: 中斷函數
- * 功 能:1毫秒@11.0592MHz
- * 作 者:大核桃
- * 版本號:1.0.1(2017.05.23)
- *******************************************************************************/
- void ET0_IRQHandler() interrupt 1
- {
- static uint8 tmr5ms = 0;
- TH0 = (65536 - 1000) / 256; //設置定時初值
- TL0 = (65536 - 1000) % 256; //設置定時初值
- EADC = 0; //不允許ADC轉換中斷
- tmr5ms++;
- if(tmr5ms >= 5)
- {
- tmr5ms = 0; //定時器5MS溢出一次
- VoltageCheckRefresh();
- }
- LedScan();
- EADC = 1; //允許ADC轉換中斷
-
- }
- /*******************************************************************************
- * 文件名:void Mcu_Port_Init()
- * 描 述: io初始化
- * 功 能:
- * 作 者:大核桃
- * 版本號:1.0.1(2017.05.23)
- *******************************************************************************/
- void Mcu_Port_Init()
- {
- IE = 0xa8;//允許AD轉換
- //將P0口低二位配置為推挽輸出
- //234567位配置位高阻輸入
- P0M1 = 0xFC;//1111 1100
- P0M0 = 0X03;//0000 0011
- //P0 = 0X01;//第6個
- //P0 = 0X02;//第7個
- //高3位配置高阻輸入,用作模擬口
- //其他配置推挽輸出,驅動LED
- P1M1 = 0xE0;//1110 0000
- P1M0 = 0X1F;//0001 1111
- //P2口配置準雙向口
- P2M1 = 0X00;
- P2M0 = 0X00;
- P2 = 0Xff; //上電為1111 1111
- // //P54,P55口為推挽輸出
- P5M1 = 0X00;
- P5M0 = 0X00;
- P5 = 0xFF;
- //P37,P36,3.2,P3.3 P3.4口為推挽輸出
- P3M1 = 0X00;
- P3M0 = 0XFC;
- P3 = 0X23; //0010 0111//第5個LED端口
-
- LED0 = 0;//第1組LED,如果使能請置為1
- LED1 = 0;
- LED2 = 0;
- LED3 = 0;
- LED4 = 0;
- LED5 = 0;
- LED6 = 0;
- LED7 = 0;
- }
- /*******************************************************************************
- * 文件名:void Delay500ms() //@11.0592MHz
- * 描 述:Y5內核延時
- * 功 能:
- * 作 者:大核桃
- * 版本號:1.0.1(2017.05.23)
- *******************************************************************************/
- void Delay500ms() //@11.0592MHz
- {
- unsigned char i, j, k;
- _nop_();
- _nop_();
- i = 22;
- j = 3;
- k = 227;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
復制代碼
在數碼管上顯示的數值如下圖所示,注意這是測試的鋰電池的電壓:
實際萬用表測量的結果是4.01V,數碼管顯示的結果跟萬用表的結果相差0.01V,我們用的ADC是10位的分辨率,參考電壓是3.3V,那么一個LSB是3.3/1024 = 0.00322265625,那么0.01V,差不多3個LSB,考慮到我們的參考電壓也是有少許誤差存在的,所以這個結果還是比較合理的,如果使用獨立的參考電壓,誤差應該會更小。
代碼奉獻上。
5.AD轉換器的使用.rar
(202.97 KB, 下載次數: 423)
2018-10-13 09:07 上傳
點擊文件名下載附件
|