You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用AEK-MCU-C4MLT1与SPC5 Studio无法读取串口消息的问题

串口接收问题解决方案

核心问题分析

你的代码存在几个关键问题导致接收失败:

  1. 接收中断回调函数rxreceive未实现数据读取逻辑,中断触发后没有将硬件FIFO的数据转移到用户缓冲区
  2. 调用sd_lld_read后立即用memset清空了接收缓冲区,即使有数据也被清零
  3. 串口驱动的中断回调未正确关联到驱动实例

具体修复步骤

1. 完善接收中断回调函数

中断触发时必须读取硬件寄存器中的数据,否则数据会丢失,同时处理接收完成逻辑:

void rxreceive(SerialDriver *sdp) {
    // 读取硬件FIFO数据到用户缓冲区
    size_t bytes_read = sd_lld_read(sdp, (uint8_t*)aux_rx, sizeof(aux_rx) - 1);
    if (bytes_read > 0) {
        // 添加字符串结束符,方便后续处理
        aux_rx[bytes_read] = '\0';
        // 可添加数据接收反馈,比如翻转LED
        pal_togglepad(PORT_F, 9);
    }
}

2. 修正主函数逻辑

移除过早的缓冲区清空操作,同时在串口启动前绑定回调函数:

int main(void) {
    componentsInit();
    irqIsrEnable();

    // 关联串口回调函数(关键步骤,之前遗漏)
    serial_config_UART.sd_rx_callback = rxreceive;
    serial_config_UART.sd_tx_callback = txreceive;

    sd_lld_start(&SD1, &serial_config_UART);

    // 初始化接收缓冲区
    memset(aux_rx, 0, sizeof(aux_rx));

    for ( ; ; ) {
        sprintf(aux_tx, "ATE1\r\n");
        sd_lld_write(&SD1, (uint8_t *)aux_tx, (uint16_t)strlen(aux_tx));
        osalThreadDelayMilliseconds(5000);

        // 主循环中检查并处理接收数据
        if (strlen(aux_rx) > 0) {
            // 示例:回发接收到的内容
            sd_lld_write(&SD1, (uint8_t *)aux_rx, (uint16_t)strlen(aux_rx));
            // 处理完成后清空缓冲区
            memset(aux_rx, 0, sizeof(aux_rx));
        }
    }
}

3. 确认串口配置完整性

确保serial_config_UART开启了接收中断,参数与Docklight匹配:

static const SerialConfig serial_config_UART = {
    .speed = 9600,  // 与Docklight波特率保持一致
    .cr1 = 0,
    .cr2 = USART_CR2_RE | USART_CR2_TE | USART_CR2_RXNEIE,  // 开启接收中断
    .cr3 = 0
};

关键说明

  • 中断回调必须实现数据读取,否则硬件接收FIFO满后会触发溢出,数据丢失
  • 串口驱动启动前必须绑定回调函数,否则中断触发后不会执行你的rxreceive逻辑
  • 中断函数中避免执行耗时操作,复杂的数据处理放在主循环中完成

内容的提问来源于stack exchange,提问作者Simone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 21:10:27