cancel
Showing results for 
Search instead for 
Did you mean: 

Why can't I read from more than one UART?

RockfordC64
Associate II

Hello community,

I'm new to ST-MCUs, so maybe this question is very basic.

I'm developing an application for a customer board with a STM32L051R6TX.

For Communication we use USART1 und USART2, for logging I activated LPUART1.

On USART1 und USART2 I get telegrams every 50ms, 40byte long. Baudrate is 9600, 8N1.

To isolate my problen, I created a project with STM32CudeIDE with minimal C-Code.

Initially I activate the Receive Interrupt on both UARTS with 40 bytes, and the InterruptRoutine does this too as the very last command.

Then I added a UARTStateCheckFunction to read the StatusFlgas of the Uarts. It is called in the InterruptRoutine and in the mainCycle (there with 100ms delay).

The InterruptRoutine only counts its calls and the UARTStateCheckFunction also counts the calls, where was an error state on an USART.

I would expect, that the InterruptRoutine is called for every USART and for every telegram. But I receive only on one USART,

The other one gets Errors: RXNE:1 ORE:1 NE:0 FE:0 PE:0 TXE:1 BUSY:0 ABRE:0,

Resetting them in the UARTStateCheckFunction helps sometimes for the ORE Flag..

But on the next call of UARTStateCheckFunction ORE is true again.

Which of the USARTs receives and which errors is randomly.

I also tried to use polling both USART, but I get same behavior. On USART receives, the other one has ORE-Flag on and doesnt receive until timeout.

I also switched of all logging and string oprations on LPUART3 to save MCU time.The App is realy minimalistic.

Is it possible, that this MCU is to slow to process those telegrams on both UARTS?

(The real application has to do some things more in maincycle).

21 REPLIES 21
RockfordC64
Associate II

I'm not shure if my boss will give me the time to read whole books.

The IOC-editor is availlable in my toolchain (STM32CubeIDE 1.9). But I need to find out, which screw to turn on. I can set MSI RC to maximal 4194 kHz, which is twice as much as now, but far away from 24 or 32 Mhz as @Community member​ wrote.0693W00000UnHvCQAV.png

RockfordC64
Associate II

Can I switch to HSI RC and PLLCLK (without destroying anything)?0693W00000UnI6ZQAV.pngSo I would reach 24MHz.

Is this all I have to do?

AScha.3
Chief II

right ! (as i showed in my post before ...)

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

Ok, thats easy.

(What are the advantages /disadvantages of MSI and HSI RC?)

I'll fetch the fire extinguisher and than give it a try.

Thank you.

RockfordC64
Associate II

The IRQ-variant works now on 24Mhz. I'm very happy and gratefull for your hints.and help.

Lets see, if I will get also DMA to work...

Thank you all.

Piranha
Chief II

> The other one gets Errors: RXNE:1 ORE:1 NE:0 FE:0 PE:0 TXE:1 BUSY:0 ABRE:0,

RXNE, TXE and BUSY are not errors.

It's impossible to implement a decent UART reception with HAL. Better don't waste time and look at this:

https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx

Pavel A.
Evangelist III

> What are the advantages /disadvantages of MSI and HSI RC?

Precision, stability.

External oscillators are suitable for matching baud rates between the sides.

With internal oscillators (HSI or MSI) you may have to tune the baudrate to match the other side.

Thank you.

I know, that RXNE, TXE and BUSY are no errors,

I've got a error check-function, which shows them, but only resets ORE and FE, if the occur.

		if ((uart->ErrorCode & HAL_UART_ERROR_ORE) == HAL_UART_ERROR_ORE) //In most cases we have an OverrunError
			__HAL_UART_CLEAR_OREFLAG(uart); //Resetting it helps to reanimate UART
		if ((uart->ErrorCode & HAL_UART_ERROR_FE) == HAL_UART_ERROR_FE) //Sometimes we have an FrameError
			__HAL_UART_CLEAR_FEFLAG(uart); //Resetting it helps to reanimate UART

But it doesn't work. ORE is still on after that.

The arcticle on github is very enlightening, I'll try this.

At the moment it works with HAL but you're right, it seem to be a little bit buggy or inefficent..

To reset ORE condition, also read the RX data register.

Meanwhile I've found it too.

__HAL_UART_CLEAR_OREFLAG(uart); only reset the flag, which is not enough.

Manual says:

Clearing this flag is done by a read access to the USARTx_SR register followed by a read access to the USARTx_DR register.

Please also consider that when clearing this flag, other flags as PE, NE, FE, IDLE would also be cleared.