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.

MSP430 TimerA 输出PWM波形的问题

Other Parts Discussed in Thread: MSP430G2452

dear TI‘s fellows:

     我正学习430TimerA,我现在想通过timerA 产生两路pwm波形。

1.当我没使用中断时,通过示波器观察到预期的波形,这没问题;

2.问题在于我想使用中断,我的思路是:通过中断服务程序分别改变CCR1,CCR2的值,这样就能很灵活的改变pwm的占空比等参数,但为何我在示波器上什么也看不到,连基本波形都没有;求解答

#include <msp430g2452.h>

unsigned char test1=0;
unsigned char test2=0;
unsigned char test=0;

int main()
{
//wdt
WDTCTL = WDTPW +WDTHOLD;//SHUTDOWN WDT

//basic clock system
DCOCTL = CALDCO_8MHZ;// calibration DCO ,8MHZ,(10FC)
BCSCTL1 = CALBC1_8MHZ;// calibration bcs, 8MHZ,(10FD)


//DISABLE INT
_DINT();


//P1.2,P1.4 FUNCTION
P1DIR |= BIT2 + BIT4;//P1.2,P1.4output
P1SEL |= BIT2 + BIT4;//TA1, TA2 function options
P1SEL2 |= BIT4;//DATASHEET :TA1(1,0),TA2(1,1)

//TIMER A
TA0CTL = TASSEL_2 + ID_3 + MC_1;           // SMCLK,8DIV->1MHZ, UP MODE
CCR0 = 50000;//50ms;
TA0CCTL1 = OUTMOD_4 ;// mode 4: TOGGLE
CCR1 = 1000;//1000us
TA0CCTL2 =OUTMOD_4; // MODE 4: TOGGLE
CCR2 = 10000;//10ms


TA0CCTL1 &= ~CCIFG;
TA0CCTL2 &= ~CCIFG;
TA0CCTL1 |= CCIE;
TA0CCTL2 |= CCIE;

//ENABLE INT
_EINT();


while(1)
{


}

}


#pragma vector =TIMER0_A1_VECTOR // 0xFFF0
__interrupt void TMR0_A1_INT(void)
{
switch(TAIV)
{
case 02 :                            //CCR1 INT
TA0CCTL1 &= ~CCIFG;
CCR1 += 1000;                /1000us           此处为P1.2的半周期
break;


case 04 :                             //CCR2 INT
TA0CCTL2 &= ~CCIFG;
CCR2 += 10000;                 //10ms          此处为P1.4的半周期
break;
}

  • 你好:

    楼主先参考一下下面的代码,是关于G2xx2的PWM的。

    //******************************************************************************
    // MSP430G2xx2 Demo - Timer_A, PWM TA1-2, Up Mode, DCO SMCLK
    //
    // Description: This program generates one PWM output on P1.2 using
    // Timer_A configured for up mode. The value in CCR0, 512-1, defines the PWM
    // period and the value in CCR1 the PWM duty cycles.
    // A 75% duty cycle on P1.2.
    // ACLK = na, SMCLK = MCLK = TACLK = default DCO
    //
    // MSP430G2xx2
    // -----------------
    // /|\| XIN|-
    // | | |
    // --|RST XOUT|-
    // | |
    // | P1.2/TA1|--> CCR1 - 75% PWM
    //
    // D. Dang
    // Texas Instruments, Inc
    // December 2010
    // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
    //******************************************************************************

    #include <msp430.h>

    int main(void)
    {
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    P1DIR |= 0x0C; // P1.2 and P1.3 output
    P1SEL |= 0x0C; // P1.2 and P1.3 TA1/2 options
    CCR0 = 512-1; // PWM Period
    CCTL1 = OUTMOD_7; // CCR1 reset/set
    CCR1 = 384; // CCR1 PWM duty cycle
    TACTL = TASSEL_2 + MC_1; // SMCLK, up mode

    _BIS_SR(CPUOFF); // Enter LPM0
    }

  •   dear  :

            你贴的代码我可以明白,TI 其它的示例代码我也看懂了。现在的问题是加入中断为何产生不了波形,求解答。

  • 注意到你的程序中使能中断 _EINT();的这条语句应该在G2的编译环境下找不到对于的原型 你可以用仿真器 go to the define ,,, 试一下,我之前也遇到过这个问题(IAR 5.4),

    //ENABLE INT
    _EINT();

    你尝试打开中断利用

    _BIS_SR(GIE);                                   //使能总中断

    看看这样能不能解决问题

  • dear  Xutong Han2:

         你好,我把中断程序改了如下就可以得到相应的波形。


    #pragma vector =TIMER0_A1_VECTOR // 0xFFF0
    __interrupt void TMR0_A1_INT(void)
    {
    switch(TAIV)
    {
    case 02 : //CCR1 INT
    TA0CCTL1 &= ~CCIFG;
    CCR1 += 1000;//1000us
    if(CCR1 > 50000)
    CCR1 = 1000;                       //CCR0=50000,CCR1不断自加,大于50000时重设为1000;如此反复。

    test1++;                                

    break;


    case 04 : //CCR2 INT
    TA0CCTL2 &= ~CCIFG;
    CCR2 += 10000;   //10ms
    if(CCR2 > 50000)
    CCR2 = 10000;
    test2++;
    break;
    }}

     //但是按照我开始的想法:在up 模式下,CCR1不断自加 并产生中断;当CCR1>50000时,不会发生捕获;当CCR1的值大于65535时,16位寄存器溢出得到一个新值,并可产生捕获中断。如此反复。  可是程序结果却不是这样。

  • if(CCR1 > 50000)
    CCR1 = 1000;                       //CCR0=50000,CCR1不断自加,大于50000时重设为1000;如此反复。

    通过测试当CCR1=51000时 重新置为CCR1=1000 相应的PWM波形的也会发生变化,你说当CCR1的值大于65535时,16位寄存器溢出得到一个新值,并可产生捕获中断,CCR1的值在等于51000时已经置位为1000不会大于65535,

  • /**************** Timer A ——>PWM ******************
    UP MODE : CCR0 -> PWM period
    CCR1 -> TA0.1 OUTPUT (P1.2)
    CCR2 -> TA0.2 OUTPUT (P1.4)

    **********************************************************/
    #include <msp430g2452.h>

    unsigned char test1=0;                                     // these three vars for test
    unsigned char test2=0;
    unsigned char test=0;

    int main()
    {
    //wdt
    WDTCTL = WDTPW +WDTHOLD;                       //SHUTDOWN WDT

    //basic clock system
    DCOCTL = CALDCO_8MHZ;                               // calibration DCO ,8MHZ,(10FC)
    BCSCTL1 = CALBC1_8MHZ;                             // calibration bcs, 8MHZ,(10FD)


    //DISABLE INT
    _DINT();


    //P1.2,P1.4 FUNCTION
    P1DIR |= BIT2 + BIT4;                                                              //P1.2,P1.4output
    P1SEL |= BIT2 + BIT4;                                                             //TA1, TA2 function options
    P1SEL2 |= BIT4;                                                                      //DATASHEET :TA1(1,0),TA2(1,1)

    //TIMER A
    TA0CTL = TASSEL_2 + ID_3 + MC_1;                                  // SMCLK,8DIV->1MHZ, UP MODE
            //TA0CTL = TASSEL_2 + ID_3 + MC_3;                                // SMCLK,8DIV->1MHZ, UP and DOWN MODE

                //CCR0 = 50000;                                           //50ms;  
                //CCR0 = 65535;                                  //65ms;      只有改值可以产生正常波形
    CCR0 = 60000;                                               //60ms;

    TA0CCTL1 = OUTMOD_4 ;                                   // mode 4: TOGGLE
    CCR1 = 1000;                                                         //1000us
    TA0CCTL2 =OUTMOD_4;                                     // MODE 4: TOGGLE
    CCR2 = 10000;                                                      //10ms
    //TA INTERRUPT SETUP
    TA0CCTL1 &= ~CCIFG;
    TA0CCTL2 &= ~CCIFG;
    TA0CCTL1 |= CCIE;
    TA0CCTL2 |= CCIE;

    //ENABLE INT
    _EINT();


    while(1)
    {

    test = test1;

    }

    }


    #pragma vector =TIMER0_A1_VECTOR              // 0xFFF0
    __interrupt void TMR0_A1_INT(void)
    {
    switch(TAIV)
    {
    case 02 : //CCR1 INT
    TA0CCTL1 &= ~CCIFG;
    CCR1 += 1000;                                           //1000us
    // if(CCR1 > 50000)
    // CCR1 = 1000;
    test1++;
    break;


    case 04 : //CCR2 INT
    TA0CCTL2 &= ~CCIFG;
    CCR2 += 10000;                                    //10ms
    // if(CCR2 > 50000)
    // CCR2 = 10000;
    test2++;
    break;
    }

    }

    dear  Xutong Han2:

        是我没有表述清楚。请看以上代码,我测试该代码时。红色标注的三条语句,只有当CCR0为65535时,可以产生正常的波形;为其他两个值都不可以,为什么会这样啊。

  • TA0CCTL1 = OUTMOD_4 ;                                   // mode 4: TOGGLE

    TA0CCTL2 =OUTMOD_4;                                     // MODE 4: TOGGLE

    你用的都是TOGGLE模式, 也就是The output is toggled when the timer counts to the TACCRx value. The output period is double the timer period. 这个和CCR0的值没有关系,如果你想用CCR0做PWM的周期尝试Reset/Set  OUTMOD_7模式,