CC2530ADC轉換


一、ADC簡介

            ADC支持 14 位的模擬數字轉換,具有多達12 位的 ENOB(有效數字位)。它包括一個模擬多路轉換器,具有多達8 個各自可配置的通道,以及一個參考電壓發生器。轉換結果通過DMA寫入存儲器。還具有若干運行模式。

二、A/D轉換的基本工作原理

將時間上連續變化的模擬量轉化為脈沖有無的數字量,這一過程就叫做數字化,實現數字化的關鍵設備是ADC

        ADC:數模轉換器,將時間和幅值連續的模擬量轉化為時間和幅值離散的數字量,A/D轉換一般要經過采樣保持量化編碼4個過程。

 

 

 

 

 

三、CC2530的A/D轉換模塊

ADC的主要特性如下:

● 可選的抽取率,這也設置了分辨率(7 到 12 位)

● 8 個獨立的輸入通道,可接受單端或差分信號

● 參考電壓可選為內部單端、外部單端、外部差分或 AVDD5

● 產生中斷請求

● 轉換結束時的 DMA 觸發

● 溫度傳感器輸入

● 電池測量功能

 

 

 

 

 

 

四、一些關於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並返回轉換結果。

 

五、ADC模塊的信號輸入

 端口0引腳可以配置為ADC輸入端,依次為AIN0~AIN7

<1> 可以把輸入配置為單端輸入或差分輸入。

<2> 在選擇差分輸入的情況下,差分輸入對:AIN0~AIN1、AIN2~AIN3、AIN4~AIN5、AIN6~AIN7。

<3>除了輸入引腳 AIN0-AIN7,片上溫度傳感器的輸出也可以選擇作為 ADC的輸入,用於溫度測量。

<4> 可以將一個對應AVDD5/3的電壓作為ADC輸入,實現電池電壓監測。

<5> 負電壓和大於VDD的電壓都不能用於這些引腳。

<6> 單端電壓輸入AIN0~AIN7,以通道號碼0~7表示;四個差分輸入對則以 通道號碼8~11表示;溫度傳感器的通道號碼為14AVDD5/3電壓輸入的通道號碼為15

 

題目:定時采集電壓數據發送到上位機

將光照度傳感器接到的Zigbee小模塊上,每隔1秒以單通道的傳送到上位機。上位機與CC2530的 串口0相連,系統時鍾為傳送到上位機。上位機與CC2530的 串口0相連,系統時鍾為16MHz,波特率為9600BPS,發送數據采用查詢的方式。數據幀有4個字節,格式如下: 0xFA (幀頭) ADCH ADCL 0xAF (幀尾)

 

思路:

1.初始化定時器1,實現0.1秒定時。

 1 void Init_Timer1()
 2 {
 3   T1CC0L = 0xd4;        //設置最大計數值的低8位
 4   T1CC0H = 0x30;        //設置最大計數值的高8位
 5   T1CCTL0 |= 0x04;      //開啟通道0的輸出比較模式
 6   T1IE = 1;             //使能定時器1中斷
 7   T1OVFIM = 1;          //使能定時器1溢出中斷
 8   EA = 1;               //使能總中斷
 9   T1CTL = 0x0e;         //分頻系數是128,模模式
10 }

 

2.在定時中斷函數中實現1秒定時。

 1 unsigned char count = 0;
 2 unsigned char F_time = 0;
 3 /*================定時器1服務函數====================*/
 4 #pragma vector = T1_VECTOR
 5 __interrupt void Timer1_Sevice()
 6 {
 7   T1STAT &= ~0x01;      //清除定時器1通道0中斷標志
 8   count++;
 9   if(count == 10)       //定時1秒到
10   {
11     F_time = 1;
12     count = 0;
13   }
14 }

 

3.按照參數要求初始化串口0。

 1 void Init_Uart0()
 2 {
 3   PERCFG = 0x00;    //串口0的引腳映射到位置1,即P0_2和P0_3
 4   P0SEL = 0x0C;     //將P0_2和P0_3端口設置成外設功能
 5   U0BAUD = 59;      //16MHz的系統時鍾產生9600BPS的波特率
 6   U0GCR = 9;
 7   U0UCR |= 0x80;    //禁止流控,8位數據,清除緩沖器
 8   U0CSR |= 0xC0;    //選擇UART模式,使能接收器
 9   UTX0IF = 0;       //清除TX發送中斷標志
10   URX0IF = 0;       //清除RX接收中斷標志
11   URX0IE = 1;       //使能URAT0的接收中斷
12   EA = 1;           //使能總中斷
13 }

 

4.設計字節數組發送函數。

unsigned char dat[4];
/*===================UR0發送字符串函數==================*/
void UR0SendString(unsigned char *str, unsigned char count)
{
  while(count--)       
  {
    U0DBUF = *str++;    //將要發送的1字節數據寫入U0DBUF
    while(!UTX0IF);     //等待TX中斷標志,即數據發送完成
    UTX0IF = 0;  
  }
}

 

5.初始化ADC (單通道采集)。

配置APCFG寄存器

        當使用ADC時,端口0的引腳必須配置為ADC模擬輸入。要配置一個端口0引腳為一個ADC輸入,APCFG寄存器中相應的位必須設置為1。這個寄存器的默認值是0,選擇端口0為非模擬輸入,即作為數字I/O端口。

        注意:APCFG寄存器的設置將覆蓋P0SEL的設置。

 

 

主要對端口的功能進行選擇,設置其傳輸方向,並將端口設置為模擬輸入。

1 void Init_ADC0()
2 {
3   P0SEL |= 0x01;      //P0_0端口設置為外設功能
4   P0DIR &= ~0x01;     //P0_0端口設置為輸入端口
5   APCFG |= 0x01;      //P0_0作為模擬I/O使用
6 }

 

6.實現數據采集並發送到上位機。

 

配置ADCCON3寄存器

        單通道的ADC轉換,只需將控制字寫入ADCCON3寄存器即可。

例子:ADCCON3 = (0x80 | 0x10 | 0x00); //參考電壓選擇AVDD5引腳,256 抽取率,AINO通道0

 

 

 

 

首先將ADCIF標志位清0,接着對ADCCON3寄存器設置,該寄存器一旦被寫入,轉換立即開啟;然后等待ADCIF置1,這時候轉換完成,讀取數據即可。

 

 1 /*===================讀取ADC的數據====================*/
 2 void Get_ADC0_Value()
 3 {
 4   ADCIF = 0;
 5   //參考電壓選擇AVDD5引腳,256抽取率,AIN0通道0
 6   ADCCON3 = (0x80 | 0x10 | 0x00);
 7   while(!ADCIF);      //等待A/D轉換完成,
 8   dat[0] = 0xaf;
 9   dat[1] = ADCH;      //讀取ADC數據低位寄存器
10   dat[2] = ADCL;      //讀取ADC數據高位寄存器
11   dat[3] = 0xfa;
12 }

 

 

完整代碼:

 1 #include "ioCC2530.h"
 2 /*===============定時器1初始化函數==================*/
 3 void Init_Timer1()
 4 {
 5   T1CC0L = 0xd4;        //設置最大計數值的低8位
 6   T1CC0H = 0x30;        //設置最大計數值的高8位
 7   T1CCTL0 |= 0x04;      //開啟通道0的輸出比較模式
 8   T1IE = 1;             //使能定時器1中斷
 9   T1OVFIM = 1;          //使能定時器1溢出中斷
10   EA = 1;               //使能總中斷
11   T1CTL = 0x0e;         //分頻系數是128,模模式
12 }
13 unsigned char count = 0;
14 unsigned char F_time = 0;
15 /*================定時器1服務函數====================*/
16 #pragma vector = T1_VECTOR
17 __interrupt void Timer1_Sevice()
18 {
19   T1STAT &= ~0x01;      //清除定時器1通道0中斷標志
20   count++;
21   if(count == 10)       //定時1秒到
22   {
23     F_time = 1;
24     count = 0;
25   }
26 }
27 /*===================UR0初始化函數====================*/
28 void Init_Uart0()
29 {
30   PERCFG = 0x00;    //串口0的引腳映射到位置1,即P0_2和P0_3
31   P0SEL = 0x0C;     //將P0_2和P0_3端口設置成外設功能
32   U0BAUD = 59;      //16MHz的系統時鍾產生9600BPS的波特率
33   U0GCR = 9;
34   U0UCR |= 0x80;    //禁止流控,8位數據,清除緩沖器
35   U0CSR |= 0xC0;    //選擇UART模式,使能接收器
36   UTX0IF = 0;       //清除TX發送中斷標志
37   URX0IF = 0;       //清除RX接收中斷標志
38   URX0IE = 1;       //使能URAT0的接收中斷
39   EA = 1;           //使能總中斷
40 }
41 unsigned char dat[4];
42 /*===================UR0發送字符串函數==================*/
43 void UR0SendString(unsigned char *str, unsigned char count)
44 {
45   while(count--)       
46   {
47     U0DBUF = *str++;    //將要發送的1字節數據寫入U0DBUF
48     while(!UTX0IF);     //等待TX中斷標志,即數據發送完成
49     UTX0IF = 0;  
50   }
51 }
52 /*===================ADC初始化函數====================*/
53 void Init_ADC0()
54 {
55   P0SEL |= 0x01;      //P0_0端口設置為外設功能
56   P0DIR &= ~0x01;     //P0_0端口設置為輸入端口
57   APCFG |= 0x01;      //P0_0作為模擬I/O使用
58 }
59 /*===================讀取ADC的數據====================*/
60 void Get_ADC0_Value()
61 {
62   ADCIF = 0;
63   //參考電壓選擇AVDD5引腳,256抽取率,AIN0通道0
64   ADCCON3 = (0x80 | 0x10 | 0x00);
65   while(!ADCIF);      //等待A/D轉換完成,
66   dat[0] = 0xaf;
67   dat[1] = ADCH;      //讀取ADC數據低位寄存器
68   dat[2] = ADCL;      //讀取ADC數據高位寄存器
69   dat[3] = 0xfa;
70 }
71 /*=======================主函數======================*/
72 void main()
73 {
74   Init_Uart0();
75   Init_Timer1();
76   Init_ADC0();
77   while(1)
78   {
79     if(F_time == 1)           //定時1秒時間到
80     {
81       Get_ADC0_Value();       //進行A/D轉換並讀取數據
82       UR0SendString(dat,4);   //向上位機發送數據
83       F_time = 0;             //定時1秒標志清0
84     }
85   }
86 }
View Code

 


免責聲明!

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



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