msp430內部含有ADC12模組,可以完成12位的模數轉換,當對精度或其他指標要求不高時,可以選用430單片機內部的ADC12完成模數轉換工作。這裡主要實現了一個比較通用的ADC12模組初始化程式,具體的資料存放區和處理需要自己在中斷處理函數中添加。
- 硬體介紹:
msp430單片機內的ADC12模組的特點如下:12位轉換精度,1位非線形誤差,1位非線形積分誤差;多種時鐘源給ADC12模組,切本身內建時鐘發生器;內建溫度感應器;TimerA/TimerB硬體觸發器;8路外部通道和4路內部通道;內建參考電壓源和6種參考電壓組合;4種模式的模數轉換;16bit的轉換緩衝;ADC12關閉支援超低功耗;採用速度快,最高200Kbps;自動掃描和DMA使能。430內部的ADC12功能還是蠻強大的,可以有定時器觸發模數轉換開始,還可以和內部的DMA模組共同使用,完成高速的採樣轉儲等進階功能。
這個AD的轉化公式如下,可以根據它計算採樣的類比電壓值:
使用AD是還要注意採樣時間,430單片機的模數ADC12模組的等效類比電壓輸入電路如下:
其中VS是訊號源電壓,RS是訊號源內阻,VI在Ax(ADC12模組類比輸入端)上的電壓,RI單片機內多路開關等效電阻,VC是保持電容上的電壓(ADC12模組採樣的電壓),CI 是電容的值。需要根據這些值計算採樣時間:
代入單片機上的參數後公式如下:
我的程式中採樣時間設的是4us,可以算出如果用我的程式(不更改採樣時間)的話,最大訊號源內阻可以是6.8k,當訊號源內阻更大時,可以自己按要求設採樣時間(在程式的初始化函數內的寄存器設定部分)。
還有,ADC模數轉換時要求參考電壓等很穩定,為了達到這個要求,德州儀器要求這部分的電路如下:
即:所有參考源和電源均並聯一組 0.1uF和10uF的電容。
硬體部分就說這麼多了;如果需要更詳細的說明,參考使用者指南。
- 程式實現:
程式主要實現的是一個比較通用的初始化程式,內容如下:
char ADC12Init(char n,char channels[],char rep){ if(n>15) return 0; //SHT0_0 ADC12CTL0 = ADC12ON + MSC + SHT0_0 + REFON + REF2_5V;// 開啟ad,參考電壓2.5v ADC12CTL1 = SHP + ADC12SSEL_3; //Use sampling timer, SMCLK for(int i = 0;i < n;i++) { if(channels[i] >= 0x80) return 0; *(char*)(ADC12MCTL0_ + i) = channels[i]; //每個MCTL設定 } *(char*)(ADC12MCTL0_ + n - 1) |= EOS; //序列結束 if(rep != 0) //多次轉換 { ADC12CTL1 |= CONSEQ_3; } else { ADC12CTL1 |= CONSEQ_1; } ADC12IE = 1<<(n-1); // Enable ADC12IFG.n-1 return 1;}
程式先判斷n 通道總數是否超過了可用的個數,超過則返回零然後設定ADC12CTL0和ADC12CTL1中不需要特殊設定的部分,然後在設定通道模式(根據rep參數的值);for迴圈設定的是每個儲存寄存器的設定ADC12MCTLx ;*(char*)(ADC12MCTL0_ + n - 1) |= EOS; //序列結束 這句加入序列結束標誌;最後設定中斷寄存器並返回成功設定標誌。其中比較特殊的是ADC12MCTL0_,這個是430提供的標頭檔中定義的ADC12MCTL0的地址值,以其為指標首址操作ADCMCTLx寄存器,從而利用迴圈設定寄存器的內容,大量減少了程式碼數。
參數channels[]是每個儲存寄存器的設定(除EOS位之外的),含義如下:
channels[]:對應通道設定,高四位,參考源選擇;低四位,通道選擇。具體如下:SREFx Bits6-4Select reference000 VR+ = AVCC and VR. = AVSS001 VR+ = VREF+ and VR. = AVSS010 VR+ = VeREF+ and VR. = AVSS011 VR+ = VeREF+ and VR. = AVSS100 VR+ = AVCC and VR. = VREF./ VeREF.101 VR+ = VREF+ and VR. = VREF./ VeREF.110 VR+ = VeREF+ and VR. = VREF./ VeREF.111 VR+ = VeREF+ and VR. = VREF./ VeREF.INCHx Bits3-0Input channel select0000 A00001 A10010 A20011 A30100 A40101 A50110 A60111 A71000 VeREF+1001 VREF./VeREF.1010 Temperature sensor1011 (AVCC – AVSS) / 21100 (AVCC – AVSS) / 21101 (AVCC – AVSS) / 21110 (AVCC – AVSS) / 21111 (AVCC – AVSS) / 2
這是從使用者指南裡複製來的,每一位和ADC12MCTLx的意義相同(去掉EOS位),所以可用宏定義來制定這個參數,如:
char channels[3];channels[0] = SREF_1+INCH_0;channels[1] = SREF_1+INCH_1;channels[2] = SREF_1+INCH_2;ADC12Init(3,channels,1);
這是3個通道A0-A2採樣,多次採樣。
啟動轉換函式:
void ADC12Start(){ ADC12CTL0 |= ENC; ADC12CTL0 |= ADC12SC;}
ADC初始化完成後,調用此函數開始AD轉換,轉換完成後(一個序列通道,如:剛才的0-2),程式自動進入AD中斷,使用者需要在這裡為自己的函數添加處理邏輯;這裡只儲存了轉化的結果:
#pragma vector=ADC_VECTOR__interrupt void ADC12ISR (void){ static int i; results[0][i] = ADC12MEM0; // Move results, IFG is cleared results[1][i] = ADC12MEM1; // Move results, IFG is cleared results[2][i] = ADC12MEM2; // Move results, IFG is cleared i++; if(i>31) //多次轉換時 轉換次數 { //多次重複採樣時,在這裡方處理函數 ADC12CTL0 &=~ ENC; //停止轉換 i=0; }}
該程式實現的是多次A0-A2 32次轉換,把結果存入results數組。單次時,僅僅採樣一次(A0-A2)可用自己更改處理函數。
程式部分就完成了,調用時注意要自己實現處理邏輯或儲存邏輯。
- 使用樣本:
本程式使用方式還是加入C檔案,包含H檔案;不過和之前的程式不同的是要自己實現中斷處理邏輯。
使用樣本參見程式庫中的ADC12.
#include <msp430x16x.h>#include "ADC12.h"void main( void ){ // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; ClkInit(); char channels[3]; channels[0] = SREF_1+INCH_0; channels[1] = SREF_1+INCH_1; channels[2] = SREF_1+INCH_2; ADC12Init(3,channels,1); _EINT(); ADC12Start(); LPM0;}
這裡實現的是3通道多次轉換,參考電壓都是內部參考電壓。自己實現的處理邏輯參見前面的程式實現的最後一部分。
ADC12模組部分就到這裡了,有什麼不足之處,歡迎提出建議、討論。
附件:程式庫
作者:給我一杯酒
出處:http://Engin.cnblogs.com/
本文著作權歸作者和部落格園共有,歡迎轉載,轉載保留此段文字並且註明出處;謝謝。