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.

2 PWM outputs on Tiva C Launchboard

Other Parts Discussed in Thread: TM4C123GH6PM

Hello,

I am having some problem with generating 2 PWM. I have one working just fine and would like to get another one (not necessarily synchronized) at the same time. The output of my first pwm on port B6 is good, but my second pwm output on port B7 is just noise.

I’m pretty sure I’m missing something since I’m new in µC programming…

Thanks for letting me know what’s wrong here:

void pwm0_init()
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    GPIOPinConfigure(GPIO_PB6_M0PWM0);
    GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_6);
    PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
}

void pwm1_init()
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    GPIOPinConfigure(GPIO_PB7_M0PWM1);
    GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_7);
    PWMGenConfigure(PWM1_BASE, PWM_GEN_1, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
}

void pwm0_start(unsigned long frequence, unsigned long duty_cycle)
{
    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, ROM_SysCtlClockGet() / frequence);
    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0, (PWMGenPeriodGet(PWM0_BASE, PWM_OUT_0) * duty_cycle) / 100);
    PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT, true);
    PWMGenEnable(PWM0_BASE, PWM_GEN_0);
}

void pwm1_start(unsigned long frequence, unsigned long duty_cycle)
{
	PWMGenPeriodSet(PWM1_BASE, PWM_GEN_1, ROM_SysCtlClockGet() / frequence);
	PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0, (PWMGenPeriodGet(PWM1_BASE, PWM_OUT_0) * duty_cycle) / 100);
	PWMOutputState(PWM1_BASE, PWM_OUT_0_BIT, true);
	PWMGenEnable(PWM1_BASE, PWM_GEN_1);
}

Thank you for your answers,

Florent

  • Hi,

    PB7 is in PWM base 0,  generator 0. So you got that wrong. Check Table 20-1

    I imagen you are using the tm4c123 launchpad? remember that now there is another tiva launchpad

  • Thanks for your answer. I tried to change my pwm1_init() and pwm1_start() as follows :

    void pwm0_init()
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        GPIOPinConfigure(GPIO_PB6_M0PWM0);
        GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_6);
        PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
    }
    
    void pwm1_init()
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        GPIOPinConfigure(GPIO_PB4_M0PWM2);
        GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_4);
        PWMGenConfigure(PWM0_BASE, PWM_GEN_1, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
    }
    
    void pwm0_start(unsigned long frequence, unsigned long duty_cycle)
    {
        PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, ROM_SysCtlClockGet() / frequence);
        PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0, (PWMGenPeriodGet(PWM0_BASE, PWM_OUT_0) * duty_cycle) / 100);
        PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT, true);
        PWMGenEnable(PWM0_BASE, PWM_GEN_0);
    }
    
    void pwm1_start(unsigned long frequence, unsigned long duty_cycle)
    {
    	PWMGenPeriodSet(PWM0_BASE, PWM_GEN_(1, ROM_SysCtlClockGet() / frequence);
    	PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, (PWMGenPeriodGet(PWM0_BASE, PWM_OUT_2) * duty_cycle) / 100);
    	PWMOutputState(PWM0_BASE, PWM_OUT_2_BIT, true);
    	PWMGenEnable(PWM0_BASE, PWM_GEN_1);
    }

    I still can't make this pwm1 work and I don't see why. What do you think about it?

    Thanks,

    Florent

    PS : Yes it's the Tiva TM4C123GH6PM I'm using.

  • Hello Florent

    What is the System Clock Frequency being used and what is the value of "frequence"?

    Regards

    Amit

  • Here is the main function where this information is :

    int main(void)
    {
    	ROM_FPUEnable();
    	ROM_FPULazyStackingEnable();
    
    	ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
    					   SYSCTL_XTAL_16MHZ);
    	
        pwm0_init(); // PWM0
        pwm1_init(); // PWM1
    
        pwm0_start(1000,50); //1kHz, 50% duty cycle
        pwm1_start(1000,50); //1kHz, 50% duty cycle
    
        while(1)
        {
        }
    }

    The system clock is 16MHz and the frequence is 1kHz.

    Regards,

    Florent

  • Hello Florent,

    Attached is the updated c file. I ran it on the LaunchPad and connected the output of the two PWM signals to the Blue and Red LED's and both of them are glowing fine. I did notice there was an error in the code due to the missing "{".

    #include "stdint.h"
    #include "stdbool.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/fpu.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/gpio.h"
    #include "driverlib/timer.h"
    #include "driverlib/pwm.c"
    #include "driverlib/pwm.h"
    #include "driverlib/pin_map.h"
    
    void pwm0_init()
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        GPIOPinConfigure(GPIO_PB6_M0PWM0);
        GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_6);
        PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
    }
    void pwm1_init()
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        GPIOPinConfigure(GPIO_PB4_M0PWM2);
        GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_4);
        PWMGenConfigure(PWM0_BASE, PWM_GEN_1, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
    }
    void pwm0_start(unsigned long frequence, unsigned long duty_cycle)
    {
        PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, SysCtlClockGet() / frequence);
        PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0, (PWMGenPeriodGet(PWM0_BASE, PWM_OUT_0) * duty_cycle) / 100);
        PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT, true);
        PWMGenEnable(PWM0_BASE, PWM_GEN_0);
    }
    void pwm1_start(unsigned long frequence, unsigned long duty_cycle)
    {
        PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, SysCtlClockGet() / frequence);
        PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, (PWMGenPeriodGet(PWM0_BASE, PWM_OUT_2) * duty_cycle) / 100);
        PWMOutputState(PWM0_BASE, PWM_OUT_2_BIT, true);
        PWMGenEnable(PWM0_BASE, PWM_GEN_1);
    }
    
    int main(void)
    {
        FPUEnable();
        FPULazyStackingEnable();
        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                           SYSCTL_XTAL_16MHZ);
    
        pwm0_init(); // PWM0
        pwm1_init(); // PWM1
        pwm0_start(1000,50); //1kHz, 50% duty cycle
        pwm1_start(1000,50); //1kHz, 50% duty cycle
        while(1)
        {
        }
    }
    

    Regards

    Amit

  • Thank you for your answer Amit,

    I put the exact same code as you uploaded above, connected one probe of my scope to PB6 and one to PB4. Only the one on PB6 provides me the square wave.
    I also tried to use another Launchpad but the problem remains the same.


    May you try to visualise your 2 pwm on a scope ?

    Regards,

    Florent

  • Hello Florent,

    My mistake. I had updated one section of the code manually but did not put it in the file after checking it.

    Replace

    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, (PWMGenPeriodGet(PWM0_BASE, PWM_OUT_2) * duty_cycle) / 100);

    with

    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, (PWMGenPeriodGet(PWM0_BASE, PWM_GEN_1) * duty_cycle) / 100);

    Full file also attached.

    #include "stdint.h"
    #include "stdbool.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/fpu.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/gpio.h"
    #include "driverlib/timer.h"
    #include "driverlib/pwm.c"
    #include "driverlib/pwm.h"
    #include "driverlib/pin_map.h"
    
    void pwm0_init()
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        GPIOPinConfigure(GPIO_PB6_M0PWM0);
        GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_6);
        PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
    }
    void pwm1_init()
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        GPIOPinConfigure(GPIO_PB4_M0PWM2);
        GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_4);
        PWMGenConfigure(PWM0_BASE, PWM_GEN_1, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
    }
    void pwm0_start(unsigned long frequence, unsigned long duty_cycle)
    {
        PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, SysCtlClockGet() / frequence);
        PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0, (PWMGenPeriodGet(PWM0_BASE, PWM_OUT_0) * duty_cycle) / 100);
        PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT, true);
        PWMGenEnable(PWM0_BASE, PWM_GEN_0);
    }
    void pwm1_start(unsigned long frequence, unsigned long duty_cycle)
    {
        PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, SysCtlClockGet() / frequence);
        PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, (PWMGenPeriodGet(PWM0_BASE, PWM_GEN_1) * duty_cycle) / 100);
        PWMOutputState(PWM0_BASE, PWM_OUT_2_BIT, true);
        PWMGenEnable(PWM0_BASE, PWM_GEN_1);
    }
    
    int main(void)
    {
        FPUEnable();
        FPULazyStackingEnable();
        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                           SYSCTL_XTAL_16MHZ);
    
        pwm0_init(); // PWM0
        pwm1_init(); // PWM1
        pwm0_start(1000,50); //1kHz, 50% duty cycle
        pwm1_start(1000,50); //1kHz, 50% duty cycle
        while(1)
        {
        }
    }
    

    Regards

    Amit

  • Hello Amit,

    Everything works perfectly now. Thank you for your help!

     

    Regards,

    Florent