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
AScha.3
Chief III

you are the first one who can read only one uart. great. or -- your mistake??

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

maybe, depends on core clock - you give not much informations.

and i dont find my magic glass ball now...

just guessing: set interrupt on both UARTS to 1 byte ! and make short INT, just store received byte and set global flag , if received ...40B. or whatever is end of telegrams.

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

Thank you for answering. I left the clocking as it was, when I inited my project from the scratch in CubeIDE.

I thought it is not a good idea to get one interrupt each single byte, but I give it a try on monday.

Meanwhile I also tried the DMA-variant of receiving. DMA is circular.. And I called

uint8_t rxData1[40] = {0};
 
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rxData1, 40);

So I expected to get an interrupt every 40 bytes. (or if my RxLine is Idle).

But only the HAL_UART_ErrorCallback is called with Overrun Error.

HAL_UARTEx_RxEventCallback was never called.

And I tried this only for huart1, I have never called. HAL_UARTEx_ReceiveToIdle_DMA for huart2.

What information do you need about clocking and configuration?

I can also send the whole project, if it is sensful.

RockfordC64
Associate II

Nearby: as I see in the oscilloscope: the telegram has a lenght of 40 bytes, which is about 40ms long at 9600 baud. then there is a pause of 10 ms. So the idle detection in DMA mode could be an easy way to synchronize to the start byte.

AScha.3
Chief III

ok, so first just send : *.ioc file.

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

This is the one, what I used for the interrupt version.

May be I'm offline the next days because of weekend and a public holiday on monday.

And I cant take the hardware with me.

So don't be disappointed, if I'm back here not until tuesday. Sorry.

AScha.3
Chief III

fast check: SYSCLKFreq_VALUE=2097000 ; so core running at 2 MHz ....what you expect from 2 MHz cpu ?

:>

select PLLCLK clock as master:

0693W00000UFXYBQA5.png

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

Watch for blocking code in interrupts or callbacks.

DMA check error/status.

UART will stop if it has Noise, Framing, Overrun​ errors.

L0 should run 24 or 32 MHz

2.097 MHz is MSI clock it initially starts with.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
RockfordC64
Associate II

OK, thank you for advices. I'm shure, there is no blocking code in InterruptRoutines in my minimal testapp, only increasing testcounters, and in interrupt-version reactivating the interrupt

But I'm completely inexperienced what to do for getting a faster systemclock. Maybe I'll find a hint in the MCU manual. Or what would you suggest to make it running faster?​

(apropos of nothing: sending an answer to this forum with both of my smartphones browsers didn't work, I got an error "wrong Identifier yyyyyy" after pushing the [answer] button)

Johi
Senior III

Manipulating the clock frequency can be done in the clock configuration panel of the STM32CubeIDE IOC editor if you change the settings of the internal PLL’s, then the processor will run at other speeds. The availability of this tool depends on how your project was set-up. The alternative is to change the code in SystemClock_config() function or similar. Anyway if you are really serious about STM32 reading a few good books can provide the necessary background (e.g. Donald Norris, Programming with STM32, getting started with the Nucleo Board and C++)