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.

TM4C1294NCPDT: PWM signal stays HIGH

Part Number: TM4C1294NCPDT


Hello,

I try to generate a PWM signal using of the PWMs modules. Basically, the steps involved in configuring the PWM are simple but I end up with a signal which stays permanently on HIGH. Please find below my initialization steps:

            ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |

            SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |

            SYSCTL_CFG_VCO_480), 120000000);

            uint32_t period = ui32SysClock / 250; /*250 Hz*/

            SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
            SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

            HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0x4C4F434B;

            GPIOPinConfigure(GPIO_PF0_M0PWM0);
            ROM_PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_1);
            GPIOPinTypePWM(PWM0_BASE, GPIO_PIN_0);
            PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
            PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, period);
            PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0_BIT, (period * 10) / 100); /*10%*/


            PWMIntEnable(PWM0_BASE, PWM_INT_GEN_0);
            PWMGenIntRegister(PWM0_BASE, PWM_GEN_0, pwmIsrCh0);
            PWMGenIntTrigEnable(PWM0_BASE, PWM_GEN_0, PWM_INT_CNT_LOAD);
            IntEnable(PWM0_BASE);
            PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT, true);
            PWMGenEnable(PWM0_BASE, PWM_GEN_0);

static void pwmIsrCh0(void)
{
    uint32_t counter_value = (10 * period) / 100 ;

    PWMGenIntClear(PWM0_BASE, PWM_GEN_0, PWM_INT_CNT_LOAD);

    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0_BIT, counter_value);
}

The ISR is successfully called.

  • The first argument of the function GPIOPinTypePWM is the base address of the GPIO port, not the base address of the PWM. Line10 of your code above should look like:

        GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_0);
    

  • Hello Bob,

    Yes, you are right.
    It was just a typo mistake when I copied from code.

    The real configuration is like you presented.
  • The PWM load register which generates the period is only 16 bits. The value you loaded is too large (120,000,000 / 250 = 480,000 or 0x75300). Only the last 16 bits are loaded into the register, 0x5300 or 21,248. The compare value you used for the pulse width 48,000 is less than 16-bits, but since it is greater than the load value, the counter never generates a match condition so the PWM output stays high.
  • I fixed two other copy errors. Here is the working code.

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_gpio.h"
    #include "inc/hw_ints.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pwm.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    
    //*****************************************************************************
    //
    // Main 'C' Language entry point.
    //
    //*****************************************************************************
    static void pwmIsrCh0(void);
    
    uint32_t period;
    
    int
    main(void)
    {
        uint32_t ui32SysClock;
    
        //
        // Run from the PLL at 120 MHz.
        //
        ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                           SYSCTL_OSC_MAIN |
                                           SYSCTL_USE_PLL |
                                           SYSCTL_CFG_VCO_480), 120000000);
    
        period = ui32SysClock / 2500; /*2.5 KHz*/
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
        GPIOPinConfigure(GPIO_PF0_M0PWM0);
        PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_1);
        GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_0);
        PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
        PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, period);
        PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0, (period * 10) / 100); /*10%*/
        PWMIntEnable(PWM0_BASE, PWM_INT_GEN_0);
        PWMGenIntRegister(PWM0_BASE, PWM_GEN_0, pwmIsrCh0);
        PWMGenIntTrigEnable(PWM0_BASE, PWM_GEN_0, PWM_INT_CNT_LOAD);
        IntEnable(INT_PWM0_0);
        PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT, true);
        PWMGenEnable(PWM0_BASE, PWM_GEN_0);
    
        while(true)
        {
        }
    }
    
    static void pwmIsrCh0(void)
    {
        uint32_t counter_value = (10 * period) / 100 ;
        PWMGenIntClear(PWM0_BASE, PWM_GEN_0, PWM_INT_CNT_LOAD);
        PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0_BIT, counter_value);
    }
    

  • Hello Bob,

    Thank you for spending time to create this example for me. 

    Indeed, I found the mistake. Instead of writing "PWM_OUT_0" I wrote "PWM_OUT_0_BIT".

    Now it works as expected. 

    All the best !