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

Posted

技术标签:

【中文标题】在STM32板上运行后如何更改UART波特率?【英文标题】:How to change the UART baud rate after running on STM32 board? 【发布时间】:2019-12-08 12:49:36 【问题描述】:

我正在使用 STM32F746ZG 并使用五个 UARTsAll UARTs 工作正常。 有人可以告诉我在 USART 初始化后更改波特率的程序吗?我正在使用USART6 并使用9600 波特率进行初始化。启动后,通过USART 没有任何通信。我想从9600 to 57600 or 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(),但它不起作用。

【问题讨论】:

直接用57600波特初始化会怎样? (没有先用 9600 波特初始化它)它工作吗? 嗨。我解决了这个问题。问题是我没有再次调用 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 你可以回答你自己的问题。它将作为已回答的问题提供,以供其他开发人员将来参考。 【参考方案1】:

您必须中止所有正在运行的HAL_UART 功能,然后取消初始化 uart,更改波特率初始化值并再次初始化:

    HAL_UART_Abort_IT(&huart1);
    
    HAL_UART_DeInit(&huart1);
    
    huart1.Init.BaudRate = 57600;
    
    if (HAL_UART_Init(&huart1) != HAL_OK) 
        Error_Handler();
    
    
    if (HAL_UART_Receive_IT(&huart1, BUFFER, YOUR_BUFFER_SIZE) != HAL_OK) 
        Error_Handler();
    
    

【讨论】:

【参考方案2】:

要更改波特率,您无需重置 UART 外设,只需停止任何活动传输(轮询/IT/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】:

最初我对 P__J__ 的简单回答感到非常兴奋,但事实证明你不能只将所需的波特率放入 BRR - 它必须是过采样和时钟速率的函数。

我使用或多或少相同的方法,但使用“LL_USART_SetBaudRate”来填充寄存器

【讨论】:

使用 C++ 编译器时,constexpr 函数可以提供干净且可配置的解决方案。【参考方案4】:

您的问题应该是:如何使用 bloatware HAL 更改 bautrate?

我不知道。

不过3行简单的代码就可以存档了。

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

【讨论】:

以上是关于在STM32板上运行后如何更改UART波特率?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过串口烧写STM32程序

STM32 UART2 BRR 未给出预期结果

esp8266将波特率改为9600,流控使能了,怎么没法通信了 at+uart

DISCO_STM32L072:Murata模块的设备注册PIN

嵌入式任意波特率的合理计算——高波特率低误差

基于STM32的串口收发讲解(HAL库)#打卡不停更#