CAN通信笔记
CAN(Controller Area Network Bus),控制局域网总线。
基本特征
-
两根通信线(CAN_H、CAN_L),无需共地
-
差分信号通信,抗干扰能力强
-
高速CAN(ISO11898):125k~1Mbps,<40m
-
低速CAN(ISO11519):10k~125kbps,<1km
-
异步,无需时钟线,通信速率由双方协定
-
半双工,可挂载多设备,多设备同时发送通过仲裁判断先后
-
11/29位报文ID,用于区分消息功能,同时决定优先级**(小的优先)**
-
可配置1~8字节的有效载荷
-
可实现广播式和请求式两种传输
-
应答、CRC校验、位填充、位同步、错误处理等特性
硬件电路

两个终端电阻的意义
-
防止回波反射
-
没有设备操作时,将两根差分线电压“收紧”,使其电压一致
(高速CAN的电阻阻值小,所以收紧更快,但能耗更大)
电平标准
CAN总线使用差分信号,即(Vcan_H - Vcan_L)
- 高速CAN规定
电压差为0V表示逻辑1(隐性电平)
电压差为2V表示逻辑0(显性电平)
- 低速CAN规定
电压差为-1.5V表示逻辑1(隐性电平)
电压差为3V表示逻辑0(显性电平)
位填充
规则:发送方连续发送5个相同电平后,自动追加一个相反电平的填充位;接收方检测到填充位时,会自动移除,恢复原始数据。
例如:
即时发送: 100000110 10000011110
实际发送: 1000001110 1000001111100
实际接收: 1000001110 1000001111100
移除填充: 100000110 10000011110
位填充的作用:
- 增加波形的定位信息,利于接收方执行“再同步”,防止波形长时间无变化,当只接收方不能精准掌握数据采样时机
- 将正常数据流与“错误帧”、“过载帧”区分开
- 保持CAN总线在发送正常数据流时的活跃状态,防止被总线误认为空闲
帧格式
| 帧类型 | 用途 |
|---|---|
| 数据帧 | 发送设备主动发送数据 |
| 遥控帧 | 接收设备主动请求数据 |
| 错误帧 | 某个设备检测出错误时向其他设备通知错误 |
| 过载帧 | 接收设备通知其尚未做好接收准备 |
| 帧间隔 | 用于将数据帧及遥控帧与前面的帧分隔开 |
帧ID值越小,优先级越高
数据帧

SOF(Start of Frame):帧起始,表示后面一段波形是传输的数据位
ID(Identify):标识符,区分功能,决定优先级
RTR(Remote Transmission Request):数据帧(0),遥控帧(1)。
IDE(Identifier Extension):用于区分标准格式(0)和扩展格式(1)
r0/r1(Reserve):保留位,为后续留空间
DLC(Data Length Code):数据长度
ACK槽,发送方(1),接收方(0),如果没有接收方就(1),告知发送方
ACK槽允许多个接收方共同拉开总线
SRR:替代RTR的位,用于保证标准格式高于扩展格式的优先级
EOF(End of Frame):帧结束,表示传输完毕
Q:为什么DLC是4位,但可以描述0-64个Byte?
0-8 对应 0-8Byte
9-15 分别对应 12、16、20、24、32、58、64Byte
遥控帧
遥控帧无数据段,RTR为隐形电平1,其他部分与数据帧相同

错误帧
总线上所有设备都会监督总线数据,一旦发现“位错误”、“填充错误”、“CRC错误”、“格式错误”、“应答错误”,这些设备就会发出错误帧来破坏数据,同时终止当前的发送设备。

- 主动错误会破坏别人的,被动错误会破坏自己的
过载帧
接收方收到大量数据而无法处理时,其可以发出过载帧,延缓发送方的数据发送,以平衡总线负担,避免数据丢失。

帧间隔
在 CAN 总线上,每一帧报文(数据帧、远程帧、错误帧、过载帧)结束之后,不会立刻开始下一帧,中间必须插入一段 固定格式的空隙,这就是 帧间隔。固定是3个隐性“1”。

位同步
-
CAN总线没有时钟线,总线上所有设备通过约定波特率来确定每一位数据位时长
-
发送方以约定的位时长,每隔固定时间输出一个数据位
-
接收方以约定的位时长,每隔固定时间采样总线的电平,输入一个数据位
-
理想状态下,接收方能依次采样到发送方发出的每个数据位,且采样点位于数据位中心附近
位时序
为了能够灵活调整每个采样点的位置,使采样点对齐数据位中心附近,CAN总线对每一个数据位的时长进行更细划分,分为同步段(SS)、传播时间段(PTS–Propagation Time Segement)、相位缓冲段1(PBS1)和相位缓冲段2(PBS2),每隔段由若干个最小时间单位(Tq)构成
- SS = 1Tq
- PTS = 1 ~ 8 Tq
- PBS1 = 1 ~ 8 Tq
- PBS2 = 2 ~ 8 Tq

最开始就没有同步时序。
硬同步(初始位置同步)
每个设备都有一个位时序计时周期,当某个设备(发送方)率先发送报文,其他所有设备(接收方)收到SOF的下降沿时,接收方会将自己的位时序计时周期拨到SS段,与发送方的位时序计时周期保持同步;
硬同步只在第一个下降沿(SOF下降沿)有效;
经过硬同步后,若发送方和接收方的时钟几乎没有误差,则后续所有数据位的采样点必然都会对齐数据位中心附近

最开始接收采样正确,但仍有误差,随着误差积累,采样点逐渐偏离。
再同步
- 若发送方或接收方的时钟有误差,随着误差积累,数据位边沿逐渐偏离SS段,则此时接收方根据再同步补偿宽度(SJW)通过加长PBS1段,或缩短PBS2段,调整同步
- 再同步可以发生在每一个下降沿之后的每个数据位跳变边沿
SJW = 1 ~ 4 Tq
如果误差值小于等于SJW指定值,则误差几个Tq,补偿几个Tq,否则补偿SJW
SJW是补偿的上限,防止波形中的噪声对位时序造成过大影响。

波特率的计算
波特率 = 1 / (一个数据位的时长) = 1 / (Tss + Tpts + Tpbs1 + Tpbs2)
举例
SS = 1 Tq,PTS = 3 Tq,PBS1 = 3 Tq,PBS2 = 3 Tq;Tq = 0.5 us
波特率 = 1 / (0.5us + 1.5us + 1.5us + 1.5us) = 200kbps
仲裁
CAN总线只有一对差分信号线,同一时间只能有一个设备操作总线发送数据,如果多个设备同时有发送需求,该如何分配?
规则1——先占先得
-
若当前已经有设备操作总线发送数据帧/遥控帧,则其他任何设备不能再同时发送数据帧/遥控帧(可以发送错误帧/过载帧破坏当前数据)
-
任何设备检测到连续11个隐性电平(帧间隔),即认为总线空闲,只有总线空闲,设备才可以发送数据帧/遥控帧
-
一旦有设备正在发送数据帧/遥控帧,总线就会变活跃状态,必然不会出现连续11个隐性电平(连续6个就是错误帧/过载帧),其他设备自然也不会破坏当前发送
-
若总线活跃,其他设备有发送需求,则需要等待总线变空闲,才能执行发送需求
规则2——非破坏性仲裁
根据ID号(仲裁段)进行非破坏性仲裁,ID号小的取到总线控制权,ID号大的仲裁失利将转为接收状态,等待下一次总线空闲时再尝试发送。
实现非破坏性仲裁两个要求:
-
线与特性:总线上任何一个设备发送显性电平0时,总线就会呈现显性电平0,只有当所有设备都发送隐性电平1时,总线才会呈现隐性电平1;即0 & X = 0, 1 & 1 = 1.
-
回读机制:每隔设备发出一个数据位后,都会读回总线当前的电平状态,以确认自己发出的电平是否被真实发送出去了。根据线与特性,发出0,读回必然是0,但是发出1读回不一定是1.(此刻是还在仲裁段,发出数据1,读回数据0,表示有设备在占用总线,ID小的优先)
优先级补充
-
数据帧和遥控帧ID号一样时,数据帧的优先级高于遥控帧
-
标准格式的11位ID号和扩展格式29位ID号的前11位系统,标准格式的优先级高于扩展格式(SSR必须始终为1)
错误类型
错误有5种:位错误、填充错误、CRC错误、格式错误、应答错误

为了防止某个设备发疯,一直认为别的设备发送是错误帧,引入错误状态
错误状态
- 主动错误状态的设备正常参与通信并检测到错误时发出主动错误帧(会破坏别的数据帧)
- 被动错误状态的设备正常参与通信但检测到错误时只能发出被动错误帧(不会破坏别的数据帧)
- 总线关闭状态的设备不能参与通信
- 每隔设备内部管理一个TEC和REC,根据TEC和REC确定直接的状态


STM32 CAN外设
-
波特率最高可达1Mbps
-
3个可配置优先级的发送邮箱 —— 发送缓冲区
-
2个3级深度接收FIFO —— 接收缓冲区
-
14个过滤器组 —— 过滤无关报文
-
时间触发通信、自动离线恢复、自动唤醒、禁止自动重传、接收FIFO溢出处理方式可配置、发送优先级可配置、双CAN模式

标识符过滤器
-
每个过滤器的核心由两个32位寄存器组成:R1[31:0]和R2[31:0];x = 0,…,13
-
FSCx:位宽设置;置0,16位;置1,32位
-
FBMx:模式设置;置0,屏蔽模式;置1,列表模式
-
FFAx:关联模式;置0,FIFO 0;置1,FIFO 1
-
FACTx:激活设置;置0,禁用;置1,启用、


(TIP:第二行Mask的0x700 ---- 0111 0000 0000,表示接收的第2到4位必须和ID相同)
测试模式

工作模式

位时间特征

TIP:STM32里面PBS1和PBS2合并成一个BS段
中断
