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.

Synchronizing PWMs

Other Parts Discussed in Thread: TM4C123GH6PM

I am using the TIVA C (TM4C123GH6PM) launchpad, and I am trying to create 2 digital signals.  I need a 500kHz output with a 50% duty cycle, and a 25kHz output with a  20% duty cycle.  These signals need to be low jitter and synchronized so that the falling edge happens at the same time for both signals.  Here is what I have so far using the PWM modules, but I am unable to get the falling edges to line up.  I don't want the timing of these to be affected by other things going on in the processor, so that's why I picked PWMs.

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_gpio.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/gpio.h"
#include "driverlib/pwm.h"

#define GPIO_PB6_M0PWM0         0x00011804
#define GPIO_PB7_M0PWM1         0x00011C04
#define GPIO_PB4_M0PWM2         0x00011004
#define GPIO_PB5_M0PWM3         0x00011404
#define GPIO_PE4_M0PWM4         0x00041004
#define GPIO_PE5_M0PWM5         0x00041404
#define GPIO_PF1_M1PWM5         0x00050405
#define GPIO_PF2_M1PWM6         0x00050805
#define GPIO_PF3_M1PWM7         0x00050C05

int
main(void)
{
    //Set the clock
    SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_INT);  // SET SYSTEM CLOCK FOR 80Mhz, off of PLL

    //Configure PWM Clock to match system
    SysCtlPWMClockSet(SYSCTL_PWMDIV_1);

    // Enable the peripherals used by this program.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);  //The Tiva Launchpad has two modules (0 and 1). Module 1 covers the LED pins

    //Configure PF1,PF2,PF3 Pins as PWM
    GPIOPinConfigure(GPIO_PF1_M1PWM5);
    GPIOPinConfigure(GPIO_PF2_M1PWM6);

    GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2);

    //Configure PWM Options

    PWMGenConfigure(PWM1_BASE, PWM_GEN_2, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
    PWMGenConfigure(PWM1_BASE, PWM_GEN_3, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
    //Set the Period (expressed in clock ticks)
    PWMGenPeriodSet(PWM1_BASE, PWM_GEN_2, 160);
    PWMGenPeriodSet(PWM1_BASE, PWM_GEN_3, 3200);

    PWMPulseWidthSet(PWM1_BASE, PWM_OUT_5,80);  //set 50% duty cycle
    PWMPulseWidthSet(PWM1_BASE, PWM_OUT_6,2560); //set 20% duty cycle
    // Enable the PWM generator
    PWMGenEnable(PWM1_BASE, PWM_GEN_2);
    PWMGenEnable(PWM1_BASE, PWM_GEN_3);

    // Turn on the Output pins
    PWMOutputState(PWM1_BASE, PWM_OUT_5_BIT | PWM_OUT_6_BIT, true);

    //Do nothing (will handle other tasks later on)
    while(1);
}

Right now, the 25kHz falling edge happens .5us after the falling edge of the 500kHz.  Are there any suggestions on how to fix this?

Thanks.

  • Hi Bryson,

    The PWM Generators need to be synchronized, and the simplest way to do it is by Reset the counter using PWMSYNC register.

    PWMSyncTimeBase(PWM1_BASE, (PWM_GEN_2_BIT|PWM_GEN_3_BIT);

    Enable the PWM as you have done, otherwise, the output may glitch

    Amit

  • Ok, I did that, and the falling edges are still not aligned, but I think it might be because I am in UP/Down mode, which may aligns to the center instead of the edge of the period.  I changed it to PWM_GEN_MODE_DOWN and now the edges are aligned.  Only problem is, the falling edge of the 25kHz 20% duty cycle is aligned with the rising edge of the 500kHz 50% duty cycle.  I had to use the PWMOutputInvert function to fix that problem.

    Thanks,

    Bryson

  • Hi Bryson

    Yes, you are correct that in UP/DOWN mode the PWM is centre aligned. Good thinking on changing it to DOWN Mode.

    As for the alignment of the edges, while PWMOutputInvert function will invert the lines, the PWMSyncTimeBase shoiud have forced them to realign as it forces the PWM counters to start from the load value.

    Amit