7

I'm using STM32F746ZG and use five UARTs. All UARTs are working fine. Can someone tell me the procedure to change the baud rate on the USART once it has already been initialized? I'm using USART6 and initialized with 9600 baud rate. After booting, there is no any communication through USART. I want to change the baud rate from 9600 to 57600 or 115200. For this changing, I called HAL_UART_DeInit() and MX_USART6_UART_Init_57600() but it doesn't work. If I didn't change the baud rate, it works fine. But if I change the baud rate, I can't receive the data through USART. If somebody knows the solution, please let me know.

The followings are my code.

int main(void)
{
  HAL_Init();

  SystemClock_Config();


  MX_UART7_Init();
  MX_UART8_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();
  MX_USART6_UART_Init();

}

void MX_USART6_UART_Init(void)
{
  huart6.Instance = USART6;
  huart6.Init.BaudRate = 9600;
  huart6.Init.WordLength = UART_WORDLENGTH_8B;
  huart6.Init.StopBits = UART_STOPBITS_1;
  huart6.Init.Parity = UART_PARITY_NONE;
  huart6.Init.Mode = UART_MODE_TX_RX;
  huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart6.Init.OverSampling = UART_OVERSAMPLING_16;
  huart6.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart6.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart6) != HAL_OK)
  {
    Error_Handler();
  }
}

void MX_USART6_UART_Init_57600(void)
{
  huart6.Instance = USART6;
  huart6.Init.BaudRate = 57600; // change from 9600 to 57600
  huart6.Init.WordLength = UART_WORDLENGTH_8B;
  huart6.Init.StopBits = UART_STOPBITS_1;
  huart6.Init.Parity = UART_PARITY_NONE;
  huart6.Init.Mode = UART_MODE_TX_RX;
  huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart6.Init.OverSampling = UART_OVERSAMPLING_16;
  huart6.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart6.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart6) != HAL_OK)
  {
    Error_Handler();
  }
}

int Change_UART(void)
{
  HAL_UART_DeInit(&huart6);
  MX_USART6_UART_Init_57600();

}

I called Change_UART() but it doesn't work.

Bor Laze
  • 2,458
  • 12
  • 20
Hans
  • 398
  • 2
  • 4
  • 14
  • 1
    What happens if you initialize it with 57600 baud directly? (without initializing it with 9600 baud first) Does it work? – Tagli Jul 31 '19 at 06:16
  • 2
    Hi. I resolved this issue. The problem was I didn't call HAL_UART_Receive_IT() function again. If I call this function once again after change the parameters. It works fine. So I can change the baud rate, stop bit, parity bit any time. The following is finial solution. int Change_UART(void) { HAL_UART_DeInit(&huart6); MX_USART6_UART_Init_57600(); HAL_UART_Receive_IT(&huart6, (uint8_t*)uart_rx_data_6, 1); } The upper function is simple code. I made some complex code for five UARTs to change the baud rate, parity bit, stop bit, and so one. Thank you. Bye.~ – Hans Jul 31 '19 at 21:32
  • @Hans You can answer your own question. It will be available as an answered question as a future reference for other developers. – kaliczp Aug 01 '19 at 04:39

4 Answers4

11

Your question should be: how to change the bautrate using the bloatware HAL?

I do not know.

But it can be archived in 3 lines of the simple code.

USART6 -> CR1 &= ~(USART_CR1_UE);
USART6 -> BRR = NEWVALUE;
USART6 -> CR1 |= USART_CR1_UE;
0___________
  • 60,014
  • 4
  • 34
  • 74
4

For changing baudrate you don't need to reset UART peripheral, just stop any active transfers (polling/IT/DMA). I use a mix of both:

huart.Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq(), new_baudrate);

Where UART_BRR_SAMPLING8() is a macro from stm32f4xx_hal_uart.h and HAL_RCC_GetPCLK2Freq() function comes from _hal_rcc.c.

This way I don't have to calculate BRR values manually, nor execute the whole initialization procedure, which actually toggles GPIO states, thus generating noise on serial line for whatever is sitting on other end of it.

stiebrs
  • 379
  • 3
  • 13
2

You have to abort all running HAL_UART funttions, then de-initialize the uart, change the baudrate init value and initialize it again:

  1. HAL_UART_Abort_IT(&huart1);
    
  2. HAL_UART_DeInit(&huart1);
    
  3. huart1.Init.BaudRate = 57600;
    
  4. if (HAL_UART_Init(&huart1) != HAL_OK) {
        Error_Handler();
    }
    
  5. if (HAL_UART_Receive_IT(&huart1, BUFFER, YOUR_BUFFER_SIZE) != HAL_OK) {
        Error_Handler();
    }
    
Syscall
  • 19,327
  • 10
  • 37
  • 52
dbuchber
  • 21
  • 1
0

Originally I was really excited by P__J__'s simple answer, but it turns out you can't just put the desired baud rate into BRR - it has to be a function of oversampling and the clock rate.

I used more or less the same method but with "LL_USART_SetBaudRate" to fill the register

Drewster
  • 174
  • 1
  • 9
  • When using a C++ compiler, a `constexpr` function can provide a clean & configurable solution. – Tagli Mar 30 '21 at 21:11