Skip to main content
Caraffa
Associate II
July 4, 2021
Question

How to use DMA to change PWM frequency?

  • July 4, 2021
  • 5 replies
  • 7342 views

Hi! I know overall idea of DMA and i need to use it but i have no idea how to do it.

I found one post with same question but i didn't found any helpful info for me. I'm not advanced in case of using registers. I used them to directly change CCR and ARR sometimes, so I need a direct answer.

Edit: It is worth mentioning that I use CubeIDE

Thanks for help

This topic has been closed for replies.

5 replies

waclawek.jan
Super User
July 4, 2021

Make TIMx_ARR to be the target of the DMA transfer on the peripheral side. Make sure ARR preload is switched on.

JW

Caraffa
CaraffaAuthor
Associate II
July 4, 2021

Could you explain it further, especially first part? How i can make TIMx_ARR target of the DMA transfer? ​

waclawek.jan
Super User
July 4, 2021

You write it in the Peripheral address register of DMA channel/stream, while the channel/stream is set to transfer memory-to-peripheral.

Read the DMA chapter first. You may also want to read the Timer cookbook AN4776. And next time start with stating which STM32 are you using.

JW

Caraffa
CaraffaAuthor
Associate II
July 5, 2021

I'm using stm32f407g

Javier1
Principal
July 5, 2021

I use here a DMA(triggered with a timer)---->PWM(timer) to create a neopixel LED driver, maybe you can fish something out, specially the DMA+PWMtest.

The mcu shouldnt matter as long as you have DMA and TIM available to use.

I tested this with stm32f103 and stm32f7

hit me up in https://www.linkedin.com/in/javiermuñoz/
Caraffa
CaraffaAuthor
Associate II
July 5, 2021

You use HAL_TIM_PWM_Start_DMA function but if i understand it correctly, it can access only TIMx_CCRx registry but i need TIMx_ARR

Javier1
Principal
July 5, 2021

what if you try this inside HAL_TIM_PWM_Start_DMA()

//instead of this:
 if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length) != HAL_OK)
 {
 
//do this :
 
 if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->ARR, Length) != HAL_OK)
 {

hit me up in https://www.linkedin.com/in/javiermuñoz/
Caraffa
CaraffaAuthor
Associate II
July 5, 2021

It turned out that i don't need DMA at all. I thought I needed because weird things were happening when i was updating ARR directly with TIMx->ARR = y. It turned out that I was doing that when counter was waaay beyond my y value. I just added line to reset CNT value and everything works like a charm.

waclawek.jan
Super User
July 5, 2021

Look at my first reply:

> Make sure ARR preload is switched on.

Read the TIM chapter. ARR preload is switched on by setting TIMx_CR1.ARPE.

JW