如何在STM32板上运行后更改UART波特率?

7
我正在使用 STM32F746ZG 并使用了五个 UART。所有的UART都工作正常。 有人能告诉我在初始化后如何更改USART的波特率吗?我正在使用USART6,并以9600波特率进行初始化。启动后,没有任何通过USART的通信。我想将波特率从9600更改为57600或115200。为了进行这种更改,我调用了HAL_UART_DeInit()MX_USART6_UART_Init_57600() 但它不起作用。 如果我不改变波特率,它可以正常工作。但是如果我改变波特率,我就无法通过USART接收数据。 如果有人知道解决方法,请告诉我。
以下是我的代码。
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();

}

我调用了Change_UART()函数但它没有起作用。

1
如果直接使用57600波特率进行初始化会发生什么?(不先使用9600波特率进行初始化)它能正常工作吗? - Tagli
2
你好。我解决了这个问题。问题是我没有再次调用HAL_UART_Receive_IT()函数。如果我在更改参数后再次调用此函数,它就可以正常工作。所以我可以随时更改波特率、停止位、奇偶校验位等。 以下是最终解决方案。 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); } 上述函数是简单的代码。我为五个UART制作了一些复杂的代码,以更改波特率、奇偶校验位、停止位等。 谢谢。再见~ - Hans
@Hans 你可以回答自己的问题。这将作为已回答的问题供其他开发人员在未来参考。 - kaliczp
4个回答

11

您的问题应该是如何使用bloatware HAL更改波特率?

我不知道。

但使用三行简单的代码就可以实现。

USART6 -> CR1 &= ~(USART_CR1_UE);
USART6 -> BRR = NEWVALUE;
USART6 -> CR1 |= USART_CR1_UE;

4
更改波特率时,不需要重置UART外设,只需停止任何活动传输(轮询/中断/ DMA)。我同时使用了两种方式:
huart.Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq(), new_baudrate);

UART_BRR_SAMPLING8()是stm32f4xx_hal_uart.h中的一个宏,HAL_RCC_GetPCLK2Freq()函数来自_hal_rcc.c。

这样我就不必手动计算BRR值,也不必执行整个初始化过程,该过程实际上会切换GPIO状态,从而在串行线上生成噪音,影响线路另一端的设备。


3
你需要中止所有正在运行的 HAL_UART 函数,然后取消初始化串口,更改波特率初始值并重新初始化它:
  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();
    }
    

0
最初我对P__J__的简单答案感到非常兴奋,但事实证明你不能只是将所需的波特率放入BRR中 - 它必须是过采样和时钟速率的函数。
我使用了几乎相同的方法,但是使用"LL_USART_SetBaudRate"来填充寄存器。

当使用C++编译器时,constexpr函数可以提供一个干净且可配置的解决方案。 - Tagli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接