標籤:src data 參考 連接埠 float 控制 工作 優先順序 個數
一、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,這時候轉換完成,讀取資料即可。
/**************************************程式描述:通過內部 AD 控制把溫度資訊通過串口發送給上位機,部分晶片誤差較大,需要校準。手摸著晶片,溫度明顯變大。**************************************/#include <ioCC2530.h>//#include “InitUART_Timer.h” //注意在 option 裡設定路徑#include<stdio.h>#define uint unsigned int#define uchar unsigned char/*===================UR0初始化函數====================*/void usart_Init(void){ PERCFG &= ~0x01;//位置 1 P0 口 P0SEL |= 0x0c;//P0_2,P0_3用作串口,第二功能 P2DIR &= ~0XC0; //P0 優先作為 UART0 ,優先順序 U0CSR |= 0x80;//UART 方式 U0UCR |= 0x0c; U0GCR |= 11;//U0GCR 與 U0BAUD 配合 U0BAUD |= 216;// 傳輸速率設為 115200 U0CSR |= 0x40;//允許接收 EA = 1;//開總中斷 URX0IE = 1;//開串口接收中斷 UTX0IF = 0;//UART0 TX 中斷標誌初始置位 URX0IF = 0;//UART0 RX 中斷標誌初始置位 }void usart_Send_Byte(uchar c){ U0DBUF = c; while( !UTX0IF );//等待發送完成標誌位置1 UTX0IF = 0;}void usart_Send_String(uchar *data,uint len){ while(len--) { usart_Send_Byte(*data++); }}/****************************************************************溫度感應器初始化函數****************************************************************/void initTempSensor(void){ EA = 0; CLKCONCMD &= ~0x40; //設定系統時鐘源為 32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振穩定為 32M CLKCONCMD &= ~0x47; //設定系統主時鐘頻率為 //DISABLE_ALL_INTERRUPTS(); //關閉所有中斷 //InitClock(); //設定系統主時鐘為 32M //TR0=0X01; //set ‘1’ to connectthe temperature sensorto theSOC_ADC. //ATEST=0X01; // Enablesthe temperature sensor}/****************************************************************讀取溫度感應器 AD 值函數****************************************************************/float getTemperature(void){ uint value; ADCCON3 = (0x3E); //選擇 1.25V 為參考電壓;12 位解析度;對片內溫度感應器採樣 ADCCON1 |= 0x30; //選擇 ADC 的啟動模式為手動 ADCCON1 |= 0x40; //啟動 AD 轉化 while(!(ADCCON1 & 0x80)); //等待 AD 轉換完成 value = ADCL >> 4; //ADCL 寄存器低 4 位無效 value |= (((uint)ADCH) << 4); return (value-1367.5)/4.5-4; //根據 AD 值,計算出實際的溫度,晶片、//手冊有錯,溫度係數應該是 4.5 /℃//進行溫度校正,這裡減去 4℃(不同晶片根據具體情況校正)}/****************************************************************主函數****************************************************************/void main(void){ uchar I; uchar TempValue[6]; float AvgTemp; usart_Init(); //初始化串口 initTempSensor(); //初始化 ADC while(1) { AvgTemp = 0; for(I = 0 ; I < 64 ; I++) { AvgTemp += getTemperature(); AvgTemp=AvgTemp/2; //每次累加後除 2 } /****溫度轉換成 ascii 碼發送****/ TempValue[0] = (unsigned char)(AvgTemp)/10 + 48; //十位 TempValue[1] = (unsigned char)(AvgTemp)%10 + 48; //個位 TempValue[2] = ‘.‘; //小數點 TempValue[3] = (unsigned char)(AvgTemp*10)%10+48; //十分位 TempValue[4] = (unsigned char)(AvgTemp*100)%10+48; //百分位 TempValue[5] = ‘\0‘; //字串結束符 usart_Send_String( TempValue,6); //Delayms(2000); //使用 32M 晶振,故這裡 2000 約等於 1S }}
ZigBee開發(7)--基礎實驗AD