[技术支持] hc32L110串口只能发送不能接收

[复制链接]
7905|7
 楼主| pm1231 发表于 2025-5-14 17:09 | 显示全部楼层 |阅读模式
代码如下,是从官方例程改的,引脚换成了23,24,现象是串口能够发送,但是好像进不去
回调函数,里面的亮灯操作不会执行。

uint8_t u8RxData[2]={0x55,0x00};
uint8_t volatile u8Rx**=0;
uint8_t Check**=0;


void RxIntCallback(void)
{
    u8RxData[1]=M0P_UART1->SBUF;
        u8Rx** = 1;
//        Uart_SendData(UARTCH1,u8RxData[0]);
        Gpio_SetIO(0,2,FALSE);
}

void ErrIntCallback(void)
{
        Uart_SendData(UARTCH1,0xaa);
}

void uart_init(void)
{
    uint16_t timer=0;
    uint32_t pclk=0;
       
        stc_uart_config_t                          stc_uart_config;              //uart 总体配置
        stc_uart_irq_cb_t                         stc_uart_irq_cb;              //uart发送接收中断处理函数接口
        stc_uart_multimode_t                 stc_uart_multimode;           //uart多主机模式及从机地址和地址掩码配置
        stc_uart_baud_config_t                 stc_uart_baud_config;         //uart 通道波特率配置

        stc_bt_config_t                         stc_bt_config;                                        //Timer 配置结构体定义
   

        //重置结构体
        DDL_ZERO_STRUCT(stc_uart_irq_cb);
        DDL_ZERO_STRUCT(stc_uart_multimode);
        DDL_ZERO_STRUCT(stc_uart_baud_config);
        DDL_ZERO_STRUCT(stc_bt_config);
        timer=0;
        pclk=0;
       
        Gpio_InitIOExt(2,3,GpioDirOut,FALSE, FALSE,FALSE,FALSE);//P35  输出 上拉 不下拉 不开漏 高驱动
        Gpio_InitIOExt(2,4,GpioDirOut,FALSE, FALSE,FALSE,FALSE);//P35  输入 上拉 不下拉 不开漏 高驱动
       
        // Gpio_SetFunc_UART1TX_P35();
        // Gpio_SetFunc_UART1RX_P36();
        Gpio_SetFunc_UART1TX_P23();
        Gpio_SetFunc_UART1RX_P24();
       
       
        Clk_SetPeripheralGate(ClkPeripheralBt,TRUE);//模式0/2可以不使能
    Clk_SetPeripheralGate(ClkPeripheralUart1,TRUE);
       
        stc_uart_irq_cb.pfnRxIrqCb = RxIntCallback;                        //接收中断回调
    stc_uart_irq_cb.pfnTxIrqCb = NULL;                                                                //发送中断回调
    stc_uart_irq_cb.pfnRxErrIrqCb = ErrIntCallback;        //接收错误中断回调
    stc_uart_config.pstcIrqCb = &stc_uart_irq_cb;                                        //中断服务函数结构体
    stc_uart_config.bTouchNvic = TRUE;                                                                        //中断使能
       
        stc_uart_config.enRunMode = UartMode1;                                                        //测试项,更改此处来转换4种模式测试       
        stc_uart_multimode.enMulti_mode = UartNormal;                                                //测试项,更改此处来转换多主机模式,mode2/3才有多主机模式
    stc_uart_config.pstcMultiMode = &stc_uart_multimode;                                        //多机模式配置
       
        stc_uart_baud_config.bDbaud = 0u;                               
        stc_uart_baud_config.u32Baud = 9600u;               
        stc_uart_baud_config.u8Mode = UartMode1;
    pclk = Clk_GetPClkFreq();                                //获得外设时钟(PCLK)频率值
    timer=Uart_SetBaudRate(UARTCH1,pclk,&stc_uart_baud_config);//UART通道波特率配置
       
        stc_bt_config.enMD = BtMode2;                        //定时器工作模式自动重装载16位计数器
    stc_bt_config.enCT = BtTimer;                        //定时器功能
    Bt_Init(TIM1, &stc_bt_config);                //调用basetimer1设置函数产生波特率
    Bt_ARRSet(TIM1,timer);                                        //重装载值配置
    Bt_Cnt16Set(TIM1,timer);                                //16位计数器初始值设置
    Bt_Run(TIM1);
       
        Uart_Init(UARTCH1, &stc_uart_config);                                //通道初始化
    Uart_EnableIrq(UARTCH1,UartRxIrq);                //UART通信中断使能
    Uart_ClrStatus(UARTCH1,UartRxFull);                //UART通道通信状态清除
    Uart_EnableFunc(UARTCH1,UartRx);                        //UART通道发送或接收使能设置
        Uart_EnableFunc(UARTCH1,UartTx);       

}

void LED_init(void)
{
        //GPIO输出
    Gpio_InitIOExt(0, 2, GpioDirOut, TRUE, FALSE, TRUE, FALSE);
        Gpio_SetIO(0,2,TRUE);
}

int32_t main(void)
{  

        uart_init();
        LED_init();
       
    while(1)
        {
                Check** = 0;
//                Gpio_SetIO(0,2,TRUE);
                if(u8Rx**)
                {
                        u8Rx** = 0;
//                        if(Uart_CheckEvenOrOdd(UARTCH1,Even,u8RxData[1])!=Ok)
//                        {
//                                Check** = 1;//奇偶校验出错
//                        }
//                        else
                        {
//                                Uart_SetTb8(UARTCH1,Even,u8RxData[0]);
                                Uart_SendData(UARTCH1,u8RxData[0]);                               
//                                Uart_SetTb8(UARTCH1,Even,u8RxData[1]);
                                Uart_SendData(UARTCH1,u8RxData[1]);
                        }
                }
                Uart_SendData(UARTCH1, u8RxData[1]);
                delay1ms(1000);
//                Gpio_SetIO(0,2,FALSE);
//                delay1ms(1000);
        }
}

评论

您好,你解决问题了吗,我使用的是串口0,用P15 P14口,配置也没有成功  发表于 2025-5-22 10:54
地瓜patch 发表于 2025-5-24 22:27 来自手机 | 显示全部楼层
一般用中断接收
zhouyong77 发表于 2025-5-26 07:55 来自手机 | 显示全部楼层
仿真单步跟踪一下代码
daichaodai 发表于 2025-5-26 08:07 来自手机 | 显示全部楼层
这个回调函数是在哪里被调用的?
tpgf 发表于 2025-5-26 13:13 | 显示全部楼层
如果使用定时器驱动串口接收,需确保定时器正确配置并启动,且定时器中断优先级低于RX中断
sunjd 发表于 2025-11-4 14:15 | 显示全部楼层
调试建议
检查引脚映射:确认P23/P24确实支持UART1功能
添加调试输出:在主循环中添加LED闪烁,确认程序在运行
检查波特率:用示波器测量TX引脚,确认波特率确实是9600
检查中断优先级:确保UART中断优先级设置正确
修改建议
uint8_t u8RxData[2] = {0x55, 0x00};
uint8_t volatile u8RxFlag = 0;  // 修改变量名
uint8_t CheckFlag = 0;          // 修改变量名

void RxIntCallback(void)
{
    u8RxData[1] = M0P_UART1->SBUF;  // 读取接收数据
    u8RxFlag = 1;                   // 设置接收标志
    Gpio_SetIO(0, 2, FALSE);        // 亮灯指示接收
}

void ErrIntCallback(void)
{
    Uart_SendData(UARTCH1, 0xAA);   // 发送错误标志
    // 清除错误状态
    Uart_ClrStatus(UARTCH1, UartFrameErr | UartParityErr | UartOverrunErr);
}

void uart_init(void)
{
    stc_uart_config_t stc_uart_config;
    stc_uart_irq_cb_t stc_uart_irq_cb;
    stc_uart_multimode_t stc_uart_multimode;
    stc_uart_baud_config_t stc_uart_baud_config;
    stc_bt_config_t stc_bt_config;

    // 重置结构体
    DDL_ZERO_STRUCT(stc_uart_irq_cb);
    DDL_ZERO_STRUCT(stc_uart_multimode);
    DDL_ZERO_STRUCT(stc_uart_baud_config);
    DDL_ZERO_STRUCT(stc_bt_config);

    // GPIO初始化 - 确保引脚配置正确
    Gpio_InitIOExt(2, 3, GpioDirOut, FALSE, FALSE, FALSE, FALSE);
    Gpio_InitIOExt(2, 4, GpioDirOut, FALSE, FALSE, FALSE, FALSE);
   
    // 设置UART引脚功能
    Gpio_SetFunc_UART1TX_P23();
    Gpio_SetFunc_UART1RX_P24();
   
    // 使能外设时钟
    Clk_SetPeripheralGate(ClkPeripheralBt, TRUE);
    Clk_SetPeripheralGate(ClkPeripheralUart1, TRUE);

    // 配置中断回调
    stc_uart_irq_cb.pfnRxIrqCb = RxIntCallback;
    stc_uart_irq_cb.pfnTxIrqCb = NULL;
    stc_uart_irq_cb.pfnRxErrIrqCb = ErrIntCallback;
    stc_uart_config.pstcIrqCb = &stc_uart_irq_cb;
    stc_uart_config.bTouchNvic = TRUE;
   
    stc_uart_config.enRunMode = UartMode1;
    stc_uart_multimode.enMulti_mode = UartNormal;
    stc_uart_config.pstcMultiMode = &stc_uart_multimode;

    // 波特率配置
    stc_uart_baud_config.bDbaud = 0u;
    stc_uart_baud_config.u32Baud = 9600u;
    stc_uart_baud_config.u8Mode = UartMode1;
   
    uint32_t pclk = Clk_GetPClkFreq();
    uint16_t timer = Uart_SetBaudRate(UARTCH1, pclk, &stc_uart_baud_config);

    // 定时器配置
    stc_bt_config.enMD = BtMode2;
    stc_bt_config.enCT = BtTimer;
    Bt_Init(TIM1, &stc_bt_config);
    Bt_ARRSet(TIM1, timer);
    Bt_Cnt16Set(TIM1, timer);
    Bt_Run(TIM1);

    // UART初始化
    Uart_Init(UARTCH1, &stc_uart_config);
   
    // 关键步骤:确保接收相关配置正确
    Uart_ClrStatus(UARTCH1, UartRxFull | UartRxErrAll);  // 清除所有接收状态
    Uart_EnableIrq(UARTCH1, UartRxIrq);                  // 使能接收中断
    Uart_EnableIrq(UARTCH1, UartRxErrIrq);               // 使能接收错误中断
    Uart_EnableFunc(UARTCH1, UartRx);                    // 使能接收功能
    Uart_EnableFunc(UARTCH1, UartTx);                    // 使能发送功能
}

int32_t main(void)
{  
    uart_init();
    LED_init();
   
    // 发送测试数据,确认发送功能正常
    Uart_SendData(UARTCH1, 0xAA);
    delay1ms(100);
    Uart_SendData(UARTCH1, 0x55);
   
    while(1)
    {
        if(u8RxFlag)
        {
            u8RxFlag = 0;
            // 收到数据后回传
            Uart_SendData(UARTCH1, u8RxData[1]);
            
            // 根据接收到的数据控制LED
            if(u8RxData[1] == 0xAA) {
                Gpio_SetIO(0, 2, TRUE);   // 灯灭
            } else {
                Gpio_SetIO(0, 2, FALSE);  // 灯亮
            }
        }
        
        // 定期发送心跳包,便于调试
        static uint32_t counter = 0;
        if(counter++ > 1000000) {
            counter = 0;
            Uart_SendData(UARTCH1, 0x5A);  // 发送心跳
        }
    }
}
简化测试:先只测试接收功能,注释掉发送部分
玛尼玛尼哄 发表于 2025-11-14 17:34 | 显示全部楼层
HC32L110 串口 “只能发送不能接收” 是很常见的问题,核心排查方向集中在 硬件接线、引脚配置、串口参数匹配、接收中断 / 缓冲区、时钟配置 这 5 个维度。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

1

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部