rogerclarkmelbourne / Arduino_STM32

Arduino STM32. Hardware files to support STM32 boards, on Arduino IDE 1.8.x including LeafLabs Maple and other generic STM32F103 boards
Other
2.53k stars 1.26k forks source link

analogWriteFrequency() not implemented #937

Open Art-ut-Kia opened 5 hours ago

Art-ut-Kia commented 5 hours ago

I intended to implement fast PWM for a motor control. Unfortunately, the analogWriteFrequency() function is not implemented. Is there a workaround to change the PWM speed?

rogerclarkmelbourne commented 3 hours ago

PWM uses hardware timers

However different pins use different timers, as the STM32 has multiple hardware timers

analogWrite() calls

pwmWrite()

https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/245b97a7d59156e4f9069498d0ff77f747170762/STM32F1/cores/maple/pwm.cpp#L41

In pwmWrite() the timer device for the pin is retrieved

timer_dev *dev = PIN_MAP[pin].timer_device;

and then

timer_set_compare(dev, cc_channel, duty_cycle);

is called

So what you need to do is to call another timer control function which changes the timer.

Depending on exactly what level of control you want, you can do various things

  1. Change the 'prescaler' for the timer. This is a divider , i.e the higher the number the lower the PWM speed
  2. Change values like the reload and compare values for the timer
  3. Change both of the above

I don't know what prescaler value is used by default, you would need to look through the code, or perhaps more easily write a sketch which printed the prescaler value for each pin.

using timer_get_prescaler()

e.g.

timer_get_prescaler(PIN_MAP[pin].timer_device);

where you need to define the pin number

I can't remember the specifics of the STM32F1 or STM32F4, but I think different hardware timers may be on different peripheral clocks, so you may not simply be able to use the same prescaler number for all pins.

If the prescaler is already set to its lowest value, you'd need to change the compare and reload values etc