2023-02-24 01:42 AM
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 ?
2023-02-24 04:36 AM
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
2023-02-24 07:42 AM
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.
2023-02-24 08:35 AM
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