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: Change PWM frequency on the fly

Part Number: EK-TM4C1294XL

Hello

I'm using the TM4C1294xl to control three stepper motors. As usual a PWM signal is needed to make a moving step. For accerlation / deaccerlation it is necessary to increase / decrease the frequency.

 I have written down following code for testing.

int main(void){

	//activate ports
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);


	//switch to PWM mode
	GPIOPinConfigure(GPIO_PF1_M0PWM1);
	GPIOPinConfigure(GPIO_PG1_M0PWM5);
	GPIOPinConfigure(GPIO_PK4_M0PWM6);

	GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1);
	GPIOPinTypePWM(GPIO_PORTG_BASE, GPIO_PIN_1);
	GPIOPinTypePWM(GPIO_PORTK_BASE, GPIO_PIN_4);


	//switch on generator
	SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
	PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC); //PortF (generator0)
	PWMGenConfigure(PWM0_BASE, PWM_GEN_2, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC); //PortG (generato2)
        PWMGenConfigure(PWM0_BASE, PWM_GEN_3, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC); //PortK (generator3)


	//set specefic pulsewidth / frequency
	PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, 100); //PortF
	PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1, 50);
	PWMGenEnable(PWM0_BASE, PWM_GEN_0);

	PWMGenPeriodSet(PWM0_BASE, PWM_GEN_2, 400); //PortG
	PWMPulseWidthSet(PWM0_BASE, PWM_OUT_5, 300);
	PWMGenEnable(PWM0_BASE, PWM_GEN_2);

	PWMGenPeriodSet(PWM0_BASE, PWM_GEN_3, 400); //PortK
	PWMPulseWidthSet(PWM0_BASE, PWM_OUT_6, 100);
	PWMGenEnable(PWM0_BASE, PWM_GEN_3);

	PWMOutputState(PWM0_BASE, PWM_OUT_1_BIT | PWM_OUT_5_BIT | PWM_OUT_6_BIT , true);
}

My question in now: Is it possible to change the frequency and duty of each signal on the fly? I've already tried out using a for loop with the single commands inserted like

for(i=1;i<400;i++){

PWMGenPeriodSet(PWM0_BASE, PWM_GEN_3, i); 
}

but no success. The only thing that is measurable is that the PWM output becomes dodgy. It simpy switches on and off providing a PWM signal in between.

Does anyone knows better / has an advice?

Thanks for your responce!

Greetings

  • It is believed that you - in general - are, 'On the right track' - yet your execution requires further (and perhaps deeper) thought.

    Starting your 'PWM Period' - as your code reveals - with the value '1' proves unwise.     Is it fair - and did you consider the fact - that you are imposing a 400:1 frequency swing - upon the MCU's PWM Generator?     Rather clearly - that's excessive - don't you agree?

    Worse - your SO Brief coding (courtesy that 'for loop')  reveals NO/ZERO Delay ...  thus "Machine Gunning the PWM Generator" - with incessant updates!    (If such (NO/ZERO) 'Delay' - proves 'not the case' - then your code presentation here - has badly failed.)

    How often do you estimate that you require the PWM frequency update?     Such is silent w/in your post.    And - that 'frequency update' requirement - is 'just one side' - of a (likely) Two-Headed Coin!   (Say what?)

    Should you not review the Source Code - w/in PWMGenPeriod Set() - so that you gain (some) understanding of that function's, 'Execution Time?'      What happens when you (pardon) 'bombard that function' with updates - faster than it can execute (a single) frequency update?     Might that - pretty much - identify your issue?

    There's another - more subtle impact - which involves your, "Updating the PWM Generator's Frequency - but ONLY - at an Optimal Time."     Your further read/review of the MCU Manual - should reveal - 'where & how' that can be achieved...    (the subtlety resides in the creation of a "runt" or excessively wide pulse - when the update is called at a, "Less than Ideal" point in time.)     It is my belief - that this proves of (usually) 'Limited Consequence' and impacts, 'One or Two PWM Pulses' only.     (which proves FAR - (very far) - from your case!    

    Instead - 'Facts in Evidence' reveal, 'Machine-Gun like Frequency Updates' - for NO GOOD REASON - are your Issue's Cause!

  • Hi Marvin,
    I don't think you want to change the duty cycle or the period while the counter is counting. I will suggest that you change duty cycles or periods synchronized to a PWM edge by using an interrupt. What you are doing right now has an immediate effect to reload the PWM counter which can produce incorrect PWM pulses. You will also want to call PWMSyncUpdate() to queue up updates to the period or duty cycle to be applied the next time the corresponding counter becomes zero.
  • Hello Charles,

    It is assumed you've recovered from your CA 'hike.'     Speaking of 'recovery' - our posts crossed - it is believed that in 'combination' - we've well guided (even resolved) poster's issue.

    Indeed you're correct - yet is not the issue (beyond) 'Just the update - while the counter is counting?'

    I believe poster's, "Machine Gun Update Rate" proves (pardon) bit higher up - the 'suspect list.'

    As you note - should 'Runt AND Bloat-Free' PWM pulses be sought - (then) one can, "Alter the Frequency" at precise, "Points in Time."     (although KISS dictates that the poster's DOMINANT ISSUE - be FIRST RESOLVED!)      (it is noted that 'KISS' received "Kiss of Death" here - far earlier than the departed (and BADLY MISSED ... despite the (now) swollen lips) LIKE!

  • Hi cb1,
    Thanks for your advice to the poster. I did notice the continuous updates to the period in a while loop. Most likely the PWM output will be flat line since the counter never had a chance to count toward its compare match value.
  • Indeed Charles - thus, 'Even allowing for the precise moment to Update' - this poster is unlikely to, 'Achieve his goal!'     Slowing the update rate - as directed - appears a sound solution.

    I never saw any 'while loop' - he added in a 'for loop' (at the tail end of his post) which provided the 'PWM Bombardment!'

    This rises to a (possible) 'Point of Value' to (serious) client-users and/or specifiers (moi)  - here.    Does your API deploy any effective 'strategy' - when a function is repeatedly called - and such 'calls'  arrive - prior to the function's ability to 'complete its execution?'     What do you believe - most likely - to then occur?

    I'd really NOT thought of that before - perhaps 'Here/Now" - proves a (proper) 'Time/Place' - to tap your,  'Insider Knowledge!'

  • Sorry, I meant the for loop, not the while loop in his code snippet.
  • Thank you - good that - Doc's swear that my 'bout w/hallucinations' is (almost) ... (maybe) over.

    Had you missed the request for explanation when (repeated) function calling rate - is faster than function's execution?     That's of (some) importance - is it not?     And may prove the ENTIRE (at least DOMINANT) issue - w/in this thread!

    Slept 3 hours last night - readying for client site inspection.    (how do you make a 'back-room' - behind (another) 'back-room' (reasonably) presentable?    Ans: Uber Smart - AND great looking (mostly gurl) staff... (fortunately - that client would NEVER look here ... or those are - among the newest, "Famous LAST WORDS!')      (others can access cb1 - you know...)

  • Hi cb1,
    You raise about the function calling rate being faster than the function's execution time is of valid concern. The for loop including the call to PWMGenPeriodSet() takes about 17 instructions to complete. The 17 instructions may take 20+ cycles since some are LDR and STR instructions to the PWM peripheral. Unless the compare value is within 20 counts from the period count, you will most likely see flat line on the output. For example, if the period with i=200 in the for loop then you may only see PWM if the compare value is with 180-199 to have any chance to see some outputs. In any case, the period/duty should only be changed with respect to the completion of the next edge.
  • here is a recent thread where the OP, like you, wanted to change PWM "on the fly": 

    as you can see, lots of good suggestions there that hopefully can help you as well.

  • Danny F said:
    lots of  good suggestions there that hopefully can help you as well.

    Yet - if  NONE w/in that past thread - specifically address the, "Machine-Gunning of the PWM Period's Update" (which is believed to have arrived NEW - to this (present) poster's thread) - how might they (really) help?