1、ADC 簡介
ADC 支持多達14 位的模擬數字轉換,具有多達12 位有效數字位。它包括一個模擬多路轉換器,具有多達8 個各自可配置的通道;以及一個參考電壓發生器。轉換結果通過DMA 寫入存儲器。還具有若干運行模式。
ADC 的主要特性如下:
● 可選的抽取率,這也設置了分辨率(7 到12 位)
● 8 個獨立的輸入通道,可接受單端或差分信號
● 參考電壓可選為內部單端、外部單端、外部差分或AVDD5
● 產生中斷請求
● 轉換結束時的DMA 觸發
● 溫度傳感器輸入
● 電池測量功能
2、ADC 操作
本節描述了ADC 的一般安裝和操作,並描述了CPU 存取的ADC 控制和狀態寄存器的使用。
2.1、ADC 輸入
The signals on the Port 0 pins can be used as ADC inputs. In the following, these port pins are referred to as the AIN0–AIN7 pins. The input pins AIN0–AIN7 are connected to the ADC.
可以把輸入配置為單端或差分輸入。在選擇差分輸入的情況下,差分輸入包括輸入對AIN0-1、AIN2-3、AIN4-5 和AIN6-7。電壓不能為負或者大於VDD。這些輸入對之間的區別書他們采用不同的模式進行轉換。
除了輸入引腳AIN0-AIN7,片上溫度傳感器的輸出也可以選擇作為ADC 的輸入,用於溫度測量。為此寄存器TR0.ADCTM 和ATEST.ATESTCTRL 必須分別按2.10 節和寄存器描述所述設置。
還可以輸入一個對應AVDD5/3 的電壓作為一個ADC 輸入。這個輸入允許諸如需要在應用中實現一個電池監測器的功能。注意在這種情況下參考電壓不能取決於電源電壓,比如AVDD5 電壓不能用作一個參考電壓。
單端電壓輸入AIN0 到AIN7 以通道號碼0 到7 表示。通道號碼8 到11 表示差分輸入,由AIN0–AIN1、AIN2–AIN3、AIN4–AIN5 和AIN6–AIN7 組成。通道號碼12 到15 表示G N D(12)溫度傳感器(14),和AVDD5/3(15)。這些值在ADCCON2.SCH 和ADCCON3.SCH 域中使用。
2.2、ADC 轉換序列(暫時難理解)
ADC將執行一系列的轉換,並把結果移動到存儲器(通過DMA),不需要任何CPU 干預。
轉換序列可以被APCFG 寄存器影響,八位模擬輸入來自I/O 引腳,不必經過編程變為模擬輸入。如果一個通道正常情況下應是序列的一部分,但是相應的模擬輸入在APCFG 中禁用,那么通道將被跳過。當使用差分輸入,處於差分對的兩個引腳都必須在APCFG 寄存器中設置為模擬輸入引腳。
The ADCCON2.SCH(用於定義轉換序列) register bits are used to define an ADC conversion sequence from the ADC inputs.
If ADCCON2.SCH is set to a value less than 8, the conversion sequence contains a conversion from each channel from 0 up to and including the channel number programmed in ADCCON2.SCH.(當設置該寄存器值小於8時,轉換序列為從通道0到SCH定義的值,包括該值)
When ADCCON2.SCH is set to a value between 8 and 12, the sequence consists of differential inputs, starting at channel 8 and ending at the programmed channel.(在8~12之間,為纏粉輸入,通道從8到定義的值)
For ADCCON2.SCH greater than or equal to 12, the sequence consists of the selected channel only.(如果大於12,則定義哪個就是哪個)
PS:the channel define in the last of 2.1
2.3、Single ADC Conversion(單個ADC轉換,2.2是設置一個ADC序列進行轉換)
In addition to this sequence of conversions, the ADC can be programmed to perform a single conversion from any channel(ADC能夠配置從任何一個channel開執行一次單通道轉換). Such a conversion is triggered by writing to the ADCCON3 register. (轉換開始的條件->)The conversion starts immediately unless a conversion sequence is already ongoing, in which case the single conversion is performed as soon as that sequence is finished.
2.4、ADC Operating Modes
本節描述:operating modes and initialization of conversions.
The ADC has three control registers: ADCCON1, ADCCON2, and ADCCON3. These registers are used to configure the ADC and to report status.
- ADCCON1.EOC 位是一個狀態位,當一個轉換結束時,設置為高電平;當讀取ADCH 時,它就被清除。
- ADCCON1.ST 位用於啟動一個轉換序列。當這個位設置為高電平,ADCCON1.STSEL 是11,且當前沒有轉換正在運行時,就啟動一個序列。當這個序列轉換完成,這個位就被自動清除。
- ADCCON1.STSEL 位選擇哪個事件將啟動一個新的轉換序列。該選項可以選擇為外部引腳P2.0 上升沿或外部引腳事件,之前序列的結束事件,定時器1 的通道0 比較事件或ADCCON1.ST 是1。
- ADCCON2 寄存器控制轉換序列是如何執行的。
- ADCCON2.SREF 用於選擇參考電壓。參考電壓只能在沒有轉換運行的時候修改。
- ADCCON2.SDIV 位選擇抽取率(並因此也設置了分辨率和完成一個轉換所需的時間,或樣本率)。抽取率只能在沒有轉換運行的時候修改。
- 轉換序列的最后一個通道由ADCCON2.SCH 位選擇,如上所述。
- ADCCON3 寄存器控制單個轉換的通道號碼、參考電壓和抽取率。單個轉換在寄存器ADCCON3 寫入后將立即發生,或如果一個轉換序列正在進行,該序列結束之后立即發生。該寄存器位的編碼和ADCCON2 是完全一樣的。
2.5、ADC 轉換結果
數字轉換結果以2 的補碼形式表示。對於單端配置,結果總是為正。這是因為結果是輸入信號和地面之間的差值,它總是一個正符號數(Vconv=Vinp-Vinn,其中Vinn=0V)。當輸入幅度等於所選的電壓參考VREF時,達到最大值。
對於差分配置,兩個引腳對之間的差分被轉換,這個差分可以是負符號數。對於抽取率是512的一個數字轉換結果的12 位MSB,當模擬輸入Vconv 等於VREF 時,數字轉換結果是2047。當模擬輸入等於
-VREF 時,數字轉換結果是-2048。
當ADCCON1.EOC 設置為1 時,數字轉換結果是可以獲得的,且結果放在ADCH 和ADCL 中。注意轉換結果總是駐留在ADCH 和ADCL 寄存器組合的MSB 段中。
當讀取ADCCON2.SCH 位時,它們將指示轉換在哪個通道上進行。ADCL 和ADCH 中的結果一般適用於之前的轉換。如果轉換序列已經結束, ADCCON2.SCH 的值大於最后一個通道號碼,但是如果最后寫入ADCCON2.SCH 的通道號碼是12 或更大,將讀回同一個值。
2.6、ADC 參考電壓
模擬數字轉換的正參考電壓可選擇為一個內部生成的電壓,AVDD5 引腳,適用於AIN7 輸入引腳的外部電壓,或適用於AIN6-AIN7 輸入引腳的差分電壓。
轉換結果的准確性取決於參考電壓的穩定性和噪音屬性。希望的電壓有偏差會導致ADC 增益誤差,與希望電壓和實際電壓的比例成正比。參考電壓的噪音必須低於ADC 的量化噪音,以確保達到規定的SNR。
2.7、ADC 轉換時間
ADC 只能運行在32 MHz XOSC 上,用戶不能整除系統時鍾。實際ADC 采樣的4 MHz 的頻率由固定的內部划分器產生。執行一個轉換所需的時間取決於所選的抽取率。總的來說,轉換時間由以下公式給定:
Tconv = (抽取率+ 16) x 0.25 μs。
2.8、ADC 中斷
當通過寫ADCCON3 觸發的一個單個轉換完成時,ADC 將產生一個中斷。當完成一個序列轉換時,不產生一個中斷。
2.9、ADC DMA 觸發(和ADC中斷有種互補的感覺~)
每完成一個序列轉換,ADC 將產生一個DMA 觸發。當完成一個單個轉換,不產生DMA 觸發。
There is one DMA trigger for each of the eight channels defined by the first eight possible settings for ADCCON2.SCH。當通道中一個新的樣本准備轉換,DMA 觸發是活動的。The DMA triggers are named ADC_CHsd in Following Table, where s is single-ended channel and d is differential channel。
In addition, one DMA trigger, ADC_CHALL, is active when new data is ready from any of the channels in the ADC conversion sequence.
3、工程解析
從下面main函數可以看出,整個流程是先初始化串口收發(這個和上一節介紹的串口收發一模一樣,請參考上一節);接着是初始化ADC將片上片上溫度傳感器的輸出選擇作為ADC 的輸入用於溫度測量;在while大循環內則是連續讀取64次溫度數據並求平均(代碼中求平均方法有點怪),最后通過串口將采集的片內溫度傳感器數據輸出。
1 void main(void) 2 { 3 char i; 4 float AvgTemp; 5 char strTemp[6]; 6 7 InitUART(); //初始化串口 8 InitSensor(); //初始化 ADC 9 10 while(1) 11 { 12 AvgTemp = GetTemperature(); 13 14 for (i=0; i<63; i++) 15 { 16 AvgTemp += GetTemperature(); 17 AvgTemp = AvgTemp/2; //每次累加后除 2 18 } 19 20 memset(strTemp, 0, 6); 21 sprintf(strTemp,"%.02f", AvgTemp);//將浮點數轉成字符串 22 UartSendString(strTemp, 5); //通過串口發給電腦顯示芯片溫度 23 DelayMS(1000); //延時 24 } 25 }
其中initSensor()是對ADC進行初始化:
第3行#define DISABLE_ALL_INTERRUPTS() (IEN0 = IEN1 = IEN2 = 0x00)是關閉所有中斷;
第4行為設置系統主時鍾為32M,上一節中main函數最前面做的工作;
1 void InitSensor(void) 2 { 3 DISABLE_ALL_INTERRUPTS(); //關閉所有中斷 4 InitClock(); //設置系統主時鍾為 32M 5 TR0=0x01; //設置為1來連接溫度傳感器到SOC_ADC 6 ATEST=0x01; //使能溫度傳感 7 }
第5行TR0=1為設置溫度傳感器連接到SOC_ADC:
第6行ATEST=1為使能溫度傳感器:
其中GetTemperature()函數用來獲取溫度傳感器AD的值:
1 /**************************************************************************** 2 * 名 稱: GetTemperature() 3 * 功 能: 獲取溫度傳感器 AD 值 4 * 入口參數: 無 5 * 出口參數: 通過計算返回實際的溫度值 6 ****************************************************************************/ 7 float GetTemperature(void) 8 { 9 uint value; 10 11 ADCCON3 = (0x3E); //選擇1.25V為參考電壓;14位分辨率;對片內溫度傳感器采樣 12 ADCCON1 |= 0x30; //選擇ADC的啟動模式為手動 13 ADCCON1 |= 0x40; //啟動AD轉化 14 while(!(ADCCON1 & 0x80)); //等待 AD 轉換完成 15 value = ADCL >> 4; //ADCL 寄存器低 2 位無效,由於他只有12位有效,ADCL寄存器低4位無效。網絡上很多代碼這里都是右移兩位,那是不對的 16 value |= (((uint)ADCH) << 4); 17 18 return (value-1367.5)/4.5-5; //根據 AD 值,計算出實際的溫度,芯片手冊有錯,溫度系數應該是4.5 /℃ 19 //進行溫度校正,這里減去5℃(不同芯片根據具體情況校正) 20 }
其中ADCCON3設置為0x3E,即選擇內聯參考電壓,512采樣率(12位有效位數),對片內溫度傳感器單通道采樣!
其中 ADCCON1 |= 0x30 即Start select. Selects the event that starts a new conversion sequence(ADC啟動模式為手動)
其中 ADCCON1 |= 0x40 即Start a conversion sequence if ADCCON1.STSEL = 11 and no sequence is running(啟動ADC轉換)
其中 while(!(ADCCON1 & 0x80)) 即等待一次轉換完成
第15、16行:是獲得ADC采樣的12位有效數據的值保存在value中
15 value = ADCL >> 4; //ADCL 寄存器低 2 位無效,由於他只有12位有效,ADCL寄存器低4位無效。網絡上很多代碼這里都是右移兩位,那是不對的 16 value |= (((uint)ADCH) << 4);
但是value值只是ADC值,並不是溫度值,需要轉換,代碼18、19行就是完成轉換:(至於怎么算的我猜測應該有個公式對應!)
18 return (value-1367.5)/4.5-5; //根據 AD 值,計算出實際的溫度,芯片手冊有錯,溫度系數應該是4.5 /℃ 19 //進行溫度校正,這里減去5℃(不同芯片根據具體情況校正)
4、實驗現象
將程序燒入CC2530,用USB連接開發板與PC,可以用串口助手觀察zigbee發來的溫度數據,當用手觸摸芯片時溫度會有明顯變化:
Zigbee系列文章:
[ZigBee] 3、ZigBee基礎實驗——GPIO輸出控制實驗-控制Led亮滅
[ZigBee] 5、ZigBee基礎實驗——圖文與代碼詳解定時器1(16位定時器)(長文)
[ZigBee] 6、ZigBee基礎實驗——定時器3和定時器4(8 位定時器)
[ZigBee] 7、ZigBee之UART剖析(ONLY串口發送)
[ZigBee] 8、ZigBee之UART剖析·二(串口收發)
PS:如果您覺得還不錯,點個贊,讓更多人受益~
@beautifulzzzz 2016-07-16 continue~
e-mail:beautifulzzzz@qq.com
sina:http://weibo.com/beautifulzzzz?is_all=1