使用AEK-MCU-C4MLT1与SPC5 Studio无法读取串口消息的问题
串口接收问题解决方案
核心问题分析
你的代码存在几个关键问题导致接收失败:
- 接收中断回调函数
rxreceive未实现数据读取逻辑,中断触发后没有将硬件FIFO的数据转移到用户缓冲区 - 调用
sd_lld_read后立即用memset清空了接收缓冲区,即使有数据也被清零 - 串口驱动的中断回调未正确关联到驱动实例
具体修复步骤
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
相关产品推荐
相关产品推荐

