|
本程序是《MSP430系列單片機系統工程設計與實踐》書里面的源碼,(包含工程文件(例4.1.6))完整例程下載:http://www.zg4o1577.cn/bbs/dpj-46245-1.html

關于本程序的詳細解說大家可以點擊上圖下載電子書
這個msp430單片機的16位ADC庫文件的調用方法可先下載完整代碼然后找到(例4.1.6)這一節,里面有調用方法
ADC16.c文件:
- /*
-
- MSP430F42X系列單片機16位ADC通用程序庫
- 說明:該驅動程序庫包含了常用的16位ADC操作與控制功能函數,如選擇通道、
- 設置信號放大倍數、設置數據格式、基準源輸出開關等,以及常用采樣
- 函數,包括單通道采樣、平均采樣、多通道同時采樣等。可以作為各種
- 程序的底層驅動使用。
- 要使用該庫函數,需要將本文件(ADC16.c)添加進工程,并在需要
- 調用ADC函數的文件開頭處包含"ADC16.h"
- (C)西安電子科技大學 測控技術與儀器教研中心 編寫:謝楷 2008/02/02
-
- */
- // MSP430FE425
- // +----------------------+
- // | |
- // Vin->100:1-->| A0+ XIN|---
- // -10~+60V | (ADC0) | 32kHz
- // GND--------->| A0- XOUT|---
- // | |
- // 1/2Vref | |
- // | | |
- // |-| | P2.2 |--------->向外部模擬電路供電
- // W1 | |<----->| A1+ |
- // |_| | (ADC1) |
- // +------->| A1- VREF |---+----->基準輸出
- // GND | | |
- // | | ---
- // 1/2Vref | | --- 1nF
- // | | | |
- // |-| | AVss |---+
- // W2 | |<----->| A2+ | |
- // |_| | (ADC2) | |
- // +------->| A2- | GND
- // GND | |
- // +----------------------+
- #include "msp430X42X.h"
- unsigned int ADC_Result[3];
- char ADC_Flag=0;
- char GRP_Flag=0;
- /****************************************************************************
- * 名 稱:ADC16_Init()
- * 功 能:ADC初始化設置函數
- * 入口參數:ADC: 選擇當前被設置的ADC(0~3): 0=ADC0 1=ADC1 2=ADC2
- Channel:設置通道號(0~7) 每個ADC有8個通道可選擇,42X單片機只用了
- 其中3個:通道0=外部電壓輸入 通道6=溫度傳感器 通道7=短路(0V)
- Sign:ADC輸出數據格式選擇: 'U'表示無符號格式,'S'表示有符號格式
- 無符號格式下,-Vref/2輸入時,ADC輸出數據 0
- 0V輸入時,ADC輸出數據 32768
- +Vref/2輸入時,ADC輸出數據 65535
- 有符號格式下,-Vref/2輸入時,ADC輸出數據 -32768
- 0V輸入時,ADC輸出數據 0
- +Vref/2輸入時,ADC輸出數據 32767
-
- Gain:內部放大器增益(1/2/4/8/16/32) 設置被測信號進入ADC之前的放大
- 倍數。用該功能可以方便的改變量程。
- * 出口參數:1表示設置成功,0表示參數錯誤,設置失敗。
- * 說 明: 在主程序調用ADC采樣函數之前,需要調用該函數設置ADC工作模式和參數。
- * 范 例: ADC16_Init(2,0,'S',1);將ADC2設為電壓輸入,有符號格式,增益=1
- ADC16_Init(1,6,'U',1);將ADC1輸入接到內部溫度傳感器,無符號格式,增益=1
- ADC16_Init(0,7,'S',1);將ADC0輸入短路(0V),有符號格式,增益=1
- ADC16_Init(1,0,'S',16);將ADC0設為電壓輸入,有符號格式,信號放大16倍
- ****************************************************************************/
- char ADC16_Init(char ADC,char Channel,char Sign,char Gain)
- { unsigned int *SD16CCTL; //ADCx控制寄存器選擇指針
- unsigned int *SD16INCTL; //ADCx輸入寄存器選擇指針
- SD16CTL|=SD16SSEL0+SD16DIV_1; //設置ADC時鐘SMCLK/2(524KHz)
- //試驗發現500KHz左右采樣效果較好,頻率高噪聲變大,頻率低采樣速度慢
- //---------------------------------------------------------------------------
- switch(ADC) //選擇當前設置哪個ADC。
- {
- case 0 : //如果選擇設置ADC0
- SD16CCTL =(unsigned int *)&SD16CCTL0; //指針指向ADC0控制寄存器
- SD16INCTL=(unsigned int *)&SD16INCTL0;//指針指向ADC0輸入寄存器
- break;
- case 1 : //如果選擇設置ADC1
- SD16CCTL =(unsigned int *)&SD16CCTL1; //指針指向ADC1控制寄存器
- SD16INCTL=(unsigned int *)&SD16INCTL1;//指針指向ADC1輸入寄存器
- break;
- case 2 : //如果選擇設置ADC2
- SD16CCTL =(unsigned int *)&SD16CCTL2; //指針指向ADC2控制寄存器
- SD16INCTL=(unsigned int *)&SD16INCTL2;//指針指向ADC2輸入寄存器
- break;
- default: return(0); //選擇了不存在的ADC,返回錯誤標志
- }
- //---------------------------------------------------------------------------
- if(Channel<=7) //設置ADCx的輸入通道號
- {
- *SD16INCTL &=~ (BIT0+BIT1+BIT2); //清除上一次設置
- *SD16INCTL |=Channel; //設置新的通道號
- }
- else return(0); //選擇了不存在的通道,返回錯誤標志
- //---------------------------------------------------------------------------
- if ((Sign=='S')||(Sign=='s')) *SD16CCTL |= SD16DF; //有符號(雙極性)
- else if ((Sign=='U')||(Sign=='u')) *SD16CCTL &=~SD16DF; //無符號(單極性)
- else return(0); //設置了不存在的參數,返回錯誤標志
- //---------------------------------------------------------------------------
- *SD16INCTL&=~(SD16GAIN0+SD16GAIN1+SD16GAIN2);//清除上一次設置的增益
- switch(Gain) //根據參數設置新的增益
- {
- case 1 : *SD16INCTL|=SD16GAIN_1; break; //1倍
- case 2 : *SD16INCTL|=SD16GAIN_2; break; //2倍
- case 4 : *SD16INCTL|=SD16GAIN_4; break; //4倍
- case 8 : *SD16INCTL|=SD16GAIN_8; break; //8倍
- case 16: *SD16INCTL|=SD16GAIN_16;break; //16倍
- case 32: *SD16INCTL|=SD16GAIN_32;break; //32倍
- default: return(0); //設置了不存在的增益,返回錯誤標志
- }
- //---------------------------------------------------------------------------
- return(1); //設置成功,返回1
- }
- /****************************************************************************
- * 名 稱:ADC16_Sample()
- * 功 能:單個ADC采樣函數。
- * 入口參數:ADC: 選擇當前采樣用的ADC(0~3): 0=ADC0 1=ADC1 2=ADC2
- AverageNum:采樣平均次數(1~65535) 設為1即為單次采樣。
- * 出口參數:平均采樣值。
- * 說 明: 返回值是無符號數,如果ADC設置成有符號模式,返回值需強整成有符
- 號數。或賦給int型變量。
- * 范 例: val=ADC16_Sample(0,30); 返回ADC0連續采樣30次的平均值,賦給val
- val=ADC16_Sample(1,1) ; 返回ADC1單次采樣值,賦給val
- ****************************************************************************/
- unsigned int ADC16_Sample(char ADC,unsigned int AverageNum)
- {
- unsigned long int ADC_SumU=0;//無符號模式的累加值
- signed long int ADC_SumS=0;//有符號模式的累加值
- unsigned int *SD16CCTL; //ADCx控制寄存器選擇指針
- int i;
- if(AverageNum==0) AverageNum=1; //至少要采樣1次
- switch(ADC) //選擇采樣ADC
- {
- case 0:SD16CCTL=(unsigned int *)&SD16CCTL0;break;//指針指向ADC0控制寄存器
- case 1:SD16CCTL=(unsigned int *)&SD16CCTL1;break;//指針指向ADC1控制寄存器
- case 2:SD16CCTL=(unsigned int *)&SD16CCTL2;break;//指針指向ADC2控制寄存器
- }
- *SD16CCTL |=SD16IE; //打開選中的ADC的中斷
- _EINT(); //開總中斷
- *SD16CCTL |= SD16SC; //向選中的ADC發出"開始采樣"命令
- for(i=0;i<AverageNum;i++) //循環連續采樣
- {
- while(ADC_Flag==0) LPM0; //等待一次采樣結束
- ADC_Flag=0;
- if(*SD16CCTL&SD16DF) //如果該ADC設為有符號數據格式
- {
- ADC_SumS+=(int)ADC_Result[ADC]; //按有符號模式累加
- }
- else //如果該ADC設為無符號數據格式
- {
- ADC_SumU+=ADC_Result[ADC]; //按無符號模式累加
- }
- } //采樣次數達到
- *SD16CCTL &=~ SD16SC; //向選中的ADC發出"停止采樣"命令
- *SD16CCTL &=~ SD16IE; //關閉相應ADC的中斷
- if(*SD16CCTL&SD16DF) return(ADC_SumS/AverageNum); //有符號數據格式平均值
- else return(ADC_SumU/AverageNum); //無符號數據格式平均值
- }
- /****************************************************************************
- * 名 稱:ADC16_Sample3()
- * 功 能:三個ADC同時采樣函數。
- * 入口參數:Result0: ADC0采樣結果存放地址
- Result1: ADC1采樣結果存放地址
- Result2: ADC2采樣結果存放地址
- AverageNum:采樣平均次數(1~65535) 設為1即為單次采樣。
- * 出口參數:無。
- * 范 例: ADC16_Sample3(&a,&b,&c,30); 3個ADC同時采樣30次,采樣結果的平均值
- 存于a,b,c三個unsigned int型變量內。
- ADC16_Sample3((unsigned int*)&a,(unsigned int*)&b,(unsigned int*)&c,10); 3個
- ADC同時采樣10次,采樣結果的平均值存于a,b,c三個int型變量內。
- ****************************************************************************/
- void ADC16_Sample3(unsigned int *Result0,unsigned int *Result1,
- unsigned int *Result2,unsigned int AverageNum)
- {
- unsigned long int ADC_SumU[3];//無符號模式的累加值
- signed long int ADC_SumS[3]; //有符號模式的累加值
- int i;
- if(AverageNum==0) AverageNum=1; //至少要采樣1次
- for(i=0;i<3;i++){ADC_SumU[i]=0;ADC_SumS[i]=0;}//累加值清零
- SD16CCTL0 |=SD16GRP; //ADC0編組
- SD16CCTL1 |=SD16GRP; //ADC1編組
- //ADC0/1/2已經被編為同一組,對ADC2的操作將同時作用于ADC0與ADC1
- SD16CCTL2 |=SD16IE; //開啟ADC2中斷
- GRP_Flag=1; //設置同時采樣模式標志(中斷內判斷用)
- _EINT(); //開總中斷
- SD16CCTL2 |= SD16SC; //向ADC0/1/2同時發出"開始采樣"命令
- for(i=0;i<AverageNum;i++) //循環連續采樣
- {
- while(ADC_Flag==0) LPM0; //等待一次采樣結束
- ADC_Flag=0;
- if(SD16CCTL0&SD16DF) ADC_SumS[0]+=(int)ADC_Result[0]; //按有符號模式累加
- else ADC_SumU[0]+=ADC_Result[0]; //按無符號模式累加
- if(SD16CCTL1&SD16DF) ADC_SumS[1]+=(int)ADC_Result[1]; //按有符號模式累加
- else ADC_SumU[1]+=ADC_Result[1]; //按無符號模式累加
- if(SD16CCTL2&SD16DF) ADC_SumS[2]+=(int)ADC_Result[2]; //按有符號模式累加
- else ADC_SumU[2]+=ADC_Result[2]; //按無符號模式累加
- } //采樣次數達到
- SD16CCTL2 &=~ SD16SC; //向ADC0/1/2同時發出"停止采樣"命令
- SD16CCTL0 &=~ SD16GRP; //解除ADC0編組
- SD16CCTL1 &=~ SD16GRP; //解除ADC1編組
- SD16CCTL2 &=~ SD16IE; //關閉ADC2中斷
- GRP_Flag=0; //清除同時采樣模式標志(中斷內判斷用)
- if(SD16CCTL0&SD16DF) *Result0=ADC_SumS[0]/AverageNum; //有符號數據格式平均值
- else *Result0=ADC_SumU[0]/AverageNum; //無符號數據格式平均值
- if(SD16CCTL1&SD16DF) *Result1=ADC_SumS[1]/AverageNum; //有符號數據格式平均值
- else *Result1=ADC_SumU[1]/AverageNum; //無符號數據格式平均值
- if(SD16CCTL2&SD16DF) *Result2=ADC_SumS[2]/AverageNum; //有符號數據格式平均值
- else *Result2=ADC_SumU[2]/AverageNum; //無符號數據格式平均值
- }
- /****************************************************************************
- * 名 稱:SD16ISR() ADC采樣結束產生的中斷
- * 功 能:保存ADC采樣結果,并喚醒CPU。
- * 入口參數:無
- * 出口參數:無
- ****************************************************************************/
- #pragma vector=SD16_VECTOR
- __interrupt void SD16ISR(void)
- {
- switch (SD16IV) //判斷中斷類型
- {
- case 2: // SD16MEM Overflow
- break;
- case 4: // ADC0 采樣結束
- ADC_Result[0]=SD16MEM0;break; // 保存ADC0采樣結果
- case 6: // ADC1 采樣結束
- ADC_Result[1]=SD16MEM1;break; // 保存ADC1采樣結果
- case 8: // ADC2 采樣結束
- if(GRP_Flag) // 若在同時采樣模式下
- {
- ADC_Result[0]=SD16MEM0;
- ADC_Result[1]=SD16MEM1; //保存3個ADC的采樣結果
- ADC_Result[2]=SD16MEM2;
- }
- else ADC_Result[2]=SD16MEM2; //普通模式下,保存ADC2采樣結果
- break;
- }
- ADC_Flag=1; //ADC中斷已執行標志
- __low_power_mode_off_on_exit(); //喚醒CPU
- }
- /****************************************************************************
- * 名 稱:ADC16_VrefOn()
- * 功 能:打開內部基準源,并對外輸出
- * 入口參數:無
- * 出口參數:無
- * 說 明: 打開基準源會增加250uA左右耗電,所以ADC采樣結束之后要及時關閉。
- 如果采用外部基準,請關閉內部基準以免沖突。
- 基準開啟后,需要2ms左右的時間穩定,應略延遲再啟動ADC采樣。
- ****************************************************************************/
- void ADC16_VrefOn()
- {
- SD16CTL |= (SD16REFON+SD16VMIDON); //開啟內部基準源,開啟輸出緩沖器
- }
- /****************************************************************************
- * 名 稱:ADC16_VrefOff()
- * 功 能:關閉內部基準源
- * 入口參數:無
- * 出口參數:無
- ****************************************************************************/
- void ADC16_VrefOff()
- {
- SD16CTL &=~ (SD16REFON+SD16VMIDON); //開啟內部基準源,開啟輸出緩沖器
- }
- /****************************************************************************
- * 名 稱:Analog_On()
- * 功 能:向外部模擬電路供電(P2.2輸出高電平)
- * 入口參數:無
- * 出口參數:無
- * 說 明: 如果單片機測控系統設計中含有模擬電路,將帶來額外的連續耗電。為了
- 降低功耗,42X系列單片機管腳排列在ADC附近安排了一個IO口:P2.2,方便
- 用它來控制模擬部分的電源。采樣間隙關閉模擬部分以節省電流。如果模
- 擬部分耗電<5mA,可以直接用P2.2口供電。也可用P2.2控制模擬部分的電
- 源開關,獲得更大驅動能力。
- ****************************************************************************/
- void Analog_On()
- {
- P2DIR|=BIT2;
- P2OUT|=BIT2;
- }
- /****************************************************************************
- * 名 稱:Analog_Off()
- * 功 能:關閉外部模擬電路的供電(P2.2輸出低電平)
- * 入口參數:無
- * 出口參數:無
- ****************************************************************************/
- void Analog_Off()
- {
- P2DIR|=BIT2;
- P2OUT&=~BIT2;
- }
復制代碼
ADC16.h文件:
- #include "msp430X42X.h"
- extern char ADC16_Init(char ADC,char Channel,char Sign,char Gain);
- extern unsigned int ADC16_Sample(char ADC,unsigned int AverageNum);
- extern void ADC16_Sample3(unsigned int *Result0,unsigned int *Result1,
- unsigned int *Result2,unsigned int AverageNum);
- extern void ADC16_VrefOn();
- extern void ADC16_VrefOff();
- extern void Analog_On();
- extern void Analog_Off();
復制代碼
|
|