在STM32板上运行后如何更改UART波特率?
Posted
技术标签:
【中文标题】在STM32板上运行后如何更改UART波特率?【英文标题】:How to change the UART baud rate after running on STM32 board? 【发布时间】:2019-12-08 12:49:36 【问题描述】:我正在使用 STM32F746ZG
并使用五个 UARTs
。 All 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波特率?的主要内容,如果未能解决你的问题,请参考以下文章
esp8266将波特率改为9600,流控使能了,怎么没法通信了 at+uart