2026-01-21 12:37 AM
Hi, I tried to find a solution in the forum, but unfortunately without success.
The problem is as follows: I need to generate a PWM signal that changes the period (not the duty cycle) with each iteration. (MCU: STM32F411)
I'm setting up the timer to use a PWM output on channel 1:
Global interrupts are also active:
Then the DMA will be configured to update the ARR register:
In the code the DMA will be activated as following:
for (int i = 0; i < 32; i++)
{
u32FreqUpdate[i] = 2000 + i*100;
}
// Activate PWM channel 1:
TIM_CCxChannelCmd(htim4.Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
// Activate PWM output:
__HAL_TIM_MOE_ENABLE(&htim4);
// Activate ARR Update:
HAL_TIM_Base_Start_DMA(&htim4, u32FreqUpdate, sizeof(u32FreqUpdate)/sizeof(uint32_t));
As a result:
The Output updates 3 times (without to change the frequency (period)) and then PWM Stops...
Could someone explain me, what I'm doing wrong?
2026-01-21 2:15 AM - edited 2026-01-21 2:16 AM
The way to debug this would be, as usually, reading out and checking the TIM and DMA registers content.
But let me guess.
u32FreqUpdate, that sounds as an array of 32-bit words; yet you've set the DMA to transfer 16-bit halfwords.
As the the first word in that array is 2000, its upper halfword is 0; DMA transfers that 0 into ARR which stops the timer. The 3 "successful" periods are due to ARR being preloaded (i.e. the first two periods are given by the initial setup) and the one nonzero halfword being transferred.
JW
PS. is u32FreqUpdate defined as a global array?