This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

对MSP430G2553示例程序ADC10, Sample A1, TA1 Trig几点疑问



现附上示例程序:

//******************************************************************************
// MSP430G2x33/G2x53 Demo - ADC10, Sample A1, 1.5V, TA1 Trig, Set P1.0 if < 0.5V
//
// Description: A1 is sampled 16/second (ACLK/2048) with reference to 1.5V.
// Timer_A is run in upmode and TA1 is used to automatically trigger
// ADC10 conversion, TA0 defines the period. Internal oscillator times sample
// (16x) and conversion (13x). Inside ADC10_ISR if A1 < 0.5Vcc, P1.0 is set,
// else reset. Normal mode is LPM3.
// //* An external watch crystal on XIN XOUT is required for ACLK *//
// D. Dang
// Texas Instruments Inc.
// December 2010
// Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************
#include "msp430g2553.h"

void main(void)
{
WDTCTL = WDTPW + WDTHOLD;                             // Stop WDT
ADC10CTL1 = SHS_1 + CONSEQ_2 + INCH_1;    // TA1 trigger sample start
ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE;
__enable_interrupt();                                                    // Enable interrupts.
TACCR0 = 30;                                                                // Delay to allow Ref to settle
TACCTL0 |= CCIE;                                                        // Compare-mode interrupt.
TACTL = TASSEL_2 + MC_1;                                     // TACLK = SMCLK, Up mode.
LPM0;                                                                              // Wait for delay.
TACCTL0 &= ~CCIE;                                                    // Disable timer Interrupt
__disable_interrupt();
ADC10CTL0 |= ENC;                                                   // ADC10 Enable
ADC10AE0 |= 0x02;                                                     // P1.1 ADC10 option select
P1DIR |= 0x01;                                                             // Set P1.0 output
TACCR0 = 2048-1;                                                     // PWM Period
TACCTL1 = OUTMOD_3;                                          // TACCR1 set/reset
TACCR1 = 2047;                                                        // TACCR1 PWM Duty Cycle
TACTL = TASSEL_1 + MC_1;                                  // ACLK, up mode

__bis_SR_register(LPM3_bits + GIE);                  // Enter LPM3 w/ interrupts
}

// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
if (ADC10MEM < 0x155)                 // ADC10MEM = A1 <  0.5V?
P1OUT &= ~0x01;                           // Clear P1.0 LED off
else
P1OUT |= 0x01;                                  // Set P1.0 LED on
}

#pragma vector=TIMER0_A0_VECTOR
__interrupt void ta0_isr(void)
{
TACTL = 0;
LPM0_EXIT;                                        // Exit LPM0 on return
}

以下是7点问题:

1.__enable_interrupt();进入的是ADC10_VECTOR中断还是TIMER0_A0_VECTOR中断?

2.这段代码中TIMER0_A0_VECTOR中断起到的又是什么作用?

3.这段代码中并没有设置ADC10SSELx,是没有设置,还是设置成了0:ADC10OSC?

4.他选择了CONSEQ = 2,那MSC位就默认为0了是吗?

5.整段程序竟然没有ADC10SC?难道不用Start sample-and-conversion了吗?

6.以下两个Timer的设置:

TACCR0 = 30;                                                                // Delay to allow Ref to settle
TACCTL0 |= CCIE;                                                        // Compare-mode interrupt.
TACTL = TASSEL_2 + MC_1;                                     // TACLK = SMCLK, Up mode.
LPM0;                                                                              // Wait for delay.
TACCTL0 &= ~CCIE;                                                    // Disable timer Interrupt

这里设置的Timer只是为了产生一个delay的?

TACCR0 = 2048-1;                                                     // PWM Period
TACCTL1 = OUTMOD_3;                                          // TACCR1 set/reset
TACCR1 = 2047;                                                        // TACCR1 PWM Duty Cycle
TACTL = TASSEL_1 + MC_1;                                  // ACLK, up mode

而这里的Timer才是为了触发ADC转换的?

7.

ADC10AE0 |= 0x02;                                                     // P1.1 ADC10 option select

这句的意思是说,选择P1.1作为信号的输入端吗?(之前他设置了INCH = 1)


P1DIR |= 0x01;                                                             // Set P1.0 output

这个把P1.0设置成输出端是为什么?

-----------------------------------------------------------------------------------------------------

问题很多,而且颇琐碎,谢谢各位了!

  •  你好,

    1.__enable_interrupt() 的意思是全局中断使能。(如果没有这句话,程序中的ADC10_VECTOR中断和TIMER0_A0_VECTOR中断都不会被响应

    2.程序中

    TACCR0 = 30;                                                                // Delay to allow Ref to settle
    TACCTL0 |= CCIE;                                                        // Compare-mode interrupt.
    TACTL = TASSEL_2 + MC_1;                                     // TACLK = SMCLK, Up mode.
    LPM0;                                                                              // Wait for delay.

    的作用是延时一段时间,让内部参考稳定。

    具体实现过程是设定闹钟(定时器),然后睡觉(休眠LPM0),等闹钟(定时器中断),醒来继续操作(退出低功耗)。

    回到你的问题,TIMER0_A0_VECTOR中断就是闹钟响了,退出休眠,继续执行LPM0;下面的程序。

  • 3.如果没有设置,就是上电复位默认值。设置成了0:ADC10OSC。

    4.是的。MSC为复位值为0,程序中未对其进行设置,所以还是0。

    5.因为本程序设定是定时器触发采样,所以不用ADC10SC。

    如图,四种触发方式只能选其一。

  • 6.

    TACCR0 = 30;                                                                // Delay to allow Ref to settle
    TACCTL0 |= CCIE;                                                        // Compare-mode interrupt.
    TACTL = TASSEL_2 + MC_1;                                     // TACLK = SMCLK, Up mode.
    LPM0;                                                                              // Wait for delay.
    TACCTL0 &= ~CCIE;                                                    // Disable timer Interrupt

    是的。这里设置的Timer只是为了产生一个delay的!

    TACCR0 = 2048-1;                                                     // PWM Period
    TACCTL1 = OUTMOD_3;                                          // TACCR1 set/reset
    TACCR1 = 2047;                                                        // TACCR1 PWM Duty Cycle
    TACTL = TASSEL_1 + MC_1;                                  // ACLK, up mode

    是的。这里的Timer才是为了触发ADC转换的!

    7.

    ADC10AE0 |= 0x02;                                                     // P1.1 ADC10 option select

    这句的意思是说,选择P1.1作为信号的输入端吗?(之前他设置了INCH = 1)

    是的,这句话的意思是,把P1.1切换到模拟功能。(默认是数字pin)


    P1DIR |= 0x01;                                                             // Set P1.0 output

    这个把P1.0设置成输出端是为什么?

    这句话的作用要看下面:

    // ADC10 interrupt service routine
    #pragma vector=ADC10_VECTOR
    __interrupt void ADC10_ISR(void)
    {
    if (ADC10MEM < 0x155)                 // ADC10MEM = A1 <  0.5V?
    P1OUT &= ~0x01;                           // Clear P1.0 LED off
    else
    P1OUT |= 0x01;                                  // Set P1.0 LED on
    }

    P1.0上接了一个LED灯来指示采样结果的状态(与0.5V比大小)。

    P1.0驱动LED,所以要设为输出。

  • 谢谢你的详细回复,学习了之后还有两个小问题:

    1.ADC10 通过引脚获取外部模拟信号是设置INCHx和ADC10AE0,

       但是在ADC12中没有ADC10AE0寄存器,那是只有通过设置INCHx了?

    2.if (ADC10MEM < 0x155)                 // ADC10MEM = A1 <  0.5V?

       这段指令:转换完成的值存到ADC10MEM中是以二进制的形式,这里REF取了1.5V,那0.5V是0x155是怎么转换的?

    Thanks!

  •  1. 建议看一下 User‘s Guide 和 code example , 结合起来看会比较清楚。

    2. ADC10的满量程是2的10次方,也就是1024。

    0x155 = 341

    0.5V = (341/1024)*1.5V