Two PWM signals with Dead time. MSP430G2452 (another PWM post)

Hello,

 

i am using the MSP430G2452, i have it in the Launch Pad and am trying to use it to produce two PWM signals that are comliments of eachother with some dead-time between transitions. The chip has one Timer0_A3 and 3 CC registers so its should be able to do it.

i have looked in the family user guide and want to do something like the picutre below (pg.364 of the MSP430x2xx family user guide)

IThis is my code

#include  <msp430g2452.h>

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
 
  P1DIR |= 0x06;                            // P1.2 and P1.1 to output
  P1SEL |= 0x06;                           
 
  CCR0 = 1000;     //PWM Period - Freq = (SMCLK freq)/(CCR0 value)
                                 //eg,SMCLK = 1MHZ so 1MHZ/1000 = 1Khz is the PWM Freq
  CCTL1 = OUTMOD_6;                         //CCR1 toggle/set
  CCTL2 = OUTMOD_2;                            //CCR2 toggle/reset
  CCR1 = 250;                               //CCR1 PWM duty cycle
  CCR2 = 50;                                //Dead time = CCR1 - CCR2 = 250 - 50 = 200
  TACTL = TASSEL_2 + MC_3; // TACTL = timer_A ctrl, TASSEL_2 = SMCLK, MC_3 = up/down mode

  _BIS_SR(LPM0_bits);                        // Enter LPM0
}

 

I can see the PWM on P1.2 but not on P1.1, obviously there is something wrong with my code, i was wondering if anyone could help me. I have looked at alot of the PWM dead-time related forum topics

http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/19031/73691.aspx#73691

http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/56142/205122.aspx#205122

http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/104860/369006.aspx#369006

http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/116416/413109.aspx#413109

But can't really seem to get it working

 

Thanks in advance

Michael Dalton

  • Michael Dalton
    I can see the PWM on P1.2 but not on P1.1

    For a reason: P1.1 is connected with TA0.0, that is the output of the CCR0 unit. Your second PWM is from CCR2 which is the TA0.2 signal on P1.4.

    So
      P1DIR |= 0x14;                            // P1.2 and P1.4 to output
      P1SEL |= 0x14;                           
    should do the trick.

    And of course the two PWMs are on (physical) pin 4 and 6 and not on pin 3 and 4.

  • In reply to Jens-Michael Gross:

    Jens-Michael Gross

    Michael Dalton
    I can see the PWM on P1.2 but not on P1.1

    For a reason: P1.1 is connected with TA0.0, that is the output of the CCR0 unit. Your second PWM is from CCR2 which is the TA0.2 signal on P1.4.

    So
      P1DIR |= 0x14;                            // P1.2 and P1.4 to output
      P1SEL |= 0x14;                           
    should do the trick.

    And of course the two PWMs are on (physical) pin 4 and 6 and not on pin 3 and 4.

    Hey Jens,

    I changed the code to reflect what you suggested, Below are the waveforms coming from P1.2(CH1) and P1.4(CH2)

    CH1 is behaving properly i.e. duty cycle of 75% with a frequency of [(SMCLK/CCR0)/2] = [(1MHz/1000)/2] = 500Hz

    But CH2 (P1.4) is outputting a waveform at 50% duty cycle with a frequency of SMCLK. I have tried changing the value for CCR2 but this seems to change nothing. I have also tried changing the mode for CCTL2 but with no results. Below is the waveform of CH2 (P1.4)

     

    Do you have any suggestions?

     

    Regards

    Michael Dalton

  • In reply to Michael Dalton:

    Hi Michael,

    Here's a snippet from the data sheet.  Looks like you must also set BIT4 in the P1SEL2 register (but not BIT2).

    This table also explains why you saw SMCLK on P1.4.  It gets tricky keeping track of all the pin configurations.

    Jeff

  • In reply to Jeff Tenney:

    Jeff Tenney

    Hi Michael,

    Here's a snippet from the data sheet.  Looks like you must also set BIT4 in the P1SEL2 register (but not BIT2).

    This table also explains why you saw SMCLK on P1.4.  It gets tricky keeping track of all the pin configurations.

    Jeff

     

    Jeff,

    Thanks that was it!!! :)

    So if anyone is interested the code remains the same at the start except for these lines (plus one)

    P1DIR |= 0x14;

    P1SEL |= 0x14;

    P1SEL2 |= BIT4;

    The following pictures show CCR2 at different values

    Here CCR2 = 220, so the dead time = CCR1 - CCR2 = 250 - 220 = 30

    Here CCR2 = 100, so the dead time = CCR1 - CCR2 = 250 - 100 = 150

     

    Thanks again, Jeff and Jens

    Regards

    Michael Dalton

  • In reply to Michael Dalton:

    Hi Guys

    I am using MSP430F2011, why I cannot use CCR2 on this part ??

    Thanks

  • In reply to marcelo deoliveira:

    Because it only has 2 capture and compare registers (CCR0 and CCR1).

  • In reply to Bernhard Weller:

    Thanks, Bernhard

    The reason of my question is, I have a code( part  of it is bellow)  that generates 1Khz PWM all the time, which generates an interrupt every 300000. In other words it does some type of mathematic calculation and keeps tracking of solar power of solar panel for the entire day doing it every 5 minutes. I want to be able to hook up an eZ430 board and use its UART to monitor through a software called realterm so I can data log over the days. I am no so familiar with UART but every example I saw and try has something to do with the Time_A so it interferes to the code, because at night the code goes to this subroutine putting out the PWM throughout P1.6 which then controls a LED driver so when it happens because the UART part of the code the LED start to blink and the PWM of 1Khz goes crazy. Any sugetion ???

    Thanks

    Bellow is part of the code..

     

    //******************************************************************************

    //PWM Frequency 1Khz

    //******************************************************************************

    #define PWM_PERIOD 1000

    //

    //******************************************************************************


    //Configure IO

      P1OUT &= ~ 0X40;                         // Sets the output to low GPIO//P1OUT &= ~ 0X40;                            // Sets the output to low GPIO

      P1DIR |= 0X40;                             // Set pin P1.6 to output direction//P1DIR |= 0X40;

      P1SEL &= ~0x40;                           // Turn LED ON//P1SEL &= ~0x40;                          // Turn LED OFF

     

     

     

    //Configure timer A

      TACCTL0 = CCIE;                                               // TACCR0 interrupt enabled

      TACCTL1 = OUTMOD_7;                                   // TACCR1 Reset/Set

      TACCR0 = PWM_PERIOD;                                // Set PWM for 1Khz operation

      TACCR1 = PWM_PERIOD >> 1;                        // Start with 50% duty cycle

      TACTL = TASSEL_2 + MC_1 + TACLR;              // SMCLK (1MHz), Clear TAR, Up mode

     

     

    //Main loop starts here

      while(1)

      {

      SD16CCTL0 |= SD16SC;                   // Set bit to start conversion

     _BIS_SR(LPM0_bits + GIE);               // Enter LPM0 take off  _BIS_SR(LPM0_bits + GIE);

     

    //LED driver control starts here

        if (Solar_Volts >= 5024)                                                             // If Solar panel is more than  1 Volts turn LED OFF;

           P1SEL &= ~0x40;                                                                     // Turn LED OFF;

        if ((Solar_Volts >= 15072) && (Bat_Volts >= 25170))        // If solar  Vp = 3 Volts // battery Vbat = 5.01 Volts, reset the code, in other words consider battery is above 3 V so wait for dark then turn LED ON; 

           i = 1;                                                                      // Reset i = 1;

        if (Bat_Volts <= 25170)                                        // If Battery is less than 5.01 Volts;

        {    

           i = 0;                                                                  // i = 0;

           P1SEL &= ~0x40;                                         // Turn LED OFF;P1SEL &= ~0x04

        }

        if ((Solar_Volts <= 3014) && (Bat_Volts >= 25170) && (i))  //4521   3014=600mV

        {      

           TACCR1 =  535;                                                                               //305 = 30% = 120mA

           P1SEL |= 0x40;                                                                                  // Turn  LED ON;

        }

      }

     

     

    // Timer A0 interrup service routine

      #pragma vector = TIMERA0_VECTOR

    __interrupt  void Timer_A (void)

    {

        pwmCycles++;               //Increment PWM cycle count

        if(pwmCycles == 300000)    //Has 5 minuts passed

        {

           Power_Count();          //Do the Power calculation

           pwmCycles = 0;          //Reset the counter

        }

    }


     

  • In reply to marcelo deoliveira:

    marcelo deoliveira
    I am no so familiar with UART but every example I saw and try has something to do with the Time_A


    This is because the 2011 does not have an UART. So it uses a tiemr to trigger interrupts when a bit should be sent,, and uses a tiemr to keep track of input line changes to calculate the incoming bits. This is called a 'sfotware uart'. And yes, software UART and PWM interfere with each other.
    I don't know whether the typical software UART requires two CCR units (all the 2011 has). I think it could be done with just one, and  alittle bit more math or RX error.
    However, if you know the UART timer tick and interrupt frequency, you may be able to combine a software UART and your long-time timer wakeup.

    Also, there's nothing that keeps you from switchign between two uses, if you don't need them at the same time.

  • In reply to Jens-Michael Gross:

    Thanks Jens

    I am actually using MSP430F2013. I am using the 16-Bit Sigma-Delta A/D Converter of it as well for 3 channels, do you know any other part that would allow me to do Timer_A and UART independent of each other keeping the 16_Bit Sigma-Delta software  ?

    Thanks 

     

  • In reply to marcelo deoliveira:

    It looks like there are no 2x family devices with both, SD16 and hardware UART.
    At least not according to the selection guide.

    There are several 4x family devices with this combination, e.g. the MSP430F477.

    Be aware that there might be subtle differences between families.