华大HC32L13x 串口波特率设置为115200打印乱码问题

问题描述

华大低功耗MCU HC32L13x在设置串口波特率为115200时,串口打印乱码,而设置9600串口打印ok。官方例程也是9600bps,然而平常串口打印习惯性还是配置为115200-8-N-1(8bit数据位,无校验位,1停止位)

标准的115200bps的最小脉宽应该为8.68us,标准的9600bps的最小脉宽应该为104.17us

现象分析

配置115200打印乱码而不是没有打印说明有数据出来,但是不满足要求,软件在串口输出字符“123”,用逻辑分析仪抓取的乱码波形,关键,可以看到最小脉宽是7.99us,远小于8.68us,误差率7.95%

华大HC32L13x 串口波特率设置为115200打印乱码问题_第1张图片

对比9600抓取的可以正常打印的波形,最小脉宽103.83us,误差率不到0.33%

image-20201117215731250

如此对比,发现实测的115200bps和实际配置的差别太远

在HC32L13x用户手册上看到了相关说明,在PCLK=4MHz的条件下说明了各波特率的误差情况(注:PCLK字面意思也就是外设时钟)

华大HC32L13x 串口波特率设置为115200打印乱码问题_第2张图片

另外PCLK=24MHz条件下对各波特率误差就相对友好,居然还有0误差的。

华大HC32L13x 串口波特率设置为115200打印乱码问题_第3张图片

那么问题来了,当前工程配置的PCLK为多少呢,虽然根据表格明显应该是4MHz,查看时钟结构图如下

关注SYSCTRL0寄存器即可,BIT7:5是选择SystemCLK哪个时钟源,BIT10:8选择SystemCLK到HCLK的分频值,BIT12:11选择HCLK到PCLK的分频值

华大HC32L13x 串口波特率设置为115200打印乱码问题_第4张图片

进入Keil仿真,查看SYSCTRL寄存器组,其中SYSCTRL0为0x0000 0001 ,解释为选择内部高速时钟,SystemCLK到HCLK不分频,HCLK到PCLK也不分频,也就是PCLK = RCH。

华大HC32L13x 串口波特率设置为115200打印乱码问题_第5张图片

问题是RCH标称为4M-24M,RCH具体为多少呢,事实上RCH最多为24M也就决定了PCLK最多为24M,(也可选择PLL,可以把RCH倍频上去到48MHz,这样PCLK也可以得到48MHz)

调试-改SystemCLK为RCH 24M

查看main入口前的SystemInit函数

void SystemInit(void)
{
    M0P_SYSCTRL->RCL_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C22ul)));
    M0P_SYSCTRL->RCH_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C08ul)));
    SystemCoreClockUpdate();
	_HidePinInit();
}

uint32_t SystemCoreClock = 4000000;


//add clock source.
void SystemCoreClockUpdate (void) // Update SystemCoreClock variable
{
    SystemCoreClock = Sysctrl_GetHClkFreq();
}

结合下图解释选择的正是4M,要改为24M,直接替换地址

华大HC32L13x 串口波特率设置为115200打印乱码问题_第6张图片改后,跟踪SystemCoreClock的值由4M变为了24M,该值也就是HCLK,也就是PCLK(没有分频)

M0P_SYSCTRL->RCH_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C00ul)));

验证

串口部分确认配置为115200-8-N-1

//串口模块配置
void App_UartCfg(void)
{
    stc_uart_cfg_t  stcCfg;
    stc_uart_baud_t stcBaud;

    DDL_ZERO_STRUCT(stcCfg);
    DDL_ZERO_STRUCT(stcBaud);

    Sysctrl_SetPeripheralGate(SysctrlPeripheralUart0,TRUE); ///<使能UART0外设时钟门控开关
    ///
    stcCfg.enRunMode        = UartMskMode1;                 ///<模式1
    stcCfg.enStopBit        = UartMsk1bit;                  ///<1bit停止位
    stcCfg.enMmdorCk =      UartMskDataOrAddr;                     //无校验
    stcCfg.stcBaud.u32Baud  = 115200;                         ///<波特率115200
    stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div;              ///<通道采样分频配置
    stcCfg.stcBaud.u32Pclk  = Sysctrl_GetPClkFreq();        ///
    Uart_Init(M0P_UART0, &stcCfg);                          ///<串口初始化

    ///
    Uart_ClrStatus(M0P_UART0,UartRC);    //清接收请求
    Uart_ClrStatus(M0P_UART0,UartTC);    //清发送请求
    Uart_EnableIrq(M0P_UART0,UartRxIrq); //使能串口接收中断
    //Uart_EnableIrq(M0P_UART0,UartTxIrq); //使能串口发送中断
    //EnableNvic(UART0_IRQn, IrqLevel3, TRUE);              ///<系统中断使能
}

再次抓取波形,123轻松识别,脉宽8.65us,误差不到0.35%,验证ok

华大HC32L13x 串口波特率设置为115200打印乱码问题_第7张图片

总结

HC32L13x 串口例程PCLK给的是4MHz,默认串口波特率也是9600,要正常使用115200bps通信,需调高PCLK的值。

也许这就是低功耗MCU吧,时钟跑这么低,PLL也不用。

你可能感兴趣的:(华大MCU,串口通信,单片机,stm32,嵌入式,乱码)