cancel
Showing results for 
Search instead for 
Did you mean: 

PWM with DMA makes unwanted pulse stream

click8
Associate II

Hi,

I want to make PWM stream with various duty, so I'm testing PWM with DMA using NUCLEO-G0B1RE and HAL library.

The first image shows weird pulse train. I set DMA buffer with [duty 1] * 8 + [duty 17] * 8 + [duty 5] * 8, but oscilloscope captures eight 1s, "nine" 17s and "seven" 5s. Left pane is screen of STM32CubeIDE Debugger.

2024-07-29 165014.png

I tested while debugging - if I change DMA buffer I can see results on-the-fly.

It looks like if I set more than 11 on DMA buffer, next PWM affected. I attached a short screen recording clip, please check it.

How can I get the exact PWM trains? 

 

I also attached entire project files.

Note : I found code generation problem regarding TIM4 and DMA(https://community.st.com/t5/stm32cubeide-mcus/stm32cubeide-1-15-1-code-generation-problem/td-p/673440) so I modified HAL_TIM_PWM_MspInit() 

1 ACCEPTED SOLUTION

Accepted Solutions
dfrejek
Associate II

Yeah, makes totally sense that my suggestion didn't work since the register write will happen during the cycle.

 

Since you initially mentioned, the problem happens only when you have a longer pulse, I assume that the pulse match is you DMA trigger.

Try using UPDATE event as DMA trigger and enabling the preload function. This way, the DMA transfer will always be completed during the cycle and the value will be loaded from the preload value at the cycle end. The downside of this method is, that the waveform will always be delayed by one cycle.

View solution in original post

5 REPLIES 5
dfrejek
Associate II

Hi,

this is likely an issue with the "output preload" feature. This causes the compare value to be loaded from the shaddow register into the actual compare register on the UPDATE event.

Bit 3 OC1PE: Output compare 1 preload enable
0: Preload register on TIMx_CCR1 disabled. TIMx_CCR1 can be written at anytime, the
new value is taken in account immediately.
1: Preload register on TIMx_CCR1 enabled. Read/Write operations access the preload
register. TIMx_CCR1 preload value is loaded in the active register at each update event.

Try disabling this and check if the problem still occurs.

Cheers,

D. Frejek

click8
Associate II

Thank you dfrejek.

I tested disabling OC preload feature.

Here is the result waveform. If I disable preload, it looks like DMA updates CC register at unwanted timing. I set eight 1s, eight 17s and eight 5s. 8th and 16th PWM were corrupted. It seems preload feature is mandatory for DMA.

screen 2024-07-29 173709.png

 

dfrejek
Associate II

Yeah, makes totally sense that my suggestion didn't work since the register write will happen during the cycle.

 

Since you initially mentioned, the problem happens only when you have a longer pulse, I assume that the pulse match is you DMA trigger.

Try using UPDATE event as DMA trigger and enabling the preload function. This way, the DMA transfer will always be completed during the cycle and the value will be loaded from the preload value at the cycle end. The downside of this method is, that the waveform will always be delayed by one cycle.

> Try using UPDATE event as DMA trigger and enabling the preload function.

+1

JW

Great. You're right. Triggering DMA with TIM UPDATE event can resolve this issue.

You mentioned a downside, but in my case, there are zero duty's in front of PWM stream so delaying one cycle doesn't make problem.

click8_0-1722247844194.png

BTW, I cannot find proper API in HAL library to set DMA triggering event. I tested it with a modified HAL code. Now I'm looking for a good way to handle this.