1. 程式人生 > >CC2530 ADC實驗1(讀取片內溫度並通過串列埠顯示)

CC2530 ADC實驗1(讀取片內溫度並通過串列埠顯示)

/*****************************************//by 虛幻程式碼//名稱:讀取片內溫度並通過串列埠顯示//說明:取片內溫度感測器為AD源,通過串列埠在PC上顯示出來。//實驗使用UART0,波特率為19200*****************************************//*引用********************************************/#include<iocc2530.h>#include<stdio.h>/*巨集定義*****************************************/#define

uchar unsignedchar#defineuintunsignedint#define int16 short#define uint16 unsignedshort/*函式定義*******************************///初始化時鐘void initclock(void){  CLKCONCMD &=0XBF;//系統時鐘源選擇32MHZ XOSC  CLKCONCMD &=0XF8;//系統時鐘頻率為32MHZ  CLKCONCMD |=0X28;  CLKCONCMD &=0XEF;//定時時鐘頻率為1MHZwhile(CLKCONSTA &0X40);//等待時鐘穩定
}//初始化串列埠0函式void inituart0(void){  PERCFG &=0XFE;//設USART0的ALT 1  P0SEL |=0X3C;//P0口2、3、4、5做外設  P2DIR &=0X3F;//P0外設優先順序USART0最高  U0CSR |=0X80;//設USART0 工作方式為 UART  U0GCR |=9;  U0BAUD |=59;//設波特率,理論上應該為19200,除錯串列埠卻要設為9600,奇怪?  UTX0IF=0;//UART0 TX中斷標誌位清0  U0CSR |=0X40;//USART0 接收使能  IEN0 |=0X04;//usart0 接收中斷使能  IEN0 |=0X80;//總中斷使能}//串列埠傳送字串函式void uarttx_send_string
(char*data,int len){int j;for(j=0;j<len;j++){    U0DBUF=*data++;while(UTX0IF==0);    UTX0IF=0;}  U0DBUF=0X0A;//換行while(UTX0IF==0);  UTX0IF=0;}//延時函式void delay(uint n){uint i;for(i=0;i<n;i++);for(i=0;i<n;i++);for(i=0;i<n;i++);for(i=0;i<n;i++);for(i=0;i<n;i++);}//讀取溫度感測器AD值函式uint gettemperature(void){uint i;  uint16 adcvalue;  uint16 value;  adcvalue=0;for(i=0;i<4;i++){   ADCCON3 |=0X0E;//單通道AD轉換源為溫度感測器--看手冊    ADCCON3 &=0X3F;//單通道AD轉換參考電壓為1.25內部電壓    ADCCON3 |=0X30;//單通道AD轉換解析度為512DEC,12有效    ADCCON1 |=0X30;//ADC啟動方式選擇為ADCCON1.ST=1事件    ADCCON1 |=0X40;//ADC啟動轉換while(!ADCCON1&0X80);//等待AD轉換完成    value =  ADCL >>2;//ADCL暫存器低2位無效    value |=(((uint16)ADCH)<<6);//連線ADCH和ADCL,並賦值給value    adcvalue +=value;//adcvalue被賦值為4次AD值之和}  value=adcvalue>>2;//累加除以4,得到平均值return((value)>>4)-315;//根據AD值,計算出實際的溫度}/*變數定義和賦值*******************************/int16 avgtemp;

/*主函式*******************************/ void main(void) { char i; char tempvalue[10];   initclock();//初始化時鐘    inituart0();//初始化串列埠   IEN0=IEN1=IEN2=0X00;//關閉所有中斷   ATEST=0X01;//開啟溫度感測器   TR0=0X01;//將溫度感測器與ADC連線起來 while(1) {     avgtemp=0; for(i=0;i<64;i++) {       avgtemp +=gettemperature();//取得溫度數,加上原平均值       avgtemp>>=1;//除以2,取得平均值 }     sprintf(tempvalue,(char*)"%dC/r",(int)avgtemp);     uarttx_send_string(tempvalue,4);     delay(50000); } }

/*本程式講解AD控制(片內溫度計)主講  王加輝*/#include<iocc2530.h>#include"stdio.h"#define uchar  unsigned char#define uint   unsigned intvoid init_UART0(void)/*初始化串列埠*/{   P0SEL|=0X3C;/*這裡我們是選擇P0_2,P0_3,P0_4,P0_5最為串列埠通訊的I/O口*/   P2DIR&=~0XC0;/*在這裡我們設定串列埠0的優先順序大於串列埠1,也就是設定使用串列埠0*/   PERCFG=0X00;/*PERCFG是介面控制暫存器,這裡我們選擇串列埠0位置1,就是選擇P0-2和P0-3為串列埠通訊介面*/   U0CSR|=0X80;/*選擇串列埠的工作方式,我們選擇為非同步通訊*/   U0GCR|=11;/*結合U0BAUD設定波特率為115200,請各位查詢手冊*/   U0BAUD|=216;   UTX0IF=0;/*UTX0IF為串列埠0傳送中斷標誌位,我們將其置零*/}float recieve_AD(void)/*AD轉換,讀取片內溫度計實時電壓*/{   uint value=0;/*無符號整型變數,用來儲存AD轉換值*/   ADCCON1|=0X30;/*選擇AD轉換啟動的方式為手動啟動*/   ADCCON3=0X3E;/*設定AD轉換的資訊源為片內溫度感測器、選擇內部參考電壓為1.25V,設定單通道AD轉換的解析度為512dec,12位,此處要對照AD暫存器手冊檢視*/   ADCCON1|=0X40;/*手動啟動AD轉換*/   while(!(ADCCON1&0X80));/*等待AD一次轉換完成*/   value=ADCL>>4;/*CC2530的AD轉換資料是由高到低儲存的,ADCL低4位無效,所以我們要向右移動去掉無效四位,                        這我也是在CC2430學校視訊上看到的,暫時我不能給出確切解釋,有懂得請補充一下,謝謝*/   value|=(uint)ADCH<<4;/*視訊上解釋高位資料向左移動4位是為了和低位對應,然後相加,我無法做出準確解釋,我找到相關資料再做補充解釋*/   return value*0.06229-303.3-4;/*溫度的計算公式為:溫度=((測量電壓-某一電壓)/溫度係數)-溫度的誤差值*/}void init_tempurature()/*初始化溫度感測器*/{    IEN0=IEN1=IEN2=0;/*因為AD轉換會產生中斷,所以此處我們先關掉所用中斷,對於AD中斷的使用大家可以參考手冊,檢視其中斷源*/    CLKCONCMD&=~0X40;/*設定時鐘頻率,在前面的串列埠通訊中我們也曾講過*/    while(CLKCONSTA&0X40);    CLKCONCMD&=~0X47;    TR0=0X01;/*這裡我讓AD和溫度感測器相連*/    ATEST=0X01;/*啟動溫度感測器*/}void data_UART0(char *character,int length)/*串列埠資料輸出函式*/{    int i;    for(i=0;i<length;i++)    {       U0DBUF=*character++;       while(UTX0IF==0);/*每次傳送資料完成後串列埠傳送中斷位硬體自動置一*/       UTX0IF=0;/*這裡我們要軟體將其置一*/    }    U0DBUF=0X0A;/*這句是在串列埠中輸出一個換行,大家可以試試*/    while(UTX0IF==0);    UTX0IF=0;}/*告訴大家一個在串列埠通訊中將數字轉換成字元輸出的簡單方法,就是在數字後面加0x30,大家可以嘗試*/void delay_ms(int ti)/*延遲函式*/{   int x,y;   for(x=0;x<ti;x++)     for(y=0;y<526;y++);}void main(){   int turn=0;   float ADTEMP=0;   char temp[6]={0};   init_tempurature();//初始化溫度感測器   init_UART0();//初始化串列埠通訊   while(1)   {       for(turn=0;turn<60;turn++)/*累計60次的溫度*/          ADTEMP+=recieve_AD();        ADTEMP=ADTEMP/60;/*求60次溫度的平均值*/       temp[0]=(uchar)(ADTEMP)/10+48;/*將溫度的數值存入陣列temp中*/       temp[1]=(uchar)(ADTEMP)%10+48;       temp[2]='.';       temp[3]=(uchar)(ADTEMP*10)%10+48;       temp[4]=(uchar)(ADTEMP*100)%10+48;       data_UART0(temp,5);//串列埠輸出溫度值       delay_ms(2000);//控制每次輸出的時間間隔   }}/*zigbee cc2530的AD控制(片內溫度計)就講到這裡,祝大家學的愉快*/