第6課 CC2530的ADC工作原理與應用
廣東職業技術學院 歐浩源
一、A/D轉換的基本工作原理
將時間上連續變化的模擬量轉化為脈沖有無的數字量,這一過程就叫做數字化,實現數字化的關鍵設備是ADC。
ADC:數模轉換器,將時間和幅值連續的模擬量轉化為時間和幅值離散的數字量,A/D轉換一般要經過采樣、保持、量化和編碼4個過程。
二、CC2530的A/D轉換模塊
CC2530的ADC模塊支持最高14位二進制的模擬數字轉換,具有12位的有效數據位,它包括一個模擬多路轉換器,具有8個各自可配置的通道,以及一個參考電壓發生器。
該ADC模塊有如下主要特征:
<1> 可選取的抽取率,設置分辨率(7~12位)。
<2> 8個獨立的輸入通道,可接收單端或差分信號。
<3> 參考電壓可選為內部單端、外部單端、外部差分或AVDD5。
<4> 單通道轉換結束可產生中斷請求。
<5> 序列轉換結束可發出DMA觸發。
<6> 可將片內溫度傳感器作為輸入。
<7> 電池電壓測量功能。
三、ADC模塊的信號輸入
端口0引腳可以配置為ADC輸入端,依次為AIN0~AIN7:
<1> 可以把輸入配置為單端輸入或差分輸入。
<2> 差分輸入對:AIN0~AIN1、AIN2~AIN3、AIN4~AIN5、AIN6~AIN7。
<3> 片上溫度傳感器的輸出也可以作為ADC的輸入用於測量芯片的溫度。
<4> 可以將一個對應AVDD5/3的電壓作為ADC輸入,實現電池電壓監測。
<5> 負電壓和大於VDD的電壓都不能用於這些引腳。
<6> 單端電壓輸入AIN0~AIN7,以通道號碼0~7表示;四個差分輸入對則以 通道號碼8~11表示;溫度傳感器的通道號碼為14;AVDD5/3電壓輸入的通道號碼為15。
四、ADC相關的幾個概念
<1> 序列ADC轉換:可以按序列進行多通道的ADC轉換,並把結果通過DMA傳送到存儲器,而不需要CPU任何參與。
<2> 單通道ADC轉換:在程序設計中,通過寫ADCCON3寄存器觸發單通道ADC轉換,一旦寄存器被寫入,轉換立即開始。
<3> 參考電壓:內部生成的電壓、AVDD5引腳、適用於AIN7輸入引腳的外部電壓,或者 適用於AIN6~AIN7輸入引腳的差分電壓。
<4> 轉換結果:數字轉換結果以2的補碼形式表示。對於單端,結果總是正的。對於差分配置,兩個引腳之間的差分被轉換,可以是負數。 當ADCCON1.EOC設置為1時,數字轉換結果可以獲得,且結果總是駐留在ADCH和ADCL寄存器組合的MSB段中。
<5> 中斷請求:通過寫ADCCON3觸發一個單通道轉換完成時,將產生一個中斷,而完成 一個序列轉換時,是不產生中斷的。當每完成一個序列轉換,ADC將產生 一個DMA觸發。
<6> 寄存器:ADC有兩個數據寄存器:ADCL和ADCH;三個控制寄存器:ADCCON1、ADCCON2、ADCCON3;分別用來配置ADC並返回轉換結果。
五、實訓項目:定時采集電壓數據發送到上位機
【1】配置APCFG寄存器
當使用ADC時,端口0的引腳必須配置為ADC模擬輸入。要配置一個端口0引腳為一個ADC輸入,APCFG寄存器中相應的位必須設置為1。這個寄存器的默認值是0,選擇端口0為非模擬輸入,即作為數字I/O端口。
注意:APCFG寄存器的設置將覆蓋P0SEL的設置。
【2】配置ADCCON3寄存器
單通道的ADC轉換,只需將控制字寫入ADCCON3寄存器即可。
【3】ADC初始化
主要對端口的功能進行選擇,設置其傳輸方向,並將端口設置為模擬輸入。
【4】ADC數據采集
首先將ADCIF標志位清0,接着對ADCCON3寄存器設置,該寄存器一旦被寫入,轉換立即開啟;然后等待ADCIF置1,這時候轉換完成,讀取數據即可。
【5】實訓項目源代碼
#include "ioCC2530.h" /*===============定時器1初始化函數==================*/ void Init_Timer1() { T1CC0L = 0xd4; //設置最大計數值的低8位 T1CC0H = 0x30; //設置最大計數值的高8位 T1CCTL0 |= 0x04; //開啟通道0的輸出比較模式 T1IE = 1; //使能定時器1中斷 T1OVFIM = 1; //使能定時器1溢出中斷 EA = 1; //使能總中斷 T1CTL = 0x0e; //分頻系數是128,模模式 } unsigned char count = 0; unsigned char F_time = 0; /*================定時器1服務函數====================*/ #pragma vector = T1_VECTOR __interrupt void Timer1_Sevice() { T1STAT &= ~0x01; //清除定時器1通道0中斷標志 count++; if(count == 10) //定時1秒到 { F_time = 1; count = 0; } } /*===================UR0初始化函數====================*/ void Init_Uart0() { PERCFG = 0x00; //串口0的引腳映射到位置1,即P0_2和P0_3 P0SEL = 0x0C; //將P0_2和P0_3端口設置成外設功能 U0BAUD = 59; //16MHz的系統時鍾產生9600BPS的波特率 U0GCR = 9; U0UCR |= 0x80; //禁止流控,8位數據,清除緩沖器 U0CSR |= 0xC0; //選擇UART模式,使能接收器 UTX0IF = 0; //清除TX發送中斷標志 URX0IF = 0; //清除RX接收中斷標志 URX0IE = 1; //使能URAT0的接收中斷 EA = 1; //使能總中斷 } unsigned char dat[4]; /*===================UR0發送字符串函數==================*/ void UR0SendString(unsigned char *str, unsigned char count) { while(count--) { U0DBUF = *str++; //將要發送的1字節數據寫入U0DBUF while(!UTX0IF); //等待TX中斷標志,即數據發送完成 UTX0IF = 0; } } /*===================ADC初始化函數====================*/ void Init_ADC0() { P0SEL |= 0x01; //P0_0端口設置為外設功能 P0DIR &= ~0x01; //P0_0端口設置為輸入端口 APCFG |= 0x01; //P0_0作為模擬I/O使用 } /*===================讀取ADC的數據====================*/ void Get_ADC0_Value() { ADCIF = 0; //參考電壓選擇AVDD5引腳,256抽取率,AIN0通道0 ADCCON3 = (0x80 | 0x10 | 0x00); while(!ADCIF); //等待A/D轉換完成, dat[0] = 0xaf; dat[1] = ADCH; //讀取ADC數據低位寄存器 dat[2] = ADCL; //讀取ADC數據高位寄存器 dat[3] = 0xfa; } /*=======================主函數======================*/ void main() { Init_Uart0(); Init_Timer1(); Init_ADC0(); while(1) { if(F_time == 1) //定時1秒時間到 { Get_ADC0_Value(); //進行A/D轉換並讀取數據 UR0SendString(dat,4); //向上位機發送數據 F_time = 0; //定時1秒標志清0 } } }
【結語】:
關於CC2530微控制器入門基礎教程到此大功告成。
理解並能獨立完成上述6個基本模塊的應用,可以說基本上掌握了CC2530的基礎應用,為日后學習Zigbee組網應用打下了良好的基礎。
對於CC2530來說,進行低功耗無線組網應用才是它的真正使命。有了我們入門的基礎,后面如果有時間,我會把OSAL操作系統和z-Stack協議棧的應用再做兩個系列的教材,讓大家真正的掌握CC2530的應用精髓。
--------------------------------------------------------------------------------------------------------------------