cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H563ZIT6 cannot receive RS485 at high baud rates (e.g. 12 Mbaud)

MES98
Associate III

TX works but RX interrupt not triggered

 

Hello,

I am currently using a custom board based on STM32H563ZIT6. My goal is to establish communication over RS485 between the STM32 and a PC (using Hterm). The system is designed to receive a command and send a response.


Communication Details:

  • Interface: RS485 (half-duplex)
  • PC Tool: Hterm
  • Converter: USB COM 485 PLUS 4
  • Packet size: Very small (typically 4 bytes)
  • Transmission interval: ≥ 300 ms

Current Situation:

  • Communication works perfectly between 115200 and 2,000,000 baud
  • I am trying to increase the baud rate up to 12 Mbaud

Problem:

At 12 Mbaud:

  • STM32 → PC communication works correctly
    (I can see transmitted data on Hterm)
  • PC → STM32 communication does NOT work
    • STM32 does not receive any data
    • RX interrupt is not triggered at all
    • It behaves as if no data is arriving

Additional Notes:

  • I have checked the termination resistor, and it seems correct
  • The data sent from PC is valid (verified from Hterm)
  • UART baud rate is configured up to 12.5 Mbaud in CubeMX
  • The issue only appears at very high baud rates

What I Suspect:

  • Possible limitation of RS485 converter at high baud rates
  • UART sampling/timing issues at 12 Mbaud
  • Interrupt-based reception may not be sufficient at such speeds
  • Hardware limitations (signal integrity, cable, etc.)

Questions:

  1. Is it realistic to achieve 12 Mbaud over RS485 in this setup?
  2. Could this be a limitation of the USB-RS485 converter?
  3. Are there any specific STM32 UART settings required for such high speeds?
  4. Should DMA be used instead of interrupt for reliable reception?
  5. Are there known limitations for STM32H5 series UART at these speeds?

Any insights or similar experiences would be very helpful.

Thanks in advance!

41 REPLIES 41
Andrew Neil
Super User

Also, those edges look rather slow

12MBaud.jpg

As @Ozone said, hard to tell if that's real, or an artifact of the scope and/or probe ...

 

@MES98 Doesn't your scope have a way to download screennshots?

That would give much better results than trying to photograph the screen!

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
mƎALLEm
ST Employee

@MES98 

Just to be sure, what GPIO speed you set for the Tx and Rx pins? Did you set them to "Very High"?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

> Also, those edges look rather slow

Yes, I very much agree. Although I'm not sure how the scope bandwidth, resolution and probe attachment affect this.
Probably one of the lower-end scopes, with 2 channels, 8-bit resolution and around 100MHz.

I suppose your are aware of the Laplace / Fourier theorems, and the bandwidth requirement this implies. There does not seem much beyond the second harmonic present in the shown signal.

 

MES98
Associate III

@Kalpak I don’t think it is causing a problem, but honestly I’m not sure why it appears.
If it were an issue, I would expect it to also affect communication at 2 Mbaud or 4 Mbaud, but those work without any problems.

Also, I am not using a long crocodile ground lead. As you suggested, I am measuring the differential lines using a very short, thin ground connection.

@Ozone You might be right. I don’t have very deep experience in this area, and my oscilloscope is relatively old, so the measurements might be affected by its limitations.

 

@unsigned_char_array I am already measuring it in this way :(

 

@Andrew Neil Unfortunately, my oscilloscope does not support direct screenshot export.
However, I can capture the signal using single trigger mode and then take a picture of the screen.


@mƎALLEm Yes, the GPIO speed is set to Very High.
You can also see it in the image I shared.
There might still be a misconfiguration in other settings though.

 

@Ozone 

Yes, you guessed my oscilloscope quite well :D I am using a GW Instek GDS-1104S, and it does have some limitations.

By the way, the transmitted data is just a 4-byte packet.
What would you recommend I try next?

At the moment, I am planning to test using the LPUART peripheral, which theoretically supports much higher baud rates (up to 50 Mbaud).
I will share an update if I observe any changes.

MES98_0-1775732380101.png

MES98_1-1775732427345.png

 

Can it be unhandled RX overrun or error condition?

 

Ozone
Principal III

> Yes, you guessed my oscilloscope quite well :D

Not that it's a problem. I own a Rigol scope with very similiar specs, and it works fine for most use cases.
However, you should always be aware of the limitations.

> At the moment, I am planning to test using the LPUART peripheral, which theoretically supports much higher baud rates (up to 50 Mbaud).

Not sure what you require such high throughputs for.
High interrupt loads or similiar regular tasks can easily consume most of the available core performance.
This is generally not a use case that standard microcontrollers like Cortex M are specifically designed for.

>  Yes, the GPIO speed is set to Very High.

AFAIK this only affects internal glitch filters.
But with bit rates far beyond 1Mbit/s, you will need consistent characteristic impedance cabling and proper impedance matching of the external circuitry and cabling. Which often means twisted pair or coax cable, with series resistors, for example. And a connection as short as possible.


@Ozone wrote:

>  Yes, the GPIO speed is set to Very High.

AFAIK this only affects internal glitch filters.


On outputs, it affects the drive strength - to be able to produce fast edges.

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

You're not so much interested in the waveform on the RS485, but rather in the signal waveform after the receiver on the STM32 side. Measure it as accurately as possible directly at the STM32's RX pin. This will help you determine whether the problem lies with the STM32 or is a signal integrity issue.
If you find that the signal is fine there, use an oscilloscope to measure its actual bit rate precisely. Next, you should verify the actual speed at which the UART on the STM32 is operating (12 Mbit is already very high and may hit the "divider" limits). You can do this either by calculating it from the values read from the registers, or more simply by sending something (to TX) and measuring it with an oscilloscope.

BTW: The manual for the USB-COM485-PLUS2 (Version 1.3) states:
"Serial port speed up to 10Mbps"

Screenshot 2026-04-10 174141.png

MES98
Associate III

@Pavel A. @Michal Dudka @Andrew Neil @mƎALLEm  @Ozone Thank you for the detailed explanation.

After checking the datasheet more carefully, I realized that the maximum supported speed is actually 10 Mbaud, not 12 Mbaud. However, I am currently unable to communicate reliably even at 8 Mbaud.

I would like to share an important update — I believe I have finally identified the root cause of the issue.

The problem is related to a UART overrun error.

For example:

  • At around 6 Mbaud, if I send data byte by byte, the STM32 is able to receive it correctly
  • In that case, the data accumulates in my ring buffer, and I can process it as expected

However:

  • My actual goal is to send a 4-byte packet at once
  • At higher baud rates (6 / 8 / 10 Mbaud), this causes an overrun, and data is lost

I tried increasing the RX FIFO threshold to FULL, which improved the situation slightly, but I am still only able to reliably receive up to 3 bytes at once


Constraint:

  • I am required to use interrupt-based reception
  • Unfortunately, using DMA is not an option in my case

Question:

Is there any recommended way to handle high baud rate UART reception (6–10 Mbaud) using interrupts only, without causing overrun?

Are there specific FIFO, interrupt, or buffering strategies that could help in this scenario?


Any suggestions or best practices would be greatly appreciated.