MSP430G2553 模数转换器 ADC10
2015-10-01 12:37
344 查看
一、ADC10组成
ADC10模块是MSP430 MCU内部的一个高性能、10位的模数转换器,包含了SAR(Successive-Approximation-Register) core、采样选择控制、基准源发生器和DTC(Data Transfer Controller)。DTC功能允许采样结果直接内部存储,而不需要CPU的干预。ADC10的框图和主要寄存器的含义,如下图所示。虽然ADC10牵扯的寄存器配置很多,但实际使用起来并不复杂。
二、相关寄存器
主要寄存器及功能有:ADC10AEx:模拟输入使能,用于使能某个管脚的模拟输入功能
ADC10MEM:保存AD转换的结果
ADC10CTL0:
- ADC10ON:开启/关闭ADC10
- ENC:Enable conversion。几乎所有的ADC10设置都要在ENC=0时进行。
- ADC10SC:Start conversion。开始转换后会自动清零。
- SREFx:选择正负基准源
- REFOUT、REFBURST、REF2_5V、REFON:选择内部基准源及其工作方式
- ADC10SHTx:选择采集和保持的时钟周期数目
- ADC10SR:选择reference buffer drive capability,影响最大采集速率
- ADC10IE、ADC10IFG:中断使能和中断标志位
- MSC:多次采集转换设置,只用于序列(sequence)或反复(repeated)模式采样。
ADC10CTL1:
- INCHx:输入通道选择,可选择外部管脚、基准源、内部温度传感器等。
- SHSx:选择采样信号由谁触发,默认是ADC10SC位,也可以是TimerA.OUTx。
- ADC10DF:转换数据格式,直接二进制或者二补码。
- ADC10SSELx、ADC10DIVx:选择ADC10的时钟,分频比。时钟默认采用ADC10内部的专门时钟ADC10OSC,频率约在5MHz左右。
- CONSEQx:选择模式,有单通道单次(默认)、多通道单次、单通道重复、多通道重复四种。
- ADC10BUSY:标志ADC10是否采样、转换完成。
如果使用到DTC的功能,还需要操作ADC10DTC0、ADC10DTC1、ADC10SA寄存器,具体可查看MSP430x2xx Family User's Guide。
三、代码示例
利用ADC10,每2秒读取一次A6(P1.6)通道上的电压,通过串口打印显示。// voltage meter 2015.10.1 // for MSPG2 launchpad, VCC = 3.6V; and if Vcc changes, // ref_vcc should be modified. #include "io430.h" #define A6 BIT6 // ADC input pin P1.6 #define RXD BIT1 //P1.1 #define TXD BIT2 //P1.2 #define IDLE 0 #define BUSY 1 // function definitions void initADC10(void); void initTA0(void); void sendByte(unsigned char); void printf(char *, ...); void initUART(void); // global variables float volts = 0.0; // unit: mV float ref_vcc = 3600.0; char i = 0; char status = IDLE; void main( void ) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; // DCO setup BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; // ADC10 setup initADC10(); // UART setup initUART(); // Timer0 setup initTA0(); __enable_interrupt(); LPM0; while(1) { switch(status) { case IDLE: break; case BUSY: ADC10CTL0 |= ADC10SC; // start a new conversion while ((ADC10CTL1 & ADC10BUSY) == 0x01); // wait for conversion to end volts = ADC10MEM * ref_vcc /1023.0; printf("Voltage: %i mV\r\n", (int)volts); status = IDLE; break; } LPM0; } } void initADC10(void) { // Use Vcc(3.6V)/GND for Refs, 16 x ADC10CLKs, reference buffer on, turn on ADC ADC10CTL0 = SREF_0 + ADC10SHT_2 + ADC10SR + ADC10ON; // A6 input, use ADC10CLK div 1, single channel mode ADC10CTL1 = INCH_6 + SHS_0 + ADC10SSEL_0 + ADC10DIV_0 + CONSEQ_0; // ADC input on P1.6 ADC10AE0 = A6; // Enable conversions ADC10CTL0 |= ENC; } void initTA0(void) { TA0CCR0 = 62550 - 1; TA0CCTL0 = CCIE; // enable compare interrupt TA0CTL = TASSEL_2 + ID_3 + MC_1 + TACLR; // input clock: SMCLK/8 -> 125kHz; Up to CCR0 mode // timer overflow freq: 125k/(TA0CCR0+1) -> 2Hz -> 500ms // clear and start the timer, up mode } void initUART(void) { //config P1.1 RXD, P1.2 TXD P1SEL |= TXD + RXD; P1SEL2 |= TXD + RXD; //reset UCA0, to be configured UCA0CTL1 = UCSWRST; //config UCA0CTL1 |= UCSSEL_2; //SMCLK UCA0BR0 = 104; UCA0BR1 = 0;//1MHz baut rate = 9600 UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1 //make UCA0 out of reset UCA0CTL1 &= ~UCSWRST; } void sendByte(unsigned char byte ) { while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = byte; // TX -> RXed character } //interrupt service routines #pragma vector = TIMER0_A0_VECTOR __interrupt void CCR0_ISR(void) { if(++i == 4) // interval: 1/2 * 4 = 2s, freq: 0.5Hz { // automatic flag clearing i = 0; status = BUSY; LPM0_EXIT; } }
相关文章推荐
- web前端面试题
- 找出360云盘的离线下载
- linux查看用户操作历史
- 获取相册
- 用数组来实现表(ArrayList)
- python连接数据库设置
- 字符串拆分-Java
- 【转载,百科】size_t,神奇的类型
- Sqlserver2000联系Oracle11G数据库进行实时数据的同步
- java篇 【8】由Java封装性引出的联想
- NET基础课--异常处理X
- leetcode@ [214]Shortest Palindrome
- js从输入框读取内容,比较两个数字的大小
- POJ 2309:BST lowbit
- POJ 2309:BST lowbit
- web前端-js通过object创建对象
- 函数
- 实现百度地图导航Demo的语音播报功能
- MySQL中的UNIX_TIMESTAMP函数使用总结 :
- 两段很鼓励很鼓励自己的话