Skip to main content
JohnsAby
Associate III
March 28, 2022
Question

I want to generate a PWM signal using DMA TIMER, in which the duty cylce should change in very frequently. Till 10 times the Duty Cycle changes with out any issues after which when I increase the array size the waveform is getting not correct. Kindly

  • March 28, 2022
  • 2 replies
  • 901 views

DMA config as below

 hdma_tim.Instance = TIMx_CC1_DMA_INST;
 
 hdma_tim.Init.Channel = DMA_CHANNEL_6;
 
 hdma_tim.Init.Direction = DMA_MEMORY_TO_PERIPH;
 
 hdma_tim.Init.PeriphInc = DMA_PINC_DISABLE;
 
 hdma_tim.Init.MemInc = DMA_MINC_ENABLE;
 
 hdma_tim.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
 
 hdma_tim.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
 
 hdma_tim.Init.Mode = DMA_CIRCULAR;
 
 hdma_tim.Init.Priority = DMA_PRIORITY_HIGH;
 
 hdma_tim.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
 
 hdma_tim.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
 
 hdma_tim.Init.MemBurst = DMA_MBURST_SINGLE;
 
 hdma_tim.Init.PeriphBurst = DMA_PBURST_SINGLE;
 
 
 
 HAL_DMA_Init(&hdma_tim);
 
 
 
 /* Link hdma_tim to hdma[TIM_DMA_ID_CC1] (channel1) */
 
 __HAL_LINKDMA(&TIMx_handle, hdma[TIM_DMA_ID_CC1], hdma_tim);
 
 
 
 /*##-2- Configure the NVIC for DMA #########################################*/
 
 /* NVIC configuration for DMA transfer complete interrupt */
 
 HAL_NVIC_SetPriority(TIMx_DMA_IRQn, 2, 4);
 
 HAL_NVIC_EnableIRQ(TIMx_DMA_IRQn);

PWM generation code +++++++++++++++++++++++++++++++

 TIMx_handle.Init.Period = 50;
 
 TIMx_handle.Init.RepetitionCounter = 0;
 
 TIMx_handle.Init.Prescaler = 0;
 
 TIMx_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 
 TIMx_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
 
 
 
 
 
 /*##-1- Initialize the timer in time base generation mode ##################*/
 
 HAL_TIM_PWM_Init(&TIMx_handle);
 
 
 
 /*##-2- Configure the PWM channels #########################################*/
 
 /* Common configuration */
 
 TIMx_sConfig.OCMode = TIM_OCMODE_PWM1;
 
 TIMx_sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
 
 TIMx_sConfig.Pulse = 5;//aCCValue_Buffer[0];
 
 TIMx_sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
 
 TIMx_sConfig.OCFastMode = TIM_OCFAST_DISABLE;
 
 TIMx_sConfig.OCIdleState = TIM_OCIDLESTATE_RESET;
 
 TIMx_sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
 
 
 
 HAL_TIM_PWM_ConfigChannel(&TIMx_handle, &TIMx_sConfig, TIM_CHANNEL_1);
 
 
 
 /*##-3- Start PWM signals generation #######################################*/
 
 
 
HAL_TIM_PWM_Start_DMA(&TIMx_handle, TIM_CHANNEL_1, aCCValue_Buffer, SIZEARRAY);

  

 uint32_t aCCValue_Buffer[SIZEARRAY] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48};

where SIZEARRAY is 25

Below image is for array size 10, came as expected

0693W00000LvxMEQAZ.jpg Below image is for array size 25, not good (I should see 25 different DCs)

0693W00000LvxMnQAJ.jpg

This topic has been closed for replies.

2 replies

waclawek.jan
Super User
March 28, 2022

Which STM32?

Read out and check/compare content of DMA (and perhaps also TIM) registers for both cases.

JW

JohnsAby
JohnsAbyAuthor
Associate III
March 28, 2022

Hi JW

Thanks for update

Am using STM32F427.

I want to update DutyCycle of a PWM timer at every 2us, so I made an array of 25 values and called

HAL_TIM_PWM_Start_DMA(&TIMx_handle, TIM_CHANNEL_1, aCCValue_Buffer, SIZEARRAY);

I have configurated DMA in circular mode.

According to my understanding I should get the below call back after full array gets updated.

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
	HAL_TIM_PWM_Stop_DMA(&TIMx_handle, TIM_CHANNEL_1);
}

But this is not the case, each DU change this is getting called, is there any callback I get after full buffer is empty ?

Please help

waclawek.jan
Super User
March 28, 2022

> But this is not the case, each DU change this is getting called, is there any callback I get after full buffer is empty ?

I don't know, I don't use Cube.

Normally, interrupts from timer and from DMA have separate vectors, it's Cube which mingles them together.

JW