HC32F460串口波特率设置19200,函数返回ErrorInvalidParameter
今天,在调试项目的时候,遇到设置串口2波特率为19200的时候,USART_SetBaudrate(M4_USART2, 19200)函数返回 ErrorInvalidParameter,导致程序陷入了死循环,配置程序如下:
void USART2_LIN_Config(void){ #ifdef LIN_EN #ifdef HC32_MCU stc_usart_uart_init_t stcInitCfg; en_result_t enRet; stcInitCfg.enClkDiv = UsartClkDiv_1; stcInitCfg.enClkMode = UsartIntClkCkNoOutput; stcInitCfg.enDataLength = UsartDataBits8; stcInitCfg.enDirection = UsartDataLsbFirst; stcInitCfg.enStopBit = UsartOneStopBit; stcInitCfg.enParity = UsartParityNone; stcInitCfg.enSampleMode = UsartSamleBit8; stcInitCfg.enDetectMode = UsartStartBitFallEdge; stcInitCfg.enHwFlow = UsartRtsEnable; enRet = USART_UART_Init(M4_USART2, &stcInitCfg); if (enRet != Ok) { while (1); } enRet = USART_SetBaudrate(M4_USART2, 19200); if (enRet != Ok) { while (1); } USART_FuncCmd(M4_USART2, UsartRx, Enable); USART_FuncCmd(M4_USART2, UsartTx, Enable); USART_FuncCmd(M4_USART2, UsartRxInt,Enable); #endif #endif }
之后,我百思不得其解,根据函数注释来看是“ErrorInvalidParameter USARTx is invalid”,也就是串口无效,这怎么可能呢,之后我进入底层函数查看
在 static en_result_t SetUartBaudrate(M4_USART_TypeDef *USARTx, uint32_t u32Baudrate) 函数里看,分析华大提供的设置波特率函数,发现在串口时钟设置为不分频的情况下,19200波特率通过代码第32行计算后,第35行的判断是不成立的,DIV_Integer的值远大于0xFF,
1 static en_result_t SetUartBaudrate(uint32_t u32Baudrate) 2 { 3 en_result_t enRet = Ok; 4 uint32_t B; 5 uint32_t C; 6 uint32_t OVER8; 7 float32_t DIV = 0.0f; 8 uint64_t u64Tmp = 0u; 9 uint32_t DIV_Integer = 0u; 10 uint32_t DIV_Fraction = 0xFFFFFFFFul; 11 12 uint32_t u32PClk1 = 0u; 13 uint32_t u32UartClk = 0u; 14 15 u32PClk1 = SystemCoreClock / (1ul << (M4_SYSREG->CMU_SCFGR_f.PCLK1S)); 16 u32UartClk = u32PClk1 / (1ul << (2ul * (M4_USART3->PR_f.PSC))); 17 18 B = u32Baudrate; 19 C = u32UartClk; 20 21 if (0ul == C) 22 { 23 enRet = ErrorInvalidParameter; 24 } 25 else 26 { 27 OVER8 = M4_USART3->CR1_f.OVER8; 28 29 /* FBME = 0 Calculation formula */ 30 /* B = C / (8 * (2 - OVER8) * (DIV_Integer + 1)) */ 31 /* DIV_Integer = (C / (B * 8 * (2 - OVER8))) - 1 */ 32 DIV = ((float)C / ((float)B * 8.0f * (2.0f - (float)OVER8))) - 1.0f; 33 DIV_Integer = (uint32_t)(DIV); 34 35 if ((DIV < 0.0f) || (DIV_Integer > 0xFFul)) 36 { 37 enRet = ErrorInvalidParameter; 38 } 39 else 40 { 41 if ((DIV - (float32_t)DIV_Integer) > 0.00001f) 42 { 43 /* FBME = 1 Calculation formula */ 44 /* B = C * (128 + DIV_Fraction) / (8 * (2 - OVER8) * (DIV_Integer + 1) * 256) */ 45 /* DIV_Fraction = ((8 * (2 - OVER8) * (DIV_Integer + 1) * 256 * B) / C) - 128 */ 46 /* E = (C * (128 + DIV_Fraction) / (8 * (2 - OVER8) * (DIV_Integer + 1) * 256 * B)) - 1 */ 47 /* DIV_Fraction = (((2 - OVER8) * (DIV_Integer + 1) * 2048 * B) / C) - 128 */ 48 u64Tmp = (2u - (uint64_t)OVER8) * ((uint64_t)DIV_Integer + 1u) * (uint64_t)B; 49 DIV_Fraction = (uint32_t)(2048ul * u64Tmp/C - 128ul); 50 } 51 else 52 { 53 } 54 55 M4_USART3->CR1_f.FBME = (0xFFFFFFFFul == DIV_Fraction) ? 0ul : 1ul; 56 M4_USART3->BRR_f.DIV_FRACTION = DIV_Fraction; 57 M4_USART3->BRR_f.DIV_INTEGER = DIV_Integer; 58 enRet = Ok; 59 } 60 } 61 return enRet; 62 }
我怀疑是频率的问题,先查看
HC32F460_F45x_A460 系列参考手册,发现一横话:
原先给串口分配的频率是42MHz,之后我改为10.5MHz,就好了
结论:在使用较低波特率进行通信时,需将串口时钟频率降低。串口时钟在100MHz的情况下,想使用9600波特率,分频系数不低于8分频。我使用的是16分频,使用正常。
之后,我发现人家测评的写的比较详细,给大家分享一下---》华大HC32F460避坑之串口通讯 - - 21ic电子技术开发论坛
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具