cancel
Showing results for 
Search instead for 
Did you mean: 

PWM Generaion with udpate of the Period using DMA (STM32F411)

Semiory
Associate II

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:

Semiory_0-1768983396786.png

Global interrupts are also active:

Semiory_3-1768984063378.png

 

Then the DMA will be configured to update the ARR register:

Semiory_1-1768983502826.png

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:

Semiory_2-1768983802474.png

The Output updates 3 times (without to change the frequency (period)) and then PWM Stops...

Could someone explain me, what I'm doing wrong?




1 REPLY 1
waclawek.jan
Super User

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?