mokongking

关于CAN的理解

CAN分为两种,经典CAN CANFD:

这个只讲CAN :

1、硬件层面需要配置哪些:

  1. 开 GPIO AF、CAN 时钟、收发器相关脚
  2. can_deinit → 进初始化模式
  3. 配波特率、正常模式
  4. 配过滤器(本机 ID)
  5. 使能 FIFO 非空中断

经典 CAN(CAN 2.0,如GD32F10x 这类):一帧最多 8 字节数据(DLC = 0~8)。

CAN FD:一帧最多 64 字节(DLC 可表示 12/16/20/24/32/48/64)。

CAN每一帧 ID、DLC、≤8 字节都是这个格式

软件需要人为协商协议具体如下

谁是主机谁从机
上位机发命令,转台应答  
命令用哪个 ID,应答用哪个 ID
命令 0x200,应答 0x201
标准帧还是扩展帧
一般 11 位标准帧
8 字节怎么用
[or_code][参数…] 还是 ID 即命令
短帧 / 分包格式
SF=0x0n,FF=0x10,CF=0x2s(人为定义的01代表包0,2代表包2,为了防止丢包可以一问一答,主要控制时序,这个01包0的是在数据种展现can的头尾都没有变化都是硬件生成)
字节序
or_code 高字节在前还是低字节
命令码含义
0x000C=绝对运动(可直接用你现有 cmd.h)
应答规则
应答码 = 命令+1 变奇数人为规定的id的应答码
超时、重发
100ms 无 CF 丢包;主机是否重发
长包上限
最大 256 字节等这个是整个数据的长度,知道多长证明是否接收完毕

 

 

过滤器里填的 ID,来自你们约定的 ID,但「过滤功能本身」是配置。

具体的can的时序如下,当上下位机定好了协议:

看下位机应答:

得有发送队列,接收队列,因为can一帧就能发8个字节,固定死的,发完8个字节进入can_rx的硬件中断,而且can,接收fifo有两个,过滤器可以把不同 ID 分到 FIFO0 或 FIFO1,所以是 两路接收队列每路大约能缓存 3 帧

  • 开 CAN、波特率
  • 配 过滤器:哪些 ID 进 FIFO0,哪些进 FIFO1
  • 开 FIFO 非空中断(或轮询)

读出来的数据放到接收队列,开启一个任务,根据上位机下位机定制的协议进行拼包,拼完一整包数据后再解析命令。再拼包的时候如果上位机发送过快可能有丢包,可以采用一问一答,或者让上位机控制时序,间隔多长时间给你发一包,或者怎末队列深度从只能存5个到存16个

发送的话呢,进行拆包,拆成一帧帧的数据后,写入发送队列,取一帧,调用 can_message_transmit(),返回值会告诉用的哪个邮箱,硬件发送有3个邮箱,发送最好一帧一帧发,避免 3 邮箱一起挂着时按 ID 优先级打乱顺序,一次只提交一帧到邮箱,发完再发下一帧。

上下危机要约定的是:哪些 ID 给紧急、哪些给普通(例如心跳/急停用小 ID,普通命令用大 ID)。一定要注意,既有区分命令类型的作用又有优先级的作用

 

CAN 的 ID 同时干两件事:

 

  1. 含义 / 路由——表示这是哪类消息、给谁(过滤、主机从机认帧都靠它)
  2. 优先级——抢总线时,ID 越小越优先发

 

ID 优先级是 CAN 总线仲裁规则:多节点同时想发时,ID 更小的先获得总线(显性位优先)。

插头经常都是 USB;出现 COM 口 就用 serial;USB-CAN 多数用 厂家 CAN 库(少数做成虚拟串口才用 serial)。下位机是 USART 还是 CAN,和上位机选哪个库是对齐的

posted on 2026-09-16 18:25  虎啸岳林  阅读(10)  评论(0)    收藏  举报

导航