打印
[技术问答]

HC32L110使用低功耗串口输出打印乱码问题

[复制链接]
1621|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 JacksonChen 于 2024-11-7 16:38 编辑

通过串口调试助手可以知道printf函数能够正常输出打印语句,但是中断接收会出现数据乱码情况,使用的是38400时钟频率,波特率为9600,以下是代码:

------------------------------------------------------------------------------------------------------------------------------------

#include "ddl.h"        //驱动头文件
#include "lpuart.h"        //低功耗串口头文件
#include "bt.h"                //中断时钟头文件
#include "lpm.h"        //低功耗模式头文件
#include "gpio.h"        //IO口头文件
#include "clk.h"        //时钟头文件
#include "stdio.h"

extern uint8_t u8RxData[RX_BUFFER_SIZE];
extern uint8_t u8Rx**;
extern uint8_t lpuart_rx_head;
extern uint8_t lpuart_rx_tail;

void RxIntCallback(void)
{
        u8Rx** = 1;//接收完整数据标志
        
        // 接收数据  
    u8RxData[lpuart_rx_head] = M0P_LPUART->SBUF;
      
    // 更新头指针  
    lpuart_rx_head = (lpuart_rx_head + 1) % RX_BUFFER_SIZE;  // 使用模运算防止溢出  
      
    // 清中断标志位  
    LPUart_ClrStatus(LPUartRxFull);  
}

void ErrIntCallback(void)
{
        LPUart_ClrStatus(LPUartRFRAMEError);//帧错误标记
}

en_result_t My_LPUart_Init(void)
{
    stc_lpuart_config_t                  stcConfig;                //串口整体配置结构体
    stc_lpuart_irq_cb_t                 stcLPUartIrqCb;        //串口中断回调函数结构体
    stc_lpuart_multimode_t                 stcMulti;                //串口多主机模式函数结构体
    stc_lpuart_sclk_sel_t                  stcLpuart_clk;        //串口时钟配置结构体
        stc_lpuart_mode_t                         stcRunMode;                //低功耗模式配置结构体
//        stc_lpuart_baud_config_t        stcBaud;                //波特率配置结构体
    stc_bt_config_t                         stcBtConfig;        //基本定时器配置结构体
        stc_lpm_config_t                         stcLpmCfg;                //低功耗配置
        
        lpuart_rx_head = lpuart_rx_tail = 0;

        memset(u8RxData , 0 , sizeof(u8RxData));
   
        //清空数据函数
        DDL_ZERO_STRUCT(stcConfig);
    DDL_ZERO_STRUCT(stcLPUartIrqCb);
    DDL_ZERO_STRUCT(stcMulti);
//    DDL_ZERO_STRUCT(stcBaud);
    DDL_ZERO_STRUCT(stcBtConfig);
        DDL_ZERO_STRUCT(stcLpmCfg);
        
    stcLpmCfg.enSLEEPDEEP = SlpDpDisable;//SlpDpEnable;//
    stcLpmCfg.enSLEEPONEXIT = SlpExtDisable;//唤醒后不自动进入睡眠
        
        Clk_Enable(ClkRCL, TRUE);
    Clk_SetRCLFreq(ClkFreq38_4K);//内部38.4K
        
    //外设时钟使能
    Clk_SetPeripheralGate(ClkPeripheralLpUart,TRUE);//使能LPUART时钟
    Clk_SetPeripheralGate(ClkPeripheralBt,TRUE);
        
    //通道端口配置
    Gpio_InitIOExt(3,3,GpioDirIn,TRUE,FALSE,FALSE,FALSE);        //配置33引脚为输入模式RX
        Gpio_InitIOExt(3,4,GpioDirOut,TRUE,FALSE,FALSE,FALSE);        //配置34引脚为输出模式TX
   
        //拉低BRTS电平
        Gpio_InitIOExt(2,5,GpioDirOut,TRUE,FALSE,FALSE,FALSE);
        Gpio_SetIO(2,5,0);
        
    Gpio_SetFunc_UART2RX_P33();
    Gpio_SetFunc_UART2TX_P34();

        //低功耗时钟配置
        stcLpuart_clk.enSclk_sel = LPUart_Rcl;        //LPUart_Pclk;//时钟源选择
        stcLpuart_clk.enSclk_Prs = LPUartDiv1;        //分频选择
        stcConfig.pstcLpuart_clk = &stcLpuart_clk;
        
        stcRunMode.enLpMode = LPUartLPMode;//LPUartNoLPMode;//非低功耗或低功耗模式选择
        stcRunMode.enMode   = LPUartMode1;//工作模式选择
    stcConfig.pstcRunMode = &stcRunMode;
        
    stcLPUartIrqCb.pfnRxIrqCb = RxIntCallback;
    stcLPUartIrqCb.pfnTxIrqCb = NULL;
    stcLPUartIrqCb.pfnRxErrIrqCb = NULL;//ErrIntCallback;
        stcConfig.pstcIrqCb = &stcLPUartIrqCb;
    stcConfig.bTouchNvic = TRUE;
        
    stcMulti.enMulti_mode = LPUartNormal;//mode2/3才有多主机模式
    stcConfig.pstcMultiMode = &stcMulti;
        
    LPUart_EnableIrq(LPUartRxIrq);
        LPUart_Init(&stcConfig);
        
        Gpio_InitIO(0,3,GpioDirOut);
        
        LPUart_EnableFunc(LPUartRx);


#if 0
    while(1 == Gpio_GetIO(T1_PORT,T1_PIN));//注意:此处用户不能屏蔽,否则进入深度休眠模式导致SWD连接不上
    Lpm_Config(&stcLpmCfg);
    Lpm_GotoLpmMode();
#endif

        return Ok;
}

int32_t main(void)
{
        char buffer[RX_BUFFER_SIZE + 1];
        uint8_t length = 0;
        
        My_LPUart_Init();
        
        printf("Init succeed!\r\n");
        
    while(1)
        {      
                if(lpuart_rx_tail != lpuart_rx_head)
                {
                        //计算可读数据的长度
            length = (lpuart_rx_head >= lpuart_rx_tail) ?
                                                (lpuart_rx_head - lpuart_rx_tail) : (RX_BUFFER_SIZE - lpuart_rx_tail + lpuart_rx_head);
            
            //将可读数据复制到临时缓冲区,并添加字符串结束符
            memcpy(buffer, &u8RxData[lpuart_rx_tail], length);
            buffer[length] = '\0';
            
            //打印接收到的数据
            printf("Received data: %s\r\n", buffer);
            
            //更新尾指针
            lpuart_rx_tail = (lpuart_rx_tail + length) % RX_BUFFER_SIZE;
            
                }

                delay1ms(500);
        }
}

使用特权

评论回复
沙发
JacksonChen|  楼主 | 2024-11-7 15:48 | 只看该作者
本帖最后由 JacksonChen 于 2024-11-7 15:50 编辑

串口调试助手里面接收和发送的内容如下:
--------------------------------------------------------------接收数据---------------------------------------------------------------------------
Init succeed!

Received data: n骥

Received data: n鲼

Received data: l铟

---------------------------------------------------------------发送数据------------------------------------------------------------------------------
123

85114672c6fc2ac3cd.png (12.86 KB )

85114672c6fc2ac3cd.png

使用特权

评论回复
板凳
JacksonChen|  楼主 | 2024-11-7 16:10 | 只看该作者
而且还有一个不太明白的现象,这些大部分代码是在例程上面copy的,但是呢他这里面是没有配置到波特率参数的,是默认9600吗?小白求解

使用特权

评论回复
地板
xionghaoyun| | 2024-11-8 09:39 | 只看该作者
看得晕

使用特权

评论回复
5
wubangmi| | 2024-11-8 17:50 | 只看该作者
JacksonChen 发表于 2024-11-7 16:10
而且还有一个不太明白的现象,这些大部分代码是在例程上面copy的,但是呢他这里面是没有配置到波特率参数的 ...

手册看的不仔细了吧
根据手册的公式:LPUART的时钟选择了RCL=38400,分频系数为1(默认)的情况下,波特率=38400/(1*4)=9600。

至于打印的乱码,那是你转义错误了吧,你直接输出打印%d试试。

123.jpg (212.04 KB )

123.jpg

使用特权

评论回复
6
JacksonChen|  楼主 | 2024-11-11 14:11 | 只看该作者
本帖最后由 JacksonChen 于 2024-11-11 14:12 编辑
wubangmi 发表于 2024-11-8 17:50
手册看的不仔细了吧
根据手册的公式:LPUART的时钟选择了RCL=38400,分频系数为1(默认)的情况下,波特率=3 ...

原来波特率是在LPMODE=1时计算出来啊,谢谢大佬。
关于转义错误的问题,我刚刚试了一下%d打印出来,他打印出来的这串数字具体是什么意思啊,求解

使用特权

评论回复
7
wubangmi| | 2024-11-11 15:04 | 只看该作者
用计算器尝试了下转化你的这个10进制的值,如图
从这个值来看,你打印的是存放你接到数据的地址而不是数据本身。

123.jpg (110.27 KB )

123.jpg

使用特权

评论回复
8
JacksonChen|  楼主 | 2024-11-11 17:34 | 只看该作者
wubangmi 发表于 2024-11-11 15:04
用计算器尝试了下转化你的这个10进制的值,如图
从这个值来看,你打印的是存放你接到数据的地址而不是数据 ...

原来是这样,这个跟我在debug看到的地址是一样的,谢谢你

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

24

帖子

0

粉丝