PWM, dynamically changing period, duty cycle (directly or via DMA)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-02-21 3:32 PM
Below question relates to STM32F0 and STM32F1 series MCU's.
From the documentation (HAL), I have been unable to determine, whether or not on-the-fly changes are supported to the PWM period (TIM_TimeBaseInitTypeDef.TIM_Prescaler) and/or duty cycle (directly via CCR1 or via DMA: DMA_InitTypeDef.DMA_Memory0BaseAddr).
Other than whether or not on-the-fly changes (to a running PWM-configured timer) are supported, I am also interested in knowing when on-the-fly changes takes effect (immediate, at next timer cycle, ...)?
- When changing the address of a (circular) DMA memory buffer containing PWM duty cycle values, will it take effect immediately, or when the current (memory) cycle has been completed. I would prefer to be able to work with a double buffered DMA design, where the DMA buffer takes effect when the current cycle completes. Alternatively, I could rely on an interrupt when the cycle completes, and update the DMA buffer then.
- When changing the PWM duty cycle directly via CCR1, will this change take effect immediately, or at the end of a timer cycle.
- When changing the PWM period/frequency (via TIM_TimeBaseInitTypeDef.TIM_Prescaler) on a running PWM configured timer, will this change take effect immediately, or at the end of a cycle.
Any help and/or references to existing documentation or examples will be greatly appreciated.
/Morten
Solved! Go to Solution.
- Labels:
-
DMA
-
STM32F0 Series
-
STM32F1 Series
-
TIM
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-02-22 7:15 AM
The prescaler PSC always uses the shadow register, changes take effect after the next update event (timer overflow or TIM_EGR_UG).
The period ARR uses the shadow register when TIM_CR1_ARPE = 1, otherwise changes take effect immediately.
The compare register CCRx uses the shadow only when OCxPE = 1.
Note that though the period will be changed when you change PSC, the duty cycle will be determined by the CCRx/ARR ratio.
DMA address can't be changed whlie running, but you can request a DMA interrupt when half of the buffer is processed, so you'd always know which half of the buffer is currently active. You can also read the number of data words remaining in the buffer from the DMA transfer counter,
Read AN4776 Application note General-purpose timer cookbook for STM32 microcontrollers if you haven't read it before.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-02-21 4:04 PM
1
Dma address cant be changed while active. It takes effect immediately the next time you start the dma. You could use double buffer mode.
2
The behavior can be either based on the value of the OC1PE bit. It can either be immediately or updated on the update event. Take a look at this field definition in the reference manual.
With DMA, the behavior is the same as if you change it manually, although dma can be delayed if you have a lot going on.
3
For the prescaler, I believe this is updated immediately. I dont believe it uses a shadow register.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-02-21 4:45 PM
Thanks for your advise. I conclude, that ...
- Changing the DMA address requires a disable/enable DMA cycle?
- Double buffering would require using the Shadow/Preload register?
- In that case, I would choose to update the prescaler when the UpdateEvent interrupt occurs, which would be the most predictable transition of PWM-period.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-02-21 5:35 PM
3 For the most predictability, I would leave the prescaler alone and only adjust the CCMR register to adjust the duty cycle. This may require avoiding the HAL drivers and working with registers directly. I’m not sure what HAL offers in this capacity.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-02-21 5:37 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-02-22 7:15 AM
The prescaler PSC always uses the shadow register, changes take effect after the next update event (timer overflow or TIM_EGR_UG).
The period ARR uses the shadow register when TIM_CR1_ARPE = 1, otherwise changes take effect immediately.
The compare register CCRx uses the shadow only when OCxPE = 1.
Note that though the period will be changed when you change PSC, the duty cycle will be determined by the CCRx/ARR ratio.
DMA address can't be changed whlie running, but you can request a DMA interrupt when half of the buffer is processed, so you'd always know which half of the buffer is currently active. You can also read the number of data words remaining in the buffer from the DMA transfer counter,
Read AN4776 Application note General-purpose timer cookbook for STM32 microcontrollers if you haven't read it before.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-07-11 7:12 PM
A belated "thank you"​ for your comprehensive and accurate answer. Much appreciated!
