This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem of updating frequency in PWM signal...

Hi!
I am a beginner in programming STM32f4 and that is my biggest problem, I think...

I am working now on the project where I need do profile the velocity of servo motor (i.e. trapezoidal velocity)... So I need to control the number of pulses I have sent and periodically update the frequency of signal...

So I have a question:
Can I just change just: TIMx->ARR, PSC and CCRx registers in the PWM signal generator...? Or for example I must turn of timer first, and then update parameters...?

Thanks a lot for any hints,
best regards,

P.S
Have You any example projects of velocity profiling in C...? Or any tutorial of doing that on uC... Thanks again...

Parents
  • Thanks a lot for this very clear explanation!

    So I know now that I don't need to turn off/on timer to change its parameters. But I have a problem, and don't know if it is possible to solve. Maybe it is just a beauty of uC's and "digital world" ;-)
    When I turn on PWM with one frequency and then change the frequency by TIMx->ARR, PSC and CCRx values, the change is taking in count always with one period delay, after updating registers.
    I checked this on the oscilloscope taking these steps:

    1. turn on PWM;
    2. turn off PWM;

    3. change TIMx->ARR, PSC, CCRx values;

    4. turn on PWM

    the first pulse (period) is always generated with earlier values of TIMx ARR, PSC, CCRx (why?)

    other pulses have desired frequency (OK)

    5. turn off PWM

    I have read about shadow registers in the RM, and that the change is taking in count after Update Event (UEV)... But I am not sure I understand it properly...
    Can I generate Update Event by myself after changing TIMx registers values...?
    Or if the timer can generate pulses without this one pulse delay some other way...
    Thanks for replies!

Reply
  • Thanks a lot for this very clear explanation!

    So I know now that I don't need to turn off/on timer to change its parameters. But I have a problem, and don't know if it is possible to solve. Maybe it is just a beauty of uC's and "digital world" ;-)
    When I turn on PWM with one frequency and then change the frequency by TIMx->ARR, PSC and CCRx values, the change is taking in count always with one period delay, after updating registers.
    I checked this on the oscilloscope taking these steps:

    1. turn on PWM;
    2. turn off PWM;

    3. change TIMx->ARR, PSC, CCRx values;

    4. turn on PWM

    the first pulse (period) is always generated with earlier values of TIMx ARR, PSC, CCRx (why?)

    other pulses have desired frequency (OK)

    5. turn off PWM

    I have read about shadow registers in the RM, and that the change is taking in count after Update Event (UEV)... But I am not sure I understand it properly...
    Can I generate Update Event by myself after changing TIMx registers values...?
    Or if the timer can generate pulses without this one pulse delay some other way...
    Thanks for replies!

Children
  • At this point I think it might be helpful to understand a few things.

    1) What is the range of frequencies you are looking for on the GPIO Pin?

    2) What is the duty cycle on the GPIO Pin (how long is it Asserted compared to Deasserted). I noticed you say that you needed to count the pulses, but made no mention of duty cycle.

    3) Are you sure this is a PWM type problem? I know you asked for "better ways" to do this, but I still don't fully understand what "this" is. You said at one point that it was working "quite well". But now it seems that it was/is actually not working, much less working "quite well". A better understanding of what you actually want the output to look like on the GPIO pin would be helpful in finding the "best way" to do this. Usually finding the "best way" is not something that is overly important. You do want something that works (actually does what you need it to do) but as long as it meets the requirements, is reasonably easy to understand and can be easily modified to do something that you cannot imagine that someone would ask for (they always do), then you have a "good solution". You will know before the project is done if there was a better way to do it, but most likely there is no need to change it because it works just fine.

  • It's normal to have a one-pulse lag between reconfiguration and the change being seen on the output pin - since it isn't until the PWM has done one complete pulse period that it will latch in the new values to use for the next pulse period. And a pulse period is the combination of the time the pin is high and the time the pin is low.

    If you are generating an analog value, then you normally have so high pulse frequency that this lag doesn't matter - you have a large number of very small pulses accumulating to the intended analog output value.

    If you are controlling a motor, then the motor supports limited acceleration/deceleration. Which means that you can't make a large change in pulse frequency - so it normally doesn't matter if your source code is one pulse period ahead of what is seen on the pin.

    Note that a traditional proportional regulator always has lag because when it get close enough the error difference will become so small. That's why there exists PID regulation where you can have one extra term allowing a quicker reaction when you need large steps, and then an integrating part that will give you a perfect match at times when there are no requested changes - the integration accumulates many small errors until it becomes large enough to react to.

    So unless you are running at extremely slow pulse frequencies, you normally don't have to worry about the PWM output reacting one pulse period late compared to your configured values.

  • Ok.

    I am working on the project of driver for 5-axies manipulator. I have three servo motors and two stepper motors but the steering method is clk, dir, enable.

    I have to implement this on stm32f429 board using LCD-TFT. Already I have set Free RTOS system and menu to interface with the user - using STemWin Library.

    To know the actual position I need to control pulses I have sent: I am managing this by 2 timers, for each motor, linked by wire: one in PWM Out Mode and the other in Input Capture Mode with External CLK on this pin. (I am turning on PWM and the Input Capture TIMx->CNT has the position via TIMx_IRQHandler() function and disables Timer PWM when the pulses were sent)

    I said that this method has "quite good results" because when I only generate required amount of pulses I can be up to date with position of servo motor. I chacked this on servo driver display which represents position of encoder.

    But where this method (or my code fails), is when I am trying to implement trapezoidal velocity profiling for each motor.

    The derivative of position from Linear Segments with Parabolic Blends gave me velocity (deg/sec), which I recalculate to frequencies. (I choose to have 10% higher velocity in linear segment + two parabolic segments of: 5% * movment_time duration, each)

    1) The range of frequencies I work with is: form 1 Hz to 200kHz/300kHz. But It have to work don't need to work fast so I can manipulate higher value... And update frequency using Timer 7 each 0.0021845 sec
    The biggest problem for me are the stepper motors: max frequency of 1.8kHz and the smalest resolution (the biggest position error)...
    So i.e. when I want to have 35% of max speed, the stepper motors have 630Hz. The deriviative gave me values:
    docs.google.com/.../edit

    So the values of velocity are good, but when I turn on PWM of stepper motor, the first period is very long - 20 Hz even about 22 new updates of TIMx ARR,PSC,CCRx register values.
    After this first period, frequency in changing properly to the end of movment Time (measured by Tim7)... But there wasn't generated enough "falling edges" and my counter has counted every generated pulse but there was them too few. Because of this first not updated period of pulse I think.

    So my question was why the 22 updates of ARR, PSC and CCRx values has no effect on output signal during first 20 Hz period...?

    2) Duty cycle of PWM I just set to 50% to be sure that my servo driver detects every pulse sent.

    3) I think that could be PWM first period problem... But I am not sure because I have a little experience with uC's...
    I've read in RM about shadow registers and don't really understand if I updated the regisrer values to shadow or active register...

    If You have other questions, I will answer as good as I can...

    Best regards,

    Marcin