cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_UART_RxCpltCallback() doesn't trigger

LBiss.1
Associate

I am working on a STL32F401RET6 MCU and the HAL_UART_RxCpltCallback() doesn't work even though I turned the global interrupt on.

Here is my code for the callback functions :

  void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
	  HAL_GPIO_TogglePin(GPIOA, LD2_Pin);
 
  	  HAL_Delay(1000);
  	  HAL_GPIO_TogglePin(GPIOA, LD2_Pin);
    }
 
  void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
      {
  	  	  HAL_GPIO_TogglePin(GPIOA, LD2_Pin);
  	  	  HAL_Delay(1000);
  	  	  HAL_GPIO_TogglePin(GPIOA, LD2_Pin);
      }

And this is the code I'm trying to run, which should trigger the callback functions :

char recep[]="";
 
HAL_UART_Receive_IT(&huart2, recep, 1);
HAL_Delay(3000);
recep[1]='b';
HAL_UART_Transmit_IT(&huart2,recep,2);
 
while (1);

I have an Hercules terminal running and the communication works alright, I just don't get why the callback functions won't fire.

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
 
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
 
  /* USER CODE END USART2_IRQn 1 */
}

Here is my USART2_IRQHandler() as well. I checked the stm32f4xx_hal_conf and stm32f4xx_it files and both the IRQHandler and UART module are functional.

Is there something I forgot ?

3 REPLIES 3
Anwar.786
Associate II

Try adding this in your callback function HAL_UART_Receive_IT(&huart2, recep, 1);

callback function should look like this

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

HAL_UART_Receive_IT(&huart2, recep, 1);

HAL_GPIO_TogglePin(GPIOA, LD2_Pin);

HAL_Delay(1000);

HAL_GPIO_TogglePin(GPIOA, LD2_Pin);

}

once you tried the above method let me know the status

Karl Yamashita
Lead III

You can't use HAL_Delay inside an interrupt. Until you exited HAL_UART_RxCpltCallback the HAL_Delay is going to stay stuck because the systick can't interrupt. Same for HAL_UART_TxCpltCallback.

Set a flag in HAL_UART_RxCpltCallback. Check the flag in main while loop and do what you need to do there.

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.
Karl Yamashita
Lead III

Here is an example of using flags and doing everything outside of an interrupt.

volatile bool dataRdyFlag = false;
volatile bool txDoneFlag = false;
char recep[2] = {0};
volatile bool rxIntErrorFlag = false;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == huart2.Instance)
	{
		dataRdyFlag = true;
		EnableRxInterrup();
	}
}
 
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
	txDoneFlag = true;
}
 
void EnableRxInterrup(void)
{
	if(HAL_UART_Receive_IT(&huart2, (uint8_t*)recep, 1) != HAL_OK)
	{
		rxIntErrorFlag = true;
	}
}
 
int main(void)
{
	EnableRxInterrup();
	while(1)
	{
		if(dataRdyFlag)
		{
			dataRdyFlag = false;
 
			recep[1] = 'b';
			HAL_UART_Transmit_IT(&huart2,(uint8_t*)recep,2);
 
 
			HAL_GPIO_TogglePin(GPIOA, LD2_Pin);
 
			HAL_Delay(1000);
			HAL_GPIO_TogglePin(GPIOA, LD2_Pin);
		}
		if(txDoneFlag)
		{
			txDoneFlag = false;
			HAL_GPIO_TogglePin(GPIOA, LD2_Pin);
			HAL_Delay(1000);
			HAL_GPIO_TogglePin(GPIOA, LD2_Pin);
		}
		if(rxIntErrorFlag)
		{
			rxIntErrorFlag = false;
			EnableRxInterrup();
		}
	}
}

You should check this video on blinking an LED using TimerCallback. This eliminates using HAL_Delay which is blocking code. The video is more on debouncing a push button but it also goes a little bit into blinking an LED at different rates

ttps://youtu.be/o0qhmXR5LD0

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.