2022-05-24 01:53 AM
I've followed some answers from a post here:
But still can't seem to get the baud rate to change. Has anyone had any luck trying to dynamically change the baud rate of the UART?
/****************************************************/
USART6 -> CR1 &= ~(USART_CR1_UE);
USART6 -> BRR = NEWVALUE;
USART6 -> CR1 |= USART_CR1_UE;
/****************************************************/
huart.Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq(), new_baudrate);
/****************************************************/
HAL_UART_DeInit(instance[bus].handle);
instance[bus].handle->Init.BaudRate = baud;
HAL_UART_Init(instance[bus].handle);
Solved! Go to Solution.
2022-05-30 07:02 AM
Here is a follow up and answer to the problem.
The issue was that The UART was part way through a interrupt transmission while I was changing the Baud rate. Having a static variable that keeps track of a message being sent has solved this issue.
2022-05-24 02:08 AM
I've also tried running the MX code again like below. The HAL_UART_Init doesn't show any errors, but the program seems to crash after this.
huart4.Instance = UART4;
huart4.Init.BaudRate = baud;
huart4.Init.WordLength = UART_WORDLENGTH_8B;
huart4.Init.StopBits = UART_STOPBITS_1;
huart4.Init.Parity = UART_PARITY_NONE;
huart4.Init.Mode = UART_MODE_TX_RX;
huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart4.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart4) != HAL_OK)
{
Error_Handler();
}
2022-05-24 02:50 AM
How sure are you that instance[bus].handle is what you want it to be?
2022-05-24 03:20 AM
@C.East2 "the program seems to crash"
What, exactly, do you mean by that?
as @Javier Muñoz suggests, if the instance[bus].handle is wrong, that could cause such issues...
@C.East2
2022-05-24 07:58 AM
Certain with the instance[bus].handle. This is correct.
2022-05-24 08:00 AM
Sorry about that.
It doesn't hard fault. I'm not sure if it's in a loop somewhere. It's not in syscalls.
2022-05-24 08:02 AM
I'm less worried about the instance where i've deinitialised it (though I do understand it may be part of the problem) but more confused as to how I would properly go about changing the Baud rate dynamically. Are you suggesting that I HAVE done it correctly in one of my examples?
2022-05-24 08:28 AM
Hi @C.East2
If your UART (example UART4), if working properly with baudrate X, you could change baudrate to Y by using the methods you mentioned, especially :
UART_HandleTypeDef huart4;
...
huart4.Instance = UART4
huart4.Init.BaudRate = X;
HAL_UART_Init(&huart4);
...
HAL_UART_DeInit(&huart4);
huart4.Init.BaudRate = Y;
HAL_UART_Init(&huart4);
...
Please make sure that you provide required content for HAL_UART_MspInit() and HAL_UART_MspDeInit() functions to handle HW resources associated to this UART, as clock source, GPIOs, ...
By default, weak functions are defined with empty bodies for these HAL_UART_MspInit() and HAL_UART_MspDeInit() functions. Please define your owns (it is normally done if you are using STM32CubeMx).
Regards.
2022-05-24 12:56 PM
@C.East2 After write to the UART register : USART6 -> CR1 &= ~(USART_CR1_UE);
add read-back to let the write propagate all way to the device (TL;DR this is complicated).
Barrier instructions after write won't harm too :
USART6 -> CR1 &= ~(USART_CR1_UE);
__DSB(); // barrier
(void)(USART6 -> CR1); // read-back
__DMB();
USART6 -> BRR = NEWVALUE;
__DSB();
(void)(USART6 -> BRR);
__DMB();
USART6 -> CR1 |= USART_CR1_UE;
__DSB();
2022-05-24 01:27 PM
Yeah, I don't know it that's necessary
It's suppose to complete the reads/writes in order, and the read should force the pending writes to complete. The _IO (or volatile) nature of the registers means the compilers not going to fold things.
Where it becomes an issue is the clock cycles between enabling the peripheral (gating the synchronous clock into it), and it being functional. And secondarily when clearing an interrupt state at a peripheral level, and that completing, and then propagating thru the NVIC at the point where the tail-chaining do it or don't do it decision is made.