cancel
Showing results for 
Search instead for 
Did you mean: 

Why HAL_UART_Transmit_DMA(&huart2, buffer, n) doesn't work properly inside Timer interrupt callback function?

NNang.1
Associate II

Greeting Everyone,

May I have some little help here? I'm currently using STM32F303K8. I had experimented with HAL_UART_Transmit_DMA function within "the main while loop" and the TIM6_DAC1_IRQHandler(void) which was called from TIM6 in Time Base mode

My application is to send the current encoder count by UART. It'd be better to send with an determinable rate, that's why I prefer to use Timer.

Here's part of my code when using polling mode(main.c)

/* USER CODE BEGIN 2 */
  HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);
  HAL_TIM_Base_Start_IT(&htim6);
  //HAL_UART_Receive_DMA(&huart2, pData, Size)
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
    char buffer[12];
    int n = sprintf(buffer, "%ld\n", TIM2->CNT);
    HAL_UART_Transmit_DMA(&huart2, buffer, n);
    HAL_Delay(200);
  }
  /* USER CODE END 3 */

Here's when it's come to Timer interrupt mode(stm32f3xx_it.c)

void TIM6_DAC1_IRQHandler(void)
{
  /* USER CODE BEGIN TIM6_DAC1_IRQn 0 */
 
  /* USER CODE END TIM6_DAC1_IRQn 0 */
  HAL_TIM_IRQHandler(&htim6);
  /* USER CODE BEGIN TIM6_DAC1_IRQn 1 */
  char buffer[12];
  int n = sprintf(buffer, "%ld\n", TIM2->CNT);
  HAL_UART_Transmit_DMA(&huart2, buffer, n);
 
  /* USER CODE END TIM6_DAC1_IRQn 1 */
}

Clock running at 64MHz

TIM6->PSC = 6399 and TIM6->ARR = 1999

So, the expected interrupt rate is 5Hz (similar to delay(200 ms))

The result between 2 mode is from below0693W000000WXE0QAO.png

I'm really curious about this, since the frequency is very low, it should have no problem, or am I missing any point?

Thank you

1 ACCEPTED SOLUTION

Accepted Solutions
Gabriele1
Associate II

Hi,

I think that’s happening because you define the buffer inside the TIM6_DAC1_IRQHandler.

Try to use a globally defined buffer.

View solution in original post

5 REPLIES 5
Gabriele1
Associate II

Hi,

I think that’s happening because you define the buffer inside the TIM6_DAC1_IRQHandler.

Try to use a globally defined buffer.

TDK
Guru

What @Gabriele says is almost certainly the culprit.

However you should also check the return value on HAL_UART_Transmit_DMA to ensure everything worked HAL_OK.

If you feel a post has answered your question, please click "Accept as Solution".
NNang.1
Associate II

Thank you so much, now the data flow like what I expected. But I'm little curious what's the technical reason behind that problem?

The buffer defined within the ISR is a local variable defined on the stack. Once you leave the ISR, whatever is on stack stops to be valid, and other routines using stack may rewrite it.

This is fairly standard C feature. If you want the buffer be persistent, use the static keyword when defining it.

JW

NNang.1
Associate II

I see, thank you for clear explanation