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.

CCS/MSP430G2231: Phase shifting PWM

Part Number: MSP430G2231


Tool/software: Code Composer Studio

Hello, I am new to programming the MSP430 microcontroller.

I want 2 PWM outputs. I am restricted to a MSP430G2231 chip - and thus one timer. I have generated the PWM signal I wanted. I want to just phase shift this PWM signal and output it (so that PWM1 and PWM2 pulses DO NOT overlap).  I'm not sure how to approach this. Should I load the PWM signal into some kind of buffer variable and then manipulate that variable? Perhaps apply a delay to that variable?

I put together the code below - I only get a high signal on P1.3 (PWM2 output pin).

#include <msp430.h>

int status;

void main(void)
{
WDTCTL = WDTPW | WDTHOLD;          // Stop watchdog timer

//------Set CLOCK------------------------------------------------
DCOCTL = 0;                                           // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_1MHZ;                  // Set range
DCOCTL = CALDCO_1MHZ;                  // Set DCO step + modulation
//----------------------------------------------------------------------

//------Set PWM----------------------------------------------------

P1DIR |= BIT6;                                        // P1.2 PWM1 output
P1SEL |= BIT6;                                       // P1.2 as TA0.1
CCR0 = 900;                                          // PWM Period/2
CCTL1 = OUTMOD_6;                          // CCR1 toggle/set
CCR1 = 850;                                         // CCR1 PWM duty cycle
TACTL = TASSEL_2 + MC_3;              // SMCLK, up-down mode

//------Manipulate PWM-----------------------------------------

P1DIR |= 0b00001000;                        // Set P1.6 as an input & P1.3 as PWM2 output
status = P1IN & BIT6;                          // Load PWM1 signal into status variable
if (status==1)                                        // Looks for rising edge of PWM1 and delays 10 then outputs that same pulse
{
__delay_cycles(10);
P1OUT = status;
}

__bis_SR_register(LPM0_bits); // Enter LPM3

}

Any help would be greatly appreciated!

Thank you!

  • TimerA doesn't really provide a general phase shift mechanism. In general, the pulses need to be anchored either at the beginning or the end of the period (or for Up/Down, in the middle). 

    That said, there are some special-ish cases which can be accommodated, and I can't tell whether yours is one of them. Are PWM1 and PWM2 inverses of one another?

  • PWM1 and PWM2 are not inverses of each other - there has to be dead time between the pulses between the two signals to ensure both outputs aren't on at the same time.

    I was thinking about utilizing the a count variable - perhaps one that is utilized by the timer function to count up to CCR0, but I'm not sure if that exists. Maybe I can use DC0CTL?

  • A forum search for "msp430 dead time" turned up:

    https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/758059

    DCOCTL controls the system clock. You should be careful what you do with it.

  • Hey Katie,

    Do the PWMs every need to change frequency?  Are they always 50% duty cycle, or does the duty cycle need to change as well?  

    Looking at the timer on that device, generating 2x PWMs is going to be quite difficult especially with only 2 capture compare registers in the timer.  The only idea I can come up with is to run the timer in full continuous mode and set your PWM frequency by adjusting your system and timer clocks.  You won't have a ton of control on the exact frequency this way, but if you can get the timer period to an acceptable level then you will have both TimerA_CCRx registers available to work with, and an overflow interrupt.  

    In this mode, you can use the overflow interrupt and CCR0 to generate PWM 1, then you can use CCR2 to try and generate PWM2.  For this seconds PWM, you would probably need to manually toggle a GPIO in the Interrupt and you would need to add/subtract the PWM period to the CCR2 register.  Basically, you are going to use this one register to trigger both rising and falling edges and will have to continue configuring it back and forth to set the appropriate phase. You will also have to handle overflows in the case that the PWM period is beyond the max timer count, and loop it back to the low side.  Same if phase shifts the opposite direct. 

    It's a pretty complicated solution.  It would be much easier to use a MCU with 2x timers, or at the very least 3x CCR registers vs the 2x on the MSP430G2231.

    Thanks,

    JD  

**Attention** This is a public forum