|
|
本程序是《MSP430系列單片機(jī)系統(tǒng)工程設(shè)計(jì)與實(shí)踐》書(shū)里面的源碼,(包含工程文件(例4.1.6))完整例程下載:http://www.denmoz.com/bbs/dpj-46245-1.html

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