2020-03-23 01:57 PM
I have a GPS module I'm talking to at the default 9600 baud. I then send it a command to change the baud rate up to 115200. After the command is sent, I believe the GPS module is correctly switched over to the new baud rate, since I immediately will start getting UART noise and frame errors.
So after I send the GPS module the command to change the baud, I then change the baud of the MCU. I've tried this two ways, first by simply fully deinitializing and reinitializing the UART with HAL:
void System::changeUARTBaudRate(UART_HandleTypeDef * uart, uint32_t baudRate)
{
HAL_UART_Abort(uart);
HAL_UART_DeInit(uart);
uart->Init.BaudRate = baudRate;
uart->Init.WordLength = UART_WORDLENGTH_8B;
uart->Init.StopBits = UART_STOPBITS_1;
uart->Init.Parity = UART_PARITY_NONE;
uart->Init.Mode = UART_MODE_TX_RX;
uart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
uart->Init.OverSampling = UART_OVERSAMPLING_16;
uart->Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
uart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(uart) != HAL_OK) {
Error_Handler();
}
}
And then I have also tried the simpler approach of setting the registers directly with some literal values:
void System::changeUARTBaudRate(UART_HandleTypeDef * uart, uint32_t baudRate)
{
__HAL_UART_DISABLE(uart);
uart->Instance->BRR = 69; // 8mhz uart clock / 115200 baud;
__HAL_UART_ENABLE(uart);
}
After I change the baud, I then start another UART read with HAL. Whenever the UART error interrupt fires, I simply start another read.
The result of all of this is that after changing baud rate on the MCU, I'm still seeing endless frame errors after each read, and I'm really not sure why.
2020-03-23 03:03 PM
Observe the data from the module and data Tx-ed from STM32 using oscilloscope or logic analyzer, check the actual nauseate of both.
What's the primary clock source? HSI, together with the non-multiple-of-16 of BRR may result in excessive baudrate mismatch.
JW
2020-03-24 04:26 PM
Thanks for your response. I currently don't have a logic analyzer, but it's clear I will need one.
Clocks are shown attached. I'm fairly new to microcontrollers in general, so the clock setup still is a bit of a mystery to me, though I've been reading to try to understand. I did take a stab at setting up a 115200 baud with MX, and noticed it didn't change the clock setup at all, so I took that to mean it it was ok as-is, but I'm not certain.
2020-03-24 10:23 PM
Unfortunately I don't see what can be done without actually measuring the communication from both sides. The module's baudrate may be off, too, at higher rates, I've seen that in the past.
You should use a precise primary clock source (crystal) and a UART (APB) clock such that the fractional part of baudrate divider is 0, both these things increase chances that things will be working.
JW
2020-03-26 07:55 PM
The logic analyzer came today and I figured it out. It was a calamity of timing errors on my part. Sometimes I aborted and reinitialized the UART peripheral with the new baud rate before it finished send the command to the chip, so the MCU would be at the new rate, the chip would be at the old rate. Other times, it could be a scenario where the GPS chip was already at the new baud rate, while the MCU assumed it was at the slower rate, so more framing errors.
Once I could see it happening, it was easy to figure out. Logic analyzers are great.
As for how to change the baud rate, it wasn't clear to me, so for posterity's sake, I'll say that I simply went through HAL_UART_DeInit, change the baud in the UART_InitTypeDef, and then called HAL_UART_Init again.
Thanks