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.

EK-TM4C1294XL: How can I change PWM frequency?

Part Number: EK-TM4C1294XL

Hi, So I am using the following code to generate a PWM signal, I eventually want it to working in this manner, I want it to be producing a certain frequency and then I would get an interrupt that would have me switch to a different frequency. For now, I haven't set up the interupt but tried to use a delay to mimic the intended operation. So I basically have it producing a certain frequency, delay for period of time, then switch the frequency after the delay. However, I am unable to do this, I end up in the Fault ISR loop, whenever I try to make this change.

I have tried using PWMdisable and setting PWMOutputState to false before changing and then re-configuring it. I also tried just changing PWMGenPeriodSet and PWMGenWidthSet only without calling the full function again but that also failed.

Any help or ideas would be appreciated.

void
configurePWM(int test)
{

    uint32_t Ticks;
    Ticks = test; //Number_Ticks_Freq();

    //PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT | PWM_OUT_1_BIT, false);
    //PWMGenDisable(PWM0_BASE, PWM_GEN_0);


    //
    // Enable the GPIO Peripheral used by PWM (PF0, and eventually PF1)
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    //
    // Enable PWM0
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);

    //
    //Dividing the clock for PWM use - Will use one for now
    //
    SysCtlPWMClockSet(SYSCTL_PWMDIV_1);

    //
    //Unlocking the pins
    //
    HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
    HWREG(GPIO_PORTF_BASE + GPIO_O_CR) = 0x01;

    //
    // Configure GPIO pin for PWM
    //
    GPIOPinConfigure(GPIO_PF0_M0PWM0);
    GPIOPinConfigure(GPIO_PF1_M0PWM1);

    GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Configure PWM
    //
    PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);

    //
    //Setting PWM Period
    //
    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, ceil(Ticks));

    //
    //Setting duty cycle
    //
    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0 , ceil(Ticks/2));
    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1 , ceil(Ticks/2));

    //
    // Enable PWM
    //
    PWMGenEnable(PWM0_BASE, PWM_GEN_0);
    PWMOutputInvert(PWM0_BASE, PWM_OUT_1_BIT, true);
    PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT | PWM_OUT_1_BIT, true);

}

int
main(void)
{
    g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                                 SYSCTL_OSC_MAIN |
                                                 SYSCTL_USE_PLL |
                                                 SYSCTL_CFG_VCO_480), 120000000);


    configurePWM(1000);
    //configureUART();
    //IntMasterEnable(); // Enable the processor to respond to interrupts.
    //Induction_Pulse();
    SysCtlDelay(40000000*10); //40000000 = 120MHz/3 = 1 sec so this should be ten seconds - read in previous forum that thats how to get close to one sec delay 
    configurePWM(500);

//    SysCtlDelay(400000);


    //TimerEnable(TIMER0_BASE, TIMER_BOTH);

    while(1)
    {

    }
}

  • Try single stepping through your code and determine exactly what line puts you in a fault. I assume the problem is calling SysCtlPeripheralEnable() on a peripheral that is already enabled.

    It is good practice to put while(!SysCtlPeripheralReady()); after such initial enables.
  • Using breakpoints I found that a PWM is only generated after the second calling of the configurePWM() function and then I'm taken to the fault ISR Loop
  • I was posting the breakpoints message while you posted this. I added in that while loop and it works now.

    Thank you!
  • One last question for you, why do I have to recall the entire function? I am assuming I have to because when I just change period and width, it still doesn't work.
  • Your welcome. Sometimes the act of writing down problems inspires finding the solution.
  • I do not believe you need to call the entire function again. PWMPulseWidthSet() and PWMGenPeriodSet() should change the frequency. Does this work?
  • Completely agree w/poster Peter's assessment.    There is NO NEED to "Recall the PWM Set-Up/Config" - if  your sole desire - is to alter the PWM Frequency and/or Duty Cycle.   

    You should note that there are "special techniques" which enable your alteration of duty cycle - while AVOIDING the production of a 'runt' or otherwise 'deformed'   PWM Pulse!

    It is suspected that - once again - the insertion of a "Peripheral Ready" and/or a "Delay" - would achieve your objective.    Would it not prove MORE USEFUL for you to present your UPDATED CODE.   (Clearly revealing your REDUCED Duty Cycle Update Code.    Forced guessing - by your Helper Crüe - proves minimally efficient...)

    My firm - near continually - commands "Cycle by Cycle" Current Loop Control - achieved via Duty Cycle Variation (Not Frequency) and the "Duty Cycle's FUNCTION CALL ... ALONE" is  "all that is required."

    You have employed a variable w/in that function - and I'd replace that w/'Hard Coded - SAFE VALUE'  to eliminate that as a 'potential issue.'      Adding those variables - as KISS directs - should occur ONLY AFTER the Program has proven successful!