cancel
Showing results for 
Search instead for 
Did you mean: 

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 help

JohnsAby
Associate II

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

3 REPLIES 3

Which STM32?

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

JW

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

> 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