TI中文支持网
TI专业的中文技术问题搜集分享网站

MSP430 TimerA 输出PWM波形的问题

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;
}

Leon Yan:

你好:

楼主先参考一下下面的代码,是关于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}

yingjun zhu:

回复 Leon Yan:

  dear Leon Yan :

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

Xutong Han2:

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

//ENABLE INT_EINT();

你尝试打开中断利用

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

看看这样能不能解决问题

yingjun zhu:

回复 Xutong Han2:

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位寄存器溢出得到一个新值,并可产生捕获中断。如此反复。  可是程序结果却不是这样。

Xutong Han2:

回复 yingjun zhu:

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

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

yingjun zhu:

回复 Xutong Han2:

/**************** 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 testunsigned 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时,可以产生正常的波形;为其他两个值都不可以,为什么会这样啊。

Xutong Han2:

回复 yingjun zhu:

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模式,

赞(0)
未经允许不得转载:TI中文支持网 » MSP430 TimerA 输出PWM波形的问题
分享到: 更多 (0)