cancel
Showing results for 
Search instead for 
Did you mean: 

is there any way to get interrupt on data ready in UART buffer in HAL library........?

NK.13
Associate II

I were trying to get data continues from a sensor and didnt find any flag that will acknowledge when a data is received . Only thing is there is HAL_UART_Receive_IT(),HAL_UART_Receive() functions.i need to seperate my data from Uart interupt handler.

11 REPLIES 11
KnarfB
Principal III

You can use HAL_UART_Receive_IT( &huart1, &ch, 1 ); to receive a single char ch. When using HAL, the interrupt is wrapped for you in a callback. You implement at global level:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1) {
		// process ch
		HAL_UART_Receive_IT( &huart1, &ch, 1 );	// receive next char
	}
}

There are more callbacks available, see HAL stm32f0xx_hal_uart.h

This works well if the throughput is low or moderate. For high throughput you might want to switch to DMA handling more than 1 char per interrupt. The most elaborated examples I know of are from Tilen Majerle https://stm32f4-discovery.net/2017/07/stm32-tutorial-efficiently-receive-uart-data-using-dma/

hth

KnarfB

NK.13
Associate II

KnarfB,

according to my understating this HAL_UART_RxCpltCallback is interrupted when a reception complete.then how this will get its first interrupt......?

KnarfB
Principal III

Correct. For starting, you call HAL_UART_Receive_IT( &huart1, &ch, 1 ); once in main().

No.

The callback is executed in the context of the Rx interrupt.

Only other interrupts with higher priority could interrupt.

Interrupts of the same priority, including other Uart RX interrupts, get "tail-chained", i.e. execute once the current one finished.

This does not save you from trouble when characters arrive faster then you process them.

berendi
Principal

Unfortunately there is no such functionality in the HAL library.

The workaround presented above is a serious waste of the limited flash and ram space and processing power of the STM32F0, unnecessarily checking flags again and again, needlessly disabling and enabling interrupts after each received byte, etc.

Using the code examples in appendix A, setting up the UART is 2 lines of code, interrupt handling is another 2 lines (receive byte code example goes directly in UART1_IRQHandler()).

NK.13
Associate II

Where i get this code examples appendix A....?

sorry, Appendix A of the Reference manual

this is the handler you mentioned above,isnt.....?

i set this in my while(1) loop and do i need to define UART1_IRQHandler() seperatly....?

There are more than one valid approaches here

  • Processing in the main loop

Put the code above in the main loop. Modify the port setup to NOT set USART_CR1_RXNEIE. Ensure that executing the main loop NEVER takes more time than the time required to receive one character (9.5s/baudrate). E.g. no more than 80 microseconds at 115200 baud. USART1_IRQHandler() is not needed at all, don't enable the USART interrupt.

  • Processing in the interrupt handler

Put the code above in USART1_IRQHandler. Set USART_CR1_RXNEIE, like in the configuration example in the reference manual. Enable the USART1_IRQn interrupt. Ensure that executing the interrupt handler takes much less time than the time required to receive one character. All variables that the interupt handler uses to communicate with the main thread must be atomic types, declared volatile.