1. 程式人生 > >ZigBee開發(7)--基礎實驗AD

ZigBee開發(7)--基礎實驗AD

數字化 優先 數字轉換 cc2530 通道 參與 監測 all con

一、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表示;溫度傳感器的通道號碼為14AVDD5/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有兩個數據寄存器:ADCLADCH;三個控制寄存器:ADCCON1ADCCON2ADCCON3;分別用來配置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