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.

Multiple PWM using a MSP430afe2xx - TACCTL0 & CCI has no effect

Other Parts Discussed in Thread: MSP430AFE222

trying the example "Multiple Time Bases on a single MSP430 Timer Module", with a MSP430AFE222, I used following code: (Compiler MSPGCC)

#include <msp430afe222.h>

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
 
  //Calibrate DCO for 8MHz operation
  BCSCTL1 = CALBC1_8MHZ;
  DCOCTL = CALDCO_8MHZ;


  P2SEL |= BIT0;                            // P2.0 option select
  P2SEL2 |= BIT0;                           // P2.0 option select
  P2DIR |= BIT0;                            // P2.0 - output
 
  P1SEL |= BIT7+BIT6 ;                      // P1.7 - P1.6 option select
  P1SEL2 |= BIT7+BIT6;                      // P1.7 - P1.6 option select
  P1DIR |= BIT7+BIT6+BIT0;                  // P1.7 - P1.6 - P1.0 outputs



  TACCTL0 = OUTMOD_4 + CCIE;                // CCR0 toggle, interrupt enabled
  TACCTL1 = OUTMOD_4 + CCIE;                // CCR1 toggle, interrupt enabled
  TACCTL2 = OUTMOD_4 + CCIE;                // CCR2 toggle, interrupt enabled
  TACTL = TASSEL_2 +  MC_2 + TAIE;          // SMCLK, Contmode, int enabled

  _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0 w/ interrupt
return 0;
}

// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0 (void)
{
    if(TACCTL0 & CCI)                         // If output currently high
    {
        TACCR0 += 1000;                       
    }
    else
    {
        TACCR0 += 500;                        
    }
}

// Timer A1 Interrupt Vector (TA0IV) handler
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A1(void)
{
  switch( TA0IV )
  {
  case  2:  if(TACCTL1 & CCI)                 // If output currently high
            {
                TACCR1 += 700;                 
            }
            else
            {
                TACCR1 += 500;                
            }
           break;
  case  4:  if(TACCTL2 & CCI)                 // If output currently high
            {
                TACCR2 += 900;                
            }
            else
            {
                TACCR2 += 500;                
            }
           break;
  case 10: P1OUT ^= 0x01;                   // Timer overflow
           break;
  default: break;
  }
}

When I run the code, I get three perfect identical frequencies (just as expected). However, the separation of rising and falling edge (TACCTLx & CCI) to get different pulse widths has no effect. Each Pulse still has the same duty cycle ration of 50%, which would mean that (TACCTLx & CCI) is always ZERO. ???


What am I missing?

Thanks for your help!!

  • Check the datasheet, the pin mapping description and the table for TimerA3 under short-form-description.
    The three pins you selected are PWM output only.
    The capture inputs (and therefore the sources for the CCI bit) are P1.2, P1.1 and ACLK on this MSP. No wonder you don’t see any change.

    However, instead of checking CCIE, you could toggle the OUTMOD between SET and RESET. It can be done with a proper XOR. Check for bit OUTMOD2 to know which the current mode is, then toggle this bit.

    If(TACCTLx&OUTMOD2)
    TACCRx += y;

    Else
    TACCRx+=z;
    TACCTLx^=OUTMOD2;

    Be aware that this way of generating different PWMs will have an epic fail if you for some reason fail to change the CCRx value before the timer reaches the new value. This may happen if you have other ISRTs executing, have to block interrupts (e.g. for flash writing) or go into LPM with an extended wakeup time (LPM>0)

**Attention** This is a public forum