cancel
Showing results for 
Search instead for 
Did you mean: 

Changing of PWM duty cycle in an efficient manner....

antoniocorregedor
Associate II
Posted on August 23, 2011 at 21:58

Hi all,

I am new to programming with the STM32 range and am currently experimenting on the Discovery Board.  I have been able to get the basics going such as reading inputs, setting outputs, measuring an ADC on a pin and setting a PWM wave output on a pin. 

I am now in the process of experimenting further with the PWM wave parameters such as changing the duty cycle of the PWM wave depending on the voltage that I read on the AD pin.  The current procedure I follow (after setting all the other relevant information) is that I change the value of TIM_OCInitStructure.TIM_Pulse to get the respective duty cycle that I desire and then I call TIM_OC4Init(TIM3, &TIM_OCInitStructure) to get my new duty cycle. 

The above seems to work but if I get stuck in a certain case and call TIM_OC4Init(TIM3, &TIM_OCInitStructure) repeatidly I have noticed that the PWM wave output on the pin becomes very noisy.  Does anyone have an explanation for this?  Is there a better way of setting the duty cycle for my application?  I have noticed that if I include a delay that the noisy effect dissapears but a delay is not appropriate in my system as it is a real time system; so I need to find an alternative solution.  My other feeling on the matter is that when I call TIM_OC4Init(TIM3, &TIM_OCInitStructure); that the PWM output on the pin is turned off, the micro then updates the respective timers with the new duty cycle and then outputs the PWM on the pin, I suspect that this on and off process is what causes the PWM signal to be noisy.  However, I still have not figured it out and would greatly appreciate it if someone here could help me.  Thanks in advance.

Kind Regards,

  Tony

#pwm #current-limiter #awd #stm32-discovery-kit #pwm
6 REPLIES 6
donald2
Associate II
Posted on August 24, 2011 at 13:39

Your expectation is correct.  You don't re-initialize and restart the timer to change the PWM.  You just write the updated width to the TIMx_CCRy register.

If you write the code correctly, it ends up as a single write instruction.  No locking or pipeline delays involved.

 

antoniocorregedor
Associate II
Posted on August 24, 2011 at 20:41

Donald,

Thank you for your quick reply; I will attempt a re-write of the code, I am however now busy with other things but as soon as I have a chance I will make the changes and let you know the result.

I am sure however that what you have suggested will work as it makes sense...

Kind Regards,

  Tony

Posted on August 25, 2011 at 00:04

One of the STM32 PWM examples uses DMA to program the width register periodically with another timer, permitting a sequenced modulation.

As Donald indicated changing the timer setting is a matter of writing a single register. Another consideration is when in the cycle you want the change to occur.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
antoniocorregedor
Associate II
Posted on August 26, 2011 at 08:23

As per Donald's suggestion I just changed the CCR value in the relevant timer register and this did the trick.  In my case, the code used to change the duty cycle is 'TIM3 -> CCR4 = {required value}'

Clive, thanks for pointing me in the direction of that example it will be nice to see a different method for changing the duty cycle.  With respect to when in the cycle the change takes place; is it right to say that with the current method I am using the duty cycle gets changed at the end of the generation of the wave?

Posted on May 20, 2013 at 11:27

Hello Clive!

I would like more precision about what you've bring to the post : ''Another consideration is when in the cycle you want the change to occur''

Is it possible to change the PWM duty cycle ''on the fly'' (immediately), not at the end of the cycle?

My set-up : 

I do an open loop voltage regulation in a coil. I have a fixed PWM duty cycle depending on the voltage input of my system. I want to do a current limitation using AWD, as soon as the current is above a limit, I want to stop or reduce the PWM duty cycle until the current goes below the limit. Normally, due to the coil's self, the current will be osciallate smoothly around the limit.

Hope you'll can help me.

Thanks.

Chris.

Posted on May 20, 2013 at 15:54

You'll want to look at the ARPE bit in TIMx_CR1, with ARPE=0 the value for ARR is not shadowed. Also TIMx_EGR may be used to generate an update event, causing the preload values to be latched into the actual registers.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..