1. 一版板子回来FDCAN 却完全“失声”问题现场还原STM32C092FCP6 这颗料我用了有一阵子了一直以为 FDCAN 的重映射问题只会在别人的帖子里出现。结果这块板子贴片回来第一次上电就给我上了一课代码初始化全走绿HAL_FDCAN_Start返回HAL_OKHAL_FDCAN_AddMessageToTxMailbox也返回HAL_OK可 CAN 总线上连一帧都看不到。做嵌入式的人都知道这种“软件全过、硬件无波”的情况最让人头疼。它不像烧录失败那么明显也不是段错误崩溃那样立刻暴露而是要带着示波器一步步去“捉鬼”。我在这块板上前前后后折腾了大半天最后定位到的问题却是很多人都容易忽视的一个细节FDCAN remapping。1.1 硬件背景与最初的现象先说一下这块板的硬件情况。主控是 STM32C092FCP6TSSOP20 封装LQFP48 开发板上那套外设引脚到了 20 脚封装上会砍掉很多所以引脚分配必须重新设计。CAN 收发器用的是 MCP2562FD一颗 CAN FD 收发器总线侧按标准接了两个 120Ω 终端电阻一个在板子靠近连接器处另一个在对端测试设备里。原本在 NUCLEO-C092RC 开发板上跑 FDCAN 环路测试一切正常发送、接收、错误计数都是干净的。于是我把同一份工程改了一下引脚分配就发出去打样了。结果板子回来刷上程序后接上总线、用另一个节点持续发数据这一端就像完全不存在一样——既不发送也不应答连 ACK 都看不到。我用示波器点开板子到收发器之间的 TXD 引脚电平一直停在隐性高电平连一个下降沿都没有。用逻辑分析仪抓总线CANH/CANL 同样是安静的。当时我心里就咯噔一下这说明 MCU 压根没有把 FDCAN 的发送信号送出来问题出在 MCU 侧而不是总线侧。1.2 快速排除先把锅从硬件外围甩出去遇到 CAN 不出波我的第一反应是查外围而不是查 MCU 配置。这个顺序很重要因为很多人一上来就翻固件最后往往浪费时间其实问题就出在前级信号链路上。我做了这样几件事量收发器的 VCC3.3V 正常量收发器的 STBY 引脚确认芯片不在待机或只听模式量总线上的终端电阻本端 120Ω 正常对端也有 120ΩCANH 与 CANL 之间总阻值约 60Ω符合 ISO 11898 的预期把收发器换了一颗新的现象不变用另一个已知正常的 CAN 节点替换测试现象依旧。到了这一步基本可以确定问题不是出在总线物理层而是出在 MCU 到收发器这一段。也就是说MCU 的引脚根本没有把 FDCAN 信号送出来或者送出来的信号被错误的引脚路由截断了。1.3 决定性的一个细节原理图上接的是哪个引脚排查到这里我重新翻了原理图才发现问题可能出在引脚选型上。PCB 布局时为了走线方便我把 FDCAN1_TX 接到了 PB13FDCAN1_RX 接到了 PB12。而在 NUCLEO 开发板上的测试工程里FDCAN 用的是默认映射组的 PA11/PA12。我最初以为只是 GPIO 配置没改于是在 CubeMX 里把 PB12/PB13 的复用模式、AF 编号都选好了重新生成工程刷进去结果还是没波形。这时候我才隐隐感觉到问题没那么简单很可能 C092 这颗芯片的 FDCAN 引脚不是“配好 GPIO 就能用”的还需要额外的重映射开关。2. FDCAN remapping 到底改了什么C092 的引脚信号路由机制在继续排查之前我先把 C0 系列的引脚信号路由机制讲清楚。因为很多从 F1、F4 转过来的朋友吃的最大的亏就是把“重映射”当成老一套想当然地以为只要 GPIO 配置正确外设就会正常工作。2.1 C0 系列没有 AFIO但 SYSCFG 里藏着重映射开关STM32F1 时代有专门的 AFIO 寄存器用来切换外设引脚。到了 F0/G0/C0 这一代这个功能被并入了 SYSCFG 模块。C0 系列不像 F4 那样每个引脚都是“AF0~AF15 随便选”的通用矩阵而是走了一条介于两者之间的路线部分外设引脚既可以通过 GPIO 的 AF 编号来选择也可以由 SYSCFG_CFGR1 里的外设重映射位来决定最终路由到哪一组引脚。换句话说对一个 FDCAN 引脚C0 上实际存在两层选择第一层GPIO 复用功能配置也就是 MODER 选择复用模式、AFR 选择复用功能编号决定这个引脚作为哪个外设功能组来工作第二层SYSCFG 重映射开关决定外设内部的某个功能信号比如 FDCAN1_TX最终送到哪一组引脚。如果第二层没配置即便你的 GPIO 已经选好了“这个引脚是 FDCAN 的”芯片内部路由也没有把 FDCAN 输出连接到这个引脚上结果就是引脚保持空闲状态自然不来波形。2.2 SYSCFG_CFGR1 里的 FDCAN1_RM 位在 C092 上FDCAN 相关引脚的重映射控制集中在 SYSCFG_CFGR1 寄存器中其中有一个 FDCAN1_RM 位专门用来选择 FDCAN1 的接收/发送信号走哪一组引脚。这个位在参考手册里的定义大致是FDCAN1_RM 0FDCAN1
阅读完成 · 觉得有帮助?