2023-10-29 04:18 AM - last edited on 2023-11-01 12:49 AM by Imen.D
Hello,
I have an STM32L476G Evaluation board, and I'm trying to use USART1 to generate an interrupt on receiving characters. On the evaluation board, this is connected to the RS232 port, which I have a module, I transmit data to get a response back. I've hooked up a salae logic analyser and can see when I send the data, the response is being sent back.
From CubeMX I have enabled the USART1, with global interrupts, as well as in the project manager tab, I have selected in the advanced settings register callback for USART and UART.
In the code I write the line below, to receive and interrupt every character:
HAL_UART_Receive_IT(&huart1, rx_buffer, 1);
Then I transmit the string code I write the line below, to receive and interrupt every character:
while(HAL_UART_Transmit_IT(&huart1, atc, 4) != HAL_OK);
HAL_Delay(1000);
The function below gets called, however, HAL_UART_RxCpltCallback(UART_HandleType *huart) never gets called.
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
When I debug and put a breakpoint in the USART_IRQHandler(void) function, there is no data in the buffer.
What is the problem with what I am doing and why is the data not being stored in the buffer? I am generating an interrupt as the USART_IRQHandler(void) is causing the breakpoint to stop, but there is no data in the buffer.
2023-10-29 04:42 AM - edited 2023-10-29 04:43 AM
Selecting "register callback" means, that you have to write code registering your own functions. The traditional way is not selecting that in which case you have to implement your own HAL_UART_RxCpltCallback (what yo did).
If you still encounter issues, step into HAL_UART_IRQHandler and let the code show you what's going on.
hth
KnarfB
2023-10-29 04:52 AM
2023-10-29 05:07 AM
Shouldn't be using the while() loops for the transmit, the IT function will return immediately.
2023-10-29 05:09 AM - edited 2023-10-29 05:15 AM
@Tesla DeLorean Ok that's fine, I've stopped doing that and still the interrupt gets triggered and no data shows when I debug
2023-10-29 05:14 AM - edited 2023-10-29 05:15 AM
@KnarfB Ok so I've unset register callback for the usart/uart. Still not data is being shown in the buffer, and the HAL_UART_RxCpltCallback is not called. In the HAL_UART_IRQHandler this if statement gets skipped.
I attached the _hal_uart.c for reference.
2023-10-29 07:42 AM
is rx_buffer a global variable? The pRxBufPtr variable in your above dump has advanced one char position, so something was received?
HAL handler should call UART_RxISR_8BIT which in turn calls your callback. Check error bits.
hth
KnarfB
2023-10-29 08:16 AM - edited 2023-10-29 08:52 AM
@KnarfB Yes rx_buffer is my global variable that stores the data. I will check tomorrow when I go into work and probe the stm pin, to see what data is coming in.
In the UART_RxISR_8BIT function, the huart->RxCpltCallbacl(huart) gets called, but it happens only once and only goes straight to the return statement, and not the if statement.
My callback function looks like this:
It could be possible that the first character received is garbage (doubt it due to the logic analyser). However, why the callback only happens once is probably a bigger problem.
In terms of error bits, is that taken from the huart instance? For example why debugging the huart in the Live Expressions the ErrorCode is 4.
I believe this is a framing error response, as the UART1_IRQHandler() sets it and has a break point there:
2023-10-29 08:58 AM - edited 2023-10-29 09:00 AM
"huart->RxCpltCallback(huart) is called" Then, USE_HAL_UART_REGISTER_CALLBACKS is still defined. You may regenerate the code to let HAL_UART_RxCpltCallback(huart); be called. The weak default implementation will be replaced by the linker by your function of (exactly) the same name.
The interrupt is only one-shot after HAL_UART_Receive_IT. You have to call that again at the end of your callback.
Single char IRQ based RX will work for lower baud rates, but is a bit of a ressource hog; at least when HAL is used.
Note that there are advanced alternatives.like https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx oder receiving a line until idle or matching char.
hth
KnarfB