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电子技术开发论坛

posted @   lazy12138  阅读(394)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示