[ZigBee] 9、ZigBee之AD剖析——AD采集CC2530溫度串口顯示


 

 

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.

  1. ADCCON1.EOC 位是一個狀態位,當一個轉換結束時,設置為高電平;當讀取ADCH 時,它就被清除。
  2. ADCCON1.ST 位用於啟動一個轉換序列。當這個位設置為高電平,ADCCON1.STSEL 是11,且當前沒有轉換正在運行時,就啟動一個序列。當這個序列轉換完成,這個位就被自動清除。
  3. ADCCON1.STSEL 位選擇哪個事件將啟動一個新的轉換序列。該選項可以選擇為外部引腳P2.0 上升沿或外部引腳事件,之前序列的結束事件,定時器1 的通道0 比較事件或ADCCON1.ST 是1。
  4. ADCCON2 寄存器控制轉換序列是如何執行的。
  5. ADCCON2.SREF 用於選擇參考電壓。參考電壓只能在沒有轉換運行的時候修改。
  6. ADCCON2.SDIV 位選擇抽取率(並因此也設置了分辨率和完成一個轉換所需的時間,或樣本率)。抽取率只能在沒有轉換運行的時候修改。
  7. 轉換序列的最后一個通道由ADCCON2.SCH 位選擇,如上所述。
  8. 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] 1、 ZigBee簡介

[ZigBee] 2、 ZigBee開發環境搭建

[ZigBee] 3、ZigBee基礎實驗——GPIO輸出控制實驗-控制Led亮滅

[ZigBee] 4、ZigBee基礎實驗——中斷

[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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM