新聞中心

msp430工作筆記二

作者: 時(shí)間:2016-11-13 來源:網(wǎng)絡(luò) 收藏
(四),ADC10

1,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)!=