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.

定时器同时输出好几路pwm,一个定时器不是共用的一个计数器吗?同时输出好几路pwm,它是如何实现的

定时器同时输出好几路pwm,一个定时器不是共用的一个计数器吗?同时输出好几路pwm,它是如何实现的

  • MSP430系列单片机的TimerA结构复杂,功能强大,当PWM 不需要修改占空比和时间时,TimerA 能自动输出PWM,而不需利用中断维持PWM输出。单片机内部均含有两个定时器,TA和TB;TA有三个模块,CCR0-CCR2;TB含有CCR0-CCR67个模块;其中CCR0模块不能完整的输出PWM波形(只有三种输出模式可用);TA可以输出完整的2路PWM波形;TB可以输出6路完整的PWM波形。

    定时器的PWM输出有有8种模式:

    输出模式0  输出模式:输出信号OUTx由每个捕获/比较模块的控制寄存器CCTLx中的OUTx位定义,并在写入该寄存器后立即更新。最终位OUTx直通。 
    输出模式1 置位模式:输出信号在TAR等于CCRx时置位,并保持置位到定时器复位或选择另一种输出模式为止。 
    输出模式2 PWM翻转/复位模式:输出在TAR的值等于CCRx时翻转,当TAR的值等于CCR0时复位。 
    输出模式3 PWM置位/复位模式:输出在TAR的值等于CCRx时置位,当TAR的值等于CCR0时复位。 
    输出模式4 翻转模式:输出电平在TAR的值等于CCRx时翻转,输出周期是定时器周期的2倍。 
    输出模式5复位模式:输出在TAR的值等于CCRx时复位,并保持低电平直到选择另一种输出模式。 
    输出模式6PWM翻转/置位模式:输出电平在TAR的值等于CCRx时翻转,当TAR值等于CCR0时置位。 
    输出模式7PWM复位/置位模式:输出电平在TAR的值等于CCRx时复位,当TAR的值等于CCR0时置位。

    1. 计数模式:

    增计数模式 
    捕获/比较寄存器CCR0用作Timer_A增计数模式的周期寄存器,因为CCR0为16位寄存器,所以该模式适用于定时周期小于65 536的连续计数情况。计数器TAR可以增计数到CCR0的值,当计数值与CCR0的值相等(或定时器值大于CCR0的值)时,定时器复位并从0开始重新计数。

    连续计数模式 
    在需要65 536个时钟周期的定时应用场合常用连续计数模式。定时器从当前值计数到0FFFFH后,又从0开始重新计数

    增/减计数模式 
    需要对称波形的情况经常可以使用增/减计数模式,该模式下,定时器先增计数到CCR0的值,然后反向减计数到0。计数周期仍由CCR0定义,它是CCR0计数器数值的2倍。

    1. TA定时器有比较、捕获两种工作方式;比较可以产生PWM波形等,捕获可以精确的测量时间;这里用的是比较输出。

    硬件介绍就这么多了,其他的可以参考msp430g2553—users_guide(用户指南)。

    1. 2.     程序实现:

    下面就给大家介绍msp430g2553生成pwm波。并控制舵机的转动,如果只需要生成pwm波的程序可以自行修改,其中主函数前一部分就是生成pwm波的部分。

    #include "msp430g2553.h"

     

    #define MCU_CLOCK 1000000

    #define PWM_FREQUENCY 44 // 当为44时,频率刚好50hz.

     

    #define SERVO_STEPS 180   // 设置一度步进

    #define SERVO_MIN 650     // 最小值0°

    #define SERVO_MAX 2700    // 大概转动180°

     

    unsigned int PWM_P =(MCU_CLOCK / PWM_FREQUENCY);// PWM 的频率

     

    void main (void)

    {

    unsigned int servo_stepval, servo_stepnow;

    unsigned int servo_lut[200];

    unsigned int i;

     

    // 计算步长值和当前步骤,默认定义为最小

    servo_stepval =((SERVO_MAX - SERVO_MIN)/ SERVO_STEPS );

    servo_stepnow = SERVO_MIN;

     

    // 赋值LUT

    for(i =0;i<200; i++)

    {

    servo_stepnow += servo_stepval;

    servo_lut[i]= servo_stepnow;

    }

     

     

     

    // 设置PWM波的输出

    WDTCTL = WDTPW + WDTHOLD;       // 关闭看门狗

    TACCTL1 = OUTMOD_7;             // TACCR1 复位/设置

    TACTL = TASSEL_2 + MC_1;        // SMCLK, upmode

    TACCR0 = PWM_P;                  // PWM 频率

    TACCR1 = servo_lut[0];          // TACCR1 PWM 占空比设置

    P1DIR |= BIT2;                  // 设置P1.2为普通IO口

    P1SEL |= BIT2;                  // 设置P1.2为TA1输出

     

    //转动角度设置

    while(1){

     

    // Go to 0°;+duty 3.0%。

    TACCR1 = servo_lut[0];

    __delay_cycles(1000000);

     

    // Go to 45°;+duty 4.8%。

    TACCR1 = servo_lut[45];

    __delay_cycles(1000000);

     

    // Go to 90°; +duty 7.4%.

    TACCR1 = servo_lut[90];

    __delay_cycles(1000000);

     

    // Go to 135°; +duty 9.8%.

    TACCR1 = servo_lut[146];

    __delay_cycles(1000000);

     

    // Go to 180°; +duty 12.3%.

    TACCR1 = servo_lut[190];

    __delay_cycles(1000000);

     

    // Go to 0°;+duty 3.0%。

    TACCR1 = servo_lut[0];

    __delay_cycles(1000000);

    }

     }

     

  • 几时到 servo_lut[0];   不产生中断吗?怎么没定时器A的中断函数。