0
\$\begingroup\$

I use STM32F103C8T6 to drive WS2812 RGB LED strip. So I try to setup TIM1 to generate PWM using DMA. Everything works fine except the fact that I get more waves then I requested. Almost all the code I get from STM32CubeMX ready, here is a code that I use:

Time initialization:

static void MX_TIM1_Init(void)
{

  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;
  TIM_OC_InitTypeDef sConfigOC;
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;

  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 3-1;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 30-1;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 0;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  HAL_TIM_MspPostInit(&htim1);
}

DMA Initialization:

static void MX_DMA_Init(void) 
{
  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Channel2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);

}

I use DMA interrupt to stop the timer:

void DMA1_Channel2_IRQHandler(void)
{
    HAL_DMA_IRQHandler(&hdma_tim1_ch1);
    HAL_TIM_PWM_Stop_DMA(&htim1,TIM_CHANNEL_1);
}

And main():

TIM_HandleTypeDef htim1;
DMA_HandleTypeDef hdma_tim1_ch1;

int main(void)
{
  HAL_Init();
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_TIM1_Init();

  uint8_t pData[] = {5,10,15,20,25};
  HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1, (uint32_t *)pData,5);  

  while (1)
  {
  }
}

The CPU works on 72MHz, in clock configuration APB1 Timer clock set to work on 72MHz too.

I configured Timer prescaler to 3 and Counter to 30 steps to generate 800 kHz waves. I send to DMA 5 bytes and expect to get 5 waves with pulse increasing. Here is what I get in fact:

enter image description here

Instead of 5 I get 7 waves for some reason. The last 2 just repeated the 5-th wave.

What I missed and how do I fix the situation?

\$\endgroup\$
  • 1
    \$\begingroup\$ Toggle an output in your DMA interrupt. I think you're looking at interrupt latency. 1us only allows ~72 instructions. \$\endgroup\$ – Jeroen3 Jun 1 '18 at 10:02
  • \$\begingroup\$ Thanks @Jeroen3, that helped me! I just moved stop instruction to the first line inside DMA1_Channel2_IRQHandler and it begins to work as expected. \$\endgroup\$ – folibis Jun 1 '18 at 10:53
  • 1
    \$\begingroup\$ You might want to strip away some HAL and put the effective code in the ISR directly. \$\endgroup\$ – Jeroen3 Jun 1 '18 at 10:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.