【问题标题】:How to change the UART baud rate after running on STM32 board?在STM32板上运行后如何更改UART波特率?
【发布时间】: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 你可以回答你自己的问题。它将作为已回答的问题提供,以供其他开发人员将来参考。

标签: stm32 stm32f4discovery stm32f4 stm32f7


【解决方案1】:

您必须中止所有正在运行的HAL_UART 功能,然后取消初始化 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();
    }
    

【讨论】:

    【解决方案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;
      

      【讨论】:

        猜你喜欢
        • 2015-06-29
        • 2022-12-13
        • 2015-10-28
        • 2022-08-23
        • 2021-06-09
        • 1970-01-01
        • 2019-01-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多