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: blink led automatically

Part Number: TM4C1294NCPDT

Tool/software:

Hi,

I have PWM module on my Tiva. 

I use the code bellow (according to the PWM invert example) and its working.

But I would like to generate the PWM module so that I won't need the while(1) loop, I want that all the PWM system will work automatically with fixed duty cycle and fixed frequency, without me handling and performing the SysCtlDelay by myself.. 

How I do that?

I attached my code.

Thanks,

Tzipi

PwmTiva.txt
void PortFunctionInit(void)
{
...
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
    //
    // Enable pin PG1 for PWM0 M0PWM5
    //
    ROM_GPIOPinConfigure(GPIO_PG1_M0PWM5);
    ROM_GPIOPinTypePWM(GPIO_PORTG_BASE, GPIO_PIN_1);

    //
    // Enable pin PG0 for PWM0 M0PWM4
    //
    ROM_GPIOPinConfigure(GPIO_PG0_M0PWM4);
    ROM_GPIOPinTypePWM(GPIO_PORTG_BASE, GPIO_PIN_0);
...
}


int PwmInit(uint32_t ui32SysClock)
{
    uint32_t ui32PWMClockRate;

    //
    // Set the PWM clock to be SysClk / 8.
    //
    ROM_PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_8);
    //
    // Use a local variable to store the PWM clock rate which will be
    // 120 MHz / 8 = 15 MHz. This variable will be used to set the
    // PWM generator period.
    //
    ui32PWMClockRate = ui32SysClock / 8;

    //
    // Configure PWM2 to count up/down without synchronization.
    //
    ROM_PWMGenConfigure(PWM0_BASE, PWM_GEN_1,
                        PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);

    //
    // Set the PWM period to 250Hz.  To calculate the appropriate parameter
    // use the following equation: N = (1 / f) * PWMClk.  Where N is the
    // function parameter, f is the desired frequency, and PWMClk is the
    // PWM clock frequency based on the system clock.
    //
    ROM_PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, (ui32PWMClockRate / 250));

    //
    // Set PWM2 to a duty cycle of 25%.  You set the duty cycle as a function
    // of the period.  Since the period was set above, you can use the
    // PWMGenPeriodGet() function.  For this example the PWM will be high for
    // 25% of the time or (PWM Period / 4).
    //
    ROM_PWMPulseWidthSet(PWM0_BASE, PWM_OUT_4,
                         ROM_PWMGenPeriodGet(PWM0_BASE, PWM_GEN_1) / 4);

    ROM_PWMPulseWidthSet(PWM0_BASE, PWM_OUT_5,
                         ROM_PWMGenPeriodGet(PWM0_BASE, PWM_GEN_1));

    //
    // Enable PWM Out Bit 2 (PF2) output signal.  PWM_OUT_4_BIT
    //
    ROM_PWMOutputState(PWM0_BASE, (PWM_OUT_4_BIT | PWM_OUT_5_BIT), true);

    //
    // Enable the PWM generator block.
    //
    ROM_PWMGenEnable(PWM0_BASE, PWM_GEN_1);


    return 0;
}


int PwmBlinkLedsLoop(uint32_t ui32SysClock, int times)
{
   //
   // Loop forever while the PWM signals are generated.
   //
   while(times>0)
   {
       //
       // Print out that the level of PWM is normal.
       //
       printf("PWM Output: Normal\n");

       //
       // This function provides a means of generating a constant length
       // delay.  The function delay (in cycles) = 3 * parameter.  Delay
       // 2 seconds arbitrarily.
       //
       SysCtlDelay((ui32SysClock) / 3);

       //
       // Invert PWM2 signal.   PWM4
       //
       ROM_PWMOutputInvert(PWM0_BASE, PWM_OUT_4_BIT, true);
       ROM_PWMOutputInvert(PWM0_BASE, PWM_OUT_5_BIT, false);

       //
       // Print out that the level of PWM is inverted.
       //
       printf("PWM Output: Inverted\n");

       //
       // This function provides a means of generating a constant length
       // delay.  The function delay (in cycles) = 3 * parameter.  Delay
       // 2 seconds arbitrarily.
       //
       SysCtlDelay((ui32SysClock) / 3);

       //
       // Switch PWM2 signal back to regular operation.   PWM4
       //

       ROM_PWMOutputInvert(PWM0_BASE, PWM_OUT_4_BIT, false);
       ROM_PWMOutputInvert(PWM0_BASE, PWM_OUT_5_BIT, true);

       times--;
   }

   ROM_PWMOutputInvert(PWM0_BASE, PWM_OUT_4_BIT | PWM_OUT_5_BIT, false);


   return 0;
}


  • Hi,

    But I would like to generate the PWM module so that I won't need the while(1) loop, I want that all the PWM system will work automatically with fixed duty cycle and fixed frequency,

      The TivaWare pwm_invert is doing pretty much what you want. It simply set up the PWM period and duty. The only thing it does in the while loop is to invert the polarity. All you need is to remove everything in the while(1) and you will see a constant 250Hz PWM with 25% duty cycle. 

  • Hi,

    I did just that - and the led turn to on, but does not blink... maybe it should be different Hz ? or different duty cycle?

    Thanks!

    Tzipi

  • Hi

    and the led turn to on, but does not blink

    The example generates a PWM at 250Hz. Do you think a human eye can see the LED blink at this rate? Why don't you try the below example that blinks the LED using PWM_0 on PF0. To visually see the LED blink you would need to slow down the period. 

    int
    main(void)
    {
        uint32_t ui32PWMClockRate;
    
    
        g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                                 SYSCTL_OSC_MAIN |
                                                 SYSCTL_USE_OSC
                                                 ), 25000000);
    
        //
        // Initialize the UART.
        //
        ConfigureUART();
    
    
    
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    
    
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    
    
        MAP_GPIOPinConfigure(GPIO_PF0_M0PWM0);
        MAP_GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_0);
    
    
        MAP_PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_64);
    
        ui32PWMClockRate = g_ui32SysClock / 64;
    
    
        MAP_PWMGenConfigure(PWM0_BASE, PWM_GEN_0,
                            PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
    
    
        MAP_PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, (ui32PWMClockRate / 8));
    
        MAP_PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0,
                             MAP_PWMGenPeriodGet(PWM0_BASE, PWM_GEN_0) / 2);
    
    
        MAP_PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT, true);
    
    
        MAP_PWMGenEnable(PWM0_BASE, PWM_GEN_0);
    
    
        while(1)
        {
    
        }
    }
    

  • Hi,

    I did exactly what you wrote here in the example, just with PEM_1 on PG4, and still - I see the led turn to on and that's it... it doesn't blink... 

    Do you have any idea why?

    Thanks,

    Tzipi

  • Hi,

      I'm currently on vacation for the entire week. I will reply your question when I have time later today. Please expect delayed response.

  • Hi,

      Did you try my code as is on a LaunchPad for PF0? I could see the LED blink on the LaunchPad. 

      Why don't you use a scope and look at your PG4? What does it show?

  • I was able to get the LED to blink! The problem was with my setup - I use PWM4 so I had to use PWN_GEN_2 (i had mistake in my code above - i used PWM_GEN_1 instead).

    In any case, if I want the LED to blink every second and not at high speed, how should I set the period and the pulse width? 

    i set the clock to be:

    g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
    SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480  
    ), 120000000);

    And rest of my code is as shown in your example:

    MAP_PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_64);

    ui32PWMClockRate = g_ui32SysClock / 64;


    MAP_PWMGenConfigure(PWM0_BASE, PWM_GEN_2,
    PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);


    MAP_PWMGenPeriodSet(PWM0_BASE, PWM_GEN_2, (ui32PWMClockRate / 8));

    MAP_PWMPulseWidthSet(PWM0_BASE, PWM_OUT_4,
    MAP_PWMGenPeriodGet(PWM0_BASE, PWM_GEN_2) / 2);


    MAP_PWMOutputState(PWM0_BASE, PWM_OUT_4_BIT, true);


    MAP_PWMGenEnable(PWM0_BASE, PWM_GEN_2);

    Thanks!!!

    Tzipi

  • Hi Charles

     if I want the LED to blink every second and not at high speed, how should I set the period and the pulse width? 

    my code is above.

    Thanks!

    Tzipi