cancel
Showing results for 
Search instead for 
Did you mean: 

Hello, I'm having troubles changing the baudrate of my UART2 configuration. It is initially set to 921600 bps and a bit duration is 1.08us = 1/921600bps, which is fine. However, trying to double this value seems impossible.

PMach.1
Senior

In MX, at first, I changed the sample rate to 8 bits to double the baudrate. The code was successfully generated, compiled and downloaded. The communication still exists, but the baudrate is still the same as before, with a bit duration of 1.08us.

Then, on MX view, I reverted the sample rate back to 16 bits and introduced manually the new baudrate 1843200. The same as before happened, with the baudrate not being updated.

I tried to update directly the values on the MX_USART2_UART_Init function and the same happened, the baudrate is still 921600bps.

As I suspected this could be a rate compatibility problem, I decided to lower the baudrate to 115200bps, both on MX view and directly on the code. Again, the real baudrate remained at 921600 bps.

On my test setup, I have two MCUs STM32H745IIK6 connected together through their UART2 (no flow control and no baudrate auto-detect). One of the MCUs sends a byte constantly over and over and the other receives it and sends it back. Obviously, the changes in baudrate I preformed were on both MCUs.

Attached goes a printscreen from the oscilloscope of a byte sent (0x71), and cursors measuring the bit width.

Any ideas on what is causing this problems?

Thanks in advance,

Machado

1 ACCEPTED SOLUTION

Accepted Solutions
PMach.1
Senior

The problem is solved!

Trying to figure out in detail, I decided to run the code step-by-step in debug mode. It happens that in this mode I checked the BRR being correctly written (like I wanted). It ended up with the UART running in different baudrates, as ordered. Basically, it works when running step-by-step in debug, but not in normal runtime.

I decided to run it step-by-step, without stepping into that many functions, so as to not to go too low-level. Gradually, I observed that only stepping over the HAL_UART_Init() function inside MX_USART2_UART_Init() function, resuming the rest of the code to runtime mode would suffice to correctly program the UART into running. I started getting the suspicion that it was some kind of timing issue, that prevented the normal writing into the registers, although some variables were updated with the correct values (like, for example, huart2.Instance.BRR which I was checking, assuming it would correctly write the value on the register, which aparently didn't).

I came up with the workaround of adding a delay before the function HAL_UART_Init() is brought up. This *****, obviously. Now, anytime I alter the definitions in MX view and generate new code, might have to re-add the delay. My new MX_USART2_UART_Init function is as follows:

void MX_USART2_UART_Init(void)

{

 huart2.Instance = USART2;

 huart2.Init.BaudRate = 1843200;

 huart2.Init.WordLength = UART_WORDLENGTH_8B;

 huart2.Init.StopBits = UART_STOPBITS_1;

 huart2.Init.Parity = UART_PARITY_NONE;

 huart2.Init.Mode = UART_MODE_TX_RX;

 huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;

 huart2.Init.OverSampling = UART_OVERSAMPLING_16;

 huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;

 huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;

 huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT|UART_ADVFEATURE_DMADISABLEONERROR_INIT;

 huart2.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;

 huart2.AdvancedInit.DMADisableonRxError = UART_ADVFEATURE_DMA_DISABLEONRXERROR;

 HAL_Delay(1);

 if (HAL_UART_Init(&huart2) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)

 {

  Error_Handler();

 }

}

Again, I only suspect of a timing issue and do not fully understand why it happens. If anyone knows exactly what the problem might be, or even has a different suspicion, please, feel free to comment.

Regards

View solution in original post

15 REPLIES 15
TDK
Guru

Changing the oversampling from 16 to 8 doesnt affect the baud rate.

Are you regenerating code after changing the setting?

You could inspect the BRR register to see what it gets. Note that there is a limit to max baud rate depending on the peripheral clock speed.

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

Hello and thank you for your quick response,

According to the Reference Manual, at least from what I understood, a oversampling of 8 doubles the baudrate (check pg. 2212, section 51.5.7: https://www.st.com/resource/en/reference_manual/dm00176879-stm32h745755-and-stm32h747757-advanced-armbased-32bit-mcus-stmicroelectronics.pdf)

I am not forgetting to regenerate the code. I double check on the MX Init function and the baud rate changes, effectivelly. Right now:

huart2.Init.BaudRate = 1843200;

(...)

huart2.Init.OverSampling = UART_OVERSAMPLING_16;

I went checking the BRR register, did the computations and the value there is correct. I have a 100MHz clock feeding the BR generator with a prescaler of one, thus, 100000000/1843200 = 54.25.

The BRR register is specifically 54, which seems correct.

And the real baudrate with BRR set to 54 is how much?

JW

I could have been more precise.

Changing the oversampling from 8 to 16 in CubeMX and then regenerating code won't change the rate, because the initialization code takes care of that for you. It's different if you're just flipping the OVER8 bit manually.

It doesn't really make sense that the rate would be fixed at 921600 regardless of what you're trying to set it to. I suspect something else may be going on here.

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

It should be 1843200. It is still 921600

Do you read out the UART registers *after* transmission which measured 921600, and BRR is 45?

Do you read out the same UART which is used for the transmission?

JW

Here is the initialization function. Do you see anything wrong?

huart2.Instance = USART2;

 huart2.Init.BaudRate = 921600;

 huart2.Init.WordLength = UART_WORDLENGTH_8B;

 huart2.Init.StopBits = UART_STOPBITS_1;

 huart2.Init.Parity = UART_PARITY_NONE;

 huart2.Init.Mode = UART_MODE_TX_RX;

 huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;

 huart2.Init.OverSampling = UART_OVERSAMPLING_16;

 huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;

 huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;

 huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT|UART_ADVFEATURE_DMADISABLEONERROR_INIT;

 huart2.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;

 huart2.AdvancedInit.DMADisableonRxError = UART_ADVFEATURE_DMA_DISABLEONRXERROR;

 if (HAL_UART_Init(&huart2) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)

 {

  Error_Handler();

 }

Correction: huart2.Init.BaudRate = 1843200;

Sorry

Hi, waclawek.jan,

I didn´t understand your question. Anyway, I kind of found the issue, though I could not understand exactly what happens, but for mere suspicions. I'll describe it in detail below.