(四),ADC101,ADC10是十位的AD,在g2553上有A0~A7八個(gè)可以外接的AD通道,A10接到片上的溫度傳感器上,其他的通道都接在內(nèi)部的VCC或GND上。因?yàn)槭牵保盀榈模粒乃杂?jì)算公式如下:
本文引用地址:http://m.butianyuan.cn/article/201611/316299.htm
2 ,ADC參考電壓的選擇:ADC的參考電壓可以為:
由ADC控制寄存器0 ADC10CTL0控制。但是要提高ADC的精度的話,盡量不要用內(nèi)部的參考電壓,最好外接一個(gè)比較穩(wěn)定的電壓作為參考電壓,因?yàn)閮?nèi)部的產(chǎn)生的參考電壓不是特別穩(wěn)定或精度不是特別的高。例如我在使用時(shí)遇到的情況如下:
Vref設(shè)為2.5V但實(shí)際的值大概為2.475V, 選擇VCCVSS作為參考,用電壓表測得大概為3.58V還是不小的偏差的。
另外,在有可能的情況下,盡量采用較大的VR+和VR-,以減小紋波對采樣結(jié)果的影響。
3,ADC10的采樣方式有:單通道單次采樣,單通道多次采樣,多通道單次采樣,多通道多次采樣。
4,DTC:因?yàn)锳DC10只有一個(gè)采樣結(jié)果存儲寄存器ADC10MEM,所以除了在單通道單次采樣的模式下,其他的三個(gè)模式都必須使用DCT,否則轉(zhuǎn)換結(jié)果會不停地被新的結(jié)果給覆蓋。
DTC是轉(zhuǎn)換結(jié)果傳送控制,也就是轉(zhuǎn)換結(jié)果可以不用CPU的干預(yù),就可以自動(dòng)地存儲在指定的存儲空間內(nèi)。使用這種方式轉(zhuǎn)換速度快,訪問方便,適用于高速采樣模式中。DTC的使用可以從下面的例子中很容易看明白:
#include <msp430g2553.h>
#include "ser_12864.h"
uchar s1[]={"DTC:"};
uchar s2[]={"2_cha_2_time_DTC"};
void ADC_init()
{
ADC10CTL1 = CONSEQ_3 + INCH_1;// 2通道多次轉(zhuǎn)換, 最大轉(zhuǎn)換通道為A1
ADC10CTL0 = ADC10SHT_2 + MSC + ADC10ON + ADC10IE; // ADC10ON, interrupt enabl參考電壓選默認(rèn)值VCC和VSS
//采樣保持時(shí)間為16 x ADC10CLKs,ADC內(nèi)核開,中斷使能MSC多次轉(zhuǎn)換選擇開
//如果MSC置位,則第一次開始轉(zhuǎn)換時(shí)需要觸發(fā)源觸發(fā)一次,以后的轉(zhuǎn)換會自動(dòng)進(jìn)行中斷使能
//使用DTC時(shí),當(dāng)一個(gè)塊傳送結(jié)束,產(chǎn)生中斷
//數(shù)據(jù)傳送控制寄存器0 ADC10DTC0設(shè)置為默認(rèn)模式:單傳送塊模式,單塊傳送完停止
ADC10DTC1 = 0x04; //數(shù)據(jù)傳送控制寄存器1 4 conversions定義在每塊的傳送數(shù)目一共采樣4次 所以單塊傳送4次
//以后就停止了傳送 因?yàn)槭莾赏ǖ赖模允敲總€(gè)通道采樣數(shù)據(jù)傳送2次
ADC10AE0 |= BIT0+BIT1;// P1.0 P1.1 ADC option select 使能模擬輸入腳A0 A1
//不知道為什么,當(dāng)P10 P11都懸空時(shí),采樣值不同,用電壓表測得懸空電壓不同,但是當(dāng)都接上采樣源的時(shí)候,
//采樣是相同的
}
void main(void)
{
uint adc_sample[8]={0};//存儲ADC序列采樣結(jié)果
WDTCTL = WDTPW+WDTHOLD;
BCSCTL1 = CALBC1_12MHZ;//設(shè)定cpu時(shí)鐘DCO頻率為12MHz
DCOCTL = CALDCO_12MHZ;
P2DIR |=BIT3+BIT4;//液晶的兩條線
init_lcd();
ADC_init();
wr_string(0,0,s1);
wr_string(0,3,s2);
for (;;)
{
ADC10CTL0 &= ~ENC;//ADC不使能其實(shí)這句話可以放在緊接著CPU喚醒之后的,因?yàn)镃PU喚醒了,說明我們想要的
//轉(zhuǎn)換數(shù)據(jù)傳送完成了,如果ADC繼續(xù)轉(zhuǎn)換,那么轉(zhuǎn)換結(jié)果也不再傳輸,是無用的。所以緊接著放在CPU喚醒之后
//計(jì)時(shí)關(guān)閉ADC,有利于降低功耗
while (ADC10CTL1 & BUSY);// Wait if ADC10 core is active等待忙
ADC10SA = (unsigned int)adc_sample;//數(shù)據(jù)傳送開始地址寄存器設(shè)置DTC的開始地址Data buffer start
//設(shè)置數(shù)據(jù)開始傳送的地址為數(shù)組adc_sample[]的首地址,因?yàn)榧拇嫫鰽DC10SA和轉(zhuǎn)換結(jié)果都是16位的,所以要把
//地址強(qiáng)制轉(zhuǎn)換為16位的int或unsigned int
//應(yīng)該也可以用指針直接訪問DTC的存儲區(qū),還沒試過
//例如:前面定義了單塊傳送4次數(shù)據(jù),所以每次傳送完成了一個(gè)塊,也就是4次,就會把中斷標(biāo)志位置位,產(chǎn)生中斷
//因?yàn)樯厦嬖O(shè)置的地址為數(shù)組adc_sample[]的首地址,所以每次轉(zhuǎn)換的結(jié)果就會傳送到該數(shù)組的前4位上,所以如果
//一切正常的話,數(shù)組里應(yīng)該是前4位為轉(zhuǎn)換的結(jié)果,后4位為初始值0通過下面的顯示,驗(yàn)證轉(zhuǎn)換是正確的
//一次觸發(fā)首先對A1、A0采樣,放入a[0]和a[1]中,再對A1、A0采樣,放入a[2]和a[3]中。如此循環(huán)下去。
//驗(yàn)證得知,當(dāng)多通道采樣時(shí),先采高的通道,再采低的通道。如上面每次采樣時(shí),先采A1 再A0
//因?yàn)橐还膊蓸觽魉?次,所以數(shù)組的后4位為初始值0
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion startADC使能,開始轉(zhuǎn)換 ADC10SC為采樣觸發(fā)源
//不需要cpu的干預(yù),DTC就可以把采樣結(jié)果存儲到指定的存儲區(qū)中
__bis_SR_register(CPUOFF + GIE);// LPM0, ADC10_ISR will force exit如果轉(zhuǎn)換結(jié)果傳送完成,
//就會進(jìn)入中斷,CPU喚醒 繼續(xù)往下運(yùn)行
wr_int(2,0,adc_sample[0]);//顯示轉(zhuǎn)換結(jié)果A1
wr_int(6,0,adc_sample[1]);//A0
wr_int(0,1,adc_sample[2]);//A1
wr_int(3,1,adc_sample[3]);//A0
wr_int(6,1,adc_sample[4]);
wr_int(0,2,adc_sample[5]);
wr_int(3,2,adc_sample[6]);
wr_int(6,2,adc_sample[7]);
}
}
// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)//中斷響應(yīng)以后,中斷標(biāo)志位自動(dòng)清零
{
__bic_SR_register_on_exit(CPUOFF);// Clear CPUOFF bit from 0(SR)
}
上面的例子是把存儲結(jié)果存儲在了uint型的數(shù)組中。也可以用指針直接指定要存放的地址,然后再用指針進(jìn)行訪問(理論上可以,但還沒有試過)。也可以把存儲結(jié)果直接存放在一個(gè)16位的寄存器中,如:
ADC10SA = (unsigned int)&TACCR1;// Data transfer location把轉(zhuǎn)換結(jié)果存儲在TACCR1所在的
//位置處,就相當(dāng)于存儲在TACCR1中 因?yàn)锳DC轉(zhuǎn)換結(jié)果和寄存器TACCR1都是16位的,所以要把地址強(qiáng)制轉(zhuǎn)換為16位的
//int 或 unsigned int型
5,ADC采樣注意事項(xiàng):用片上的ADC10進(jìn)行采樣,如果外部分壓電路的電阻過大(比如幾K以上),AD引腳會把電壓拉高,使采樣結(jié)果發(fā)生很大的偏差。應(yīng)換成小電阻(幾十~幾百歐),如果要求更精確的話,要加運(yùn)放進(jìn)行電壓跟隨。
6,AD采樣交流信號:
一般是50Hz,100Hz,1000Hz。方法是在交流信號的一個(gè)周期內(nèi)采樣多次(如40次,30次等),然后利用公式可以求出交流信號的有效值,平均值等。
7,片上溫度傳感器
ADC的A10通道接片上的溫度傳感器,MSP430內(nèi)嵌的溫度傳感器實(shí)際上就是一個(gè)輸出電壓隨環(huán)境溫度而變化的溫度二極管。
當(dāng)使用片上溫度傳感器時(shí),采樣周期必須大于30us片上溫度傳感器的偏移很大,所以精確測量需要
進(jìn)行校準(zhǔn)。選擇片上溫度傳感器INCH_10,ADC其他的設(shè)置都和外部通道的設(shè)置相同,包括參考電壓源的選擇和轉(zhuǎn)換存儲的選擇
選擇了片上溫度傳感器,會自動(dòng)地打開片上參考電壓源發(fā)生器作為溫度傳感器的電壓源,但是這并不會時(shí)能VREF+輸出,也不會
影響AD轉(zhuǎn)換參考源的選擇,轉(zhuǎn)換參考源的選擇和其他通道的選擇相同
公式為:VTEMP=0.00355(TEMPC)+0.986
片上溫度傳感器的校準(zhǔn),可以參見我的溫度傳感器校準(zhǔn)程序,也可以參考其他的論文。下面只給出程序的一部分:
void ADC_init()
{
ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE; // ADC10ON, interrupt enabled 參考電壓選默認(rèn)值VCC和VSS
//采樣保持時(shí)間為16 x ADC10CLKs,ADC開,中斷使能
ADC10CTL1 = INCH_10;// ADC輸入通道選擇A10,為內(nèi)部的溫度傳感器
//其他是默認(rèn),采樣觸發(fā)輸入源選擇為ADC10SC,采樣輸入信號不翻轉(zhuǎn),轉(zhuǎn)換時(shí)鐘選擇內(nèi)部時(shí)鐘源:ADC10OSC,3.7~6.3MHz
//不分頻,單通道單次轉(zhuǎn)換
//ADC10AE0 |= 0x02;// PA.1 ADC option select 使能模擬輸入腳A1
//P1DIR |= 0x01;// Set P1.0 to output direction
//所以是P11為ADC輸入腳,P10控制led
}
(五),通用串行通信接口(USCI)
1,USCI_A:支持UART,IrDA,SPI
USCI_B:支持I2C, SPI
2,UART這個(gè)模塊沒什么好說的,和其他的一寫處理器如S12,ARM等差不多。只要設(shè)置好幾個(gè)控制寄存器,波特率,寫幾個(gè)收發(fā)函數(shù)就可以了。下面就給出msp430g2553于PC用UART通信的基本程序:
#include"msp430g2553.h"
unsigned char rev;
char *string1="Helloworld!";
char string2[]="Get it!n";//n是換行符
void putchar(unsigned char c)//發(fā)送字符函數(shù)
{
while (!(IFG2&UCA0TXIFG));// USCI_A0 TX buffer ready? 等待TX buffer為空
UCA0TXBUF = c;// TX -> RXed character發(fā)送字符c
}
void putstr(char *s)//發(fā)送字符串函數(shù)
{
IE2 &= ~UCA0RXIE;//發(fā)送時(shí)先關(guān)閉接收中斷,不接收
while((*s)!=