联系管理员

开通文章发布权限

扫码 添加微信
微信图片
电话: QQ:1602036736

关于 G3519 的串口中断异常

问题本质

整个调试过程其实踩了三层独立的坑,每一层都会让 UART7 收不到数据,叠加在一起非常难定位。

第一层:SDK 启动文件向量表缺失(已解决)

SDK 2.05 的 startup_mspm0g351x_ticlang.c 里,UART7(中断号 27)在向量表中对应位置是 0(空)。无论
UART7 收到多少数据,CPU 都不会跳转到 ISR。
解决:升级到 SDK 2.10.00.04,其启动文件正确填入了 UART7_IRQHandler。

第二层:RX 中断未真正使能(已解决)

即使 syscfg 里配了 UART2.enabledInterrupts = ["RX"],UART7 外设的 RX 中断也没被打开。
解决:在 wireless_uart_init() 里手动加 DL_UART_Main_enableInterrupt(UART_WIRELESS_INST,
DL_UART_MAIN_INTERRUPT_RX)。

第三层:FIFO 溢出导致 RX 卡死(最后这个,刚解决)

这是最隐蔽的,也是「AT 命令一生效就收不到数据」的真凶:

  • RF 关闭时,模块只慢速发 RDY,原版 ISR(一次读一个字节)跟得上。

  • RF 连接成功后,dongle 的数据突发高速涌入,RX FIFO 来不及读就溢出(overrun)。

  • 溢出时硬件触发的中断 IIDX 不再是 DL_UART_IIDX_RX,而是 OVERRUN_ERROR。原版 ISR 的判断 if
    (getPendingInterrupt() == DL_UART_IIDX_RX) 不成立 → 不读数据、不清错误 → RX
    通道彻底卡死,再也收不到。

最终解法

  void UART_WIRELESS_INST_IRQHandler(void)
  {
      DL_UART_getPendingInterrupt(UART_WIRELESS_INST);      // 必须保留:清中断标志(含 overrun)
      while (!DL_UART_isRXFIFOEmpty(UART_WIRELESS_INST)) {  // 无条件排空 FIFO,溢出也能恢复
          char ch = DL_UART_Main_receiveData(UART_WIRELESS_INST);
          wireless_rx.buf[wireless_rx.len++] = ch;
          if (wireless_rx.len >= WIRELESS_RX_BUF_MAX - 1) wireless_rx.len = 0;
          debug_uart_send_char(ch);
      }
  }

两个关键点缺一不可:

  1. 保留 getPendingInterrupt() —— 清 IIDX 标志,否则中断永久挂起(我中间删掉它那次就是这个错)。

  2. while 循环排空 FIFO —— 不再只认 RX 中断源,无论溢出与否都把数据全读走,让 RX 自动恢复。

    AT 命令则用最简单的「只发不等」(wireless_uart_send_string),模块返回的 OK 由这个加固后的 ISR
    自动回显。

    一句话总结

    根因是中断服务函数没有处理 FIFO 溢出:低速场景能跑,一旦 RF 连上数据变快就溢出卡死。把 ISR
    改成「清标志 + 循环排空 FIFO」后,高速数据也能稳定接收。

评论

快捷导航

把好文章收藏到微信

打开微信,扫码查看

关闭

还没有账号?立即注册