CANFD — 经典帧基址 ID 轮询收发 CANFD_Classic_BaseID_polling
固件库: PY32F403_Firmware V1.4.5
芯片: PY32F403(Cortex-M4)⭐ F403 特色外设
源文件:PY32F403-STK/Example/CANFD/CANFD_Classic_BaseID_polling/Src/main.c
核心外设: CANFD(兼容 CAN 2.0B / CAN-FD),PA11/PA12
1. 功能简介(大白话)
这是 F403 特色外设 CANFD 的入门例子。它演示「经典 CAN 帧(非 FD)+ 轮询方式」的收发:
- 把 CANFD 配成经典帧、正常模式、波特率 250Kbps;
- 设置过滤器:只收 ID =
0x12F的报文(标准 11 位 ID); - MCU 自动发一帧 ID=0x123、8 字节数据
{1,2,3,4,5,6,7,8}出去(给 PC 上的 PCAN-View 看); - 然后轮询等待接收 FIFO 有数据,一旦从 PCAN-View 收到 ID=0x12F 的 8 字节,就通过串口
printf把数据打出来。
简单说:MCU 主动发一帧 → PC 收到;PC 手动回一帧 0x12F → MCU 收到并打印。整个过程没有中断,CPU 一直「盯着」接收 FIFO 等数据(轮询)。
2. 硬件准备
| 物品 | 说明 |
|---|---|
| PY32F403-STK 开发板 | 自带 CANFD(PA11/PA12)+ 调试串口 |
| USB 转 CAN 模块 + CAN 转接板 | 接 STK 的 CAN 差分脚 |
| USB 转 TTL 模块 | 接 STK 的 USART2 看 printf |
| PC + PCAN-View 软件 | 收发 CAN 帧 |
CAN 接线(STK → CAN 转接板):
|
|
CAN 转接板 → USB 转 CAN 模块:
|
|
串口接线(看 printf 输出):
|
|
PCAN-View 配置:协议 CAN 2.0,Clock Frequency 20MHz,Nominal Bit Rate 250kBit/s,Data Bit Rate 不设置,Standard。
3. 完整代码(带中文注释)
|
|
附:MSP 里的时钟与引脚配置(HAL_CANFD_Init 自动调用)
|
|
4. 代码分段讲解
4.1 经典帧 vs FD 帧
CANFD_FRAME_CLASSIC = 经典 CAN 2.0,单帧最多 8 字节,仲裁段与数据段同速。若改成 CANFD_FRAME_FD,则数据段可用更高波特率、最大 64 字节(对应 DLCtoBytes 表里 12~64 的值)。
4.2 波特率 250K 是怎么来的?
CAN 时钟 = 20MHz,每个 Tq(时间量子)= Prescaler / 20MHz = 50ns。一位 = (SYNC_SEG=1 + TS1=64 + TS2=16) = 81 个 Tq:
|
|
PUYA 的
SyncJumpWidth/TimeSeg1/TimeSeg2直接以 Tq 个数为单位,所以数值偏大是正常的。FD 帧的DataTimeSeg1/2独立控制数据段更高速率。
4.3 过滤器 MaskID=0 的含义
过滤器只在「收到的 ID 与 FilterID(0x12F) 完全一致」时才放进 RX FIFO(MaskID=0 = 精确匹配)。MCU 自己发出的帧 ID 是 0x123(给 PC 看),而它接收的是 PC 发来的 0x12F——所以 PCAN-View 手动发 0x12F 才会被收下并打印;发别的 ID 会被硬件丢弃。
4.4 发送:PTB + 激活
HAL_CANFD_AddMessageToTxFifo(..., CANFD_TX_FIFO_PTB) 把报文放进优先发送缓冲(PTB),HAL_CANFD_ActivateTxRequest(PTB_SEND) 触发硬件发出。STm32 风格里 TX 要显式「激活请求」。
4.5 接收:轮询 FIFO
__HAL_CANFD_GET_RX_FIFO_FILL_LEVEL 查接收 FIFO 是否为空;非空则 HAL_CANFD_GetRxMessage 取出帧头与数据。因为是轮询,CPU 在 while 里空转等,最简单但占 CPU——想解放 CPU 可换 *_IT(中断)版本。
5. 实验现象
- 烧录复位后,PCAN-View 会立即收到 MCU 发出的 ID=0x123、8 字节
1 2 3 4 5 6 7 8; - 在 PCAN-View 里手动发送 ID=0x12F、8 字节 数据;
- STK 的调试串口(115200)打印:
|
|
(x1~x8 为你从 PCAN-View 发出的数值)
6. 常见问题
| 现象 | 原因 | 解决 |
|---|---|---|
| PCAN-View 收不到 MCU 发的帧 | CANH/CANL 接反 / 没终端电阻 | 确认差分线序;总线两端各 120Ω |
| MCU 串口不打印 | 过滤器 ID 不匹配 | 用 PCAN-View 发 ID=0x12F;不要发别的 |
| 报错误帧/波特率不对 | CAN 时钟或 Bit Timing 错 | 确认 CAN 时钟 20MHz,且 PCAN 配 250K |
| 单板想自测 | 没有第二节点 | 把 Mode 改为 CANFD_MODE_LOOPBACK 内部回环 |
| 想发超过 8 字节 | 用了经典帧 | 改 CANFD_FRAME_FD 并设置 Data 段更高波特率 |
| printf 无输出 | 串口接线/波特率 | PA2→RX、PA3→TX、115200-8-N-1 |
7. 小结
- CANFD 是 F403 特色外设,兼容经典 CAN 2.0B 与 CAN-FD;
- 引脚固定 PA11(RX)/PA12(TX) AF10,时钟由 PLL 分频而来(本例 20MHz);
- 流程:Init → ConfigFilter → Start → AddMessageToTxFifo → ActivateTxRequest → 轮询 Rx;
- 经典帧单帧 ≤8 字节;过滤器
MaskID=0做精确 ID 匹配; - 本例 250K,MCU 发 0x123、收 0x12F 并打印,是 CAN 入门最佳样本。
8. 拓展应用(学了能做什么项目)
- 汽车/工业节点:定义 ID 优先级矩阵,多 ECU 协同;
- 多板互联:用过滤器分组,主节点轮询各从节点传感器;
- 升级 CAN-FD:提高数据段波特率、传 64 字节,做固件 OTA / 图像下发;
- 中断化:参考
CANFD_ExtendedID_IT,收帧即进回调,释放 CPU; - 回环自测:参考
CANFD_ExtendedID_LBMI/LBME_polling,无外设也能验证协议栈; - BMS / 机器人:多电芯电压、关节状态经 CAN 汇总到主控制器。
返回:CANFD 总览