CAN总线协议分层结构
CAN总线协议可分为4层模型,分别为物理层、MAC(媒介访问控制)层、LLC(逻辑链路控制)层、传输层
物理层
物理层定义了信号实际的发送方式、位时序、位的编码方式及同步的步骤
一般来说,参与CAN总线的设备有:MCU、CAN控制器、CAN收发器、CAN_H高电平线、CAN_L低电平线
| - TX > | | CAN_H
MCU -> CAN控制器 | | CAN收发器 <-> |
| < RX - | | CAN_L
发送方式
CAN收发器负责将CAN控制器的TTL/CMOS电平信号转换为CAN差分电平信号进行数据传输。也将CAN的差分电平信号转换为TTL/CMOS的电平信号送到CAN控制器,以实现完整的双向通信。

位时序
CAN总线上的时序不一定固定,主要依靠用户自定义;
同时也没有专门的时序发生器,仅依靠总线上的CAN控制器,由主机端指定
位的编码方式(NRZ编码)
不归零编码(NRZ)通过高低电平直接表示二进制数据,但缺乏自同步能力,需额外传输时钟信号
CAN总线使用6个位的插入填充位
同步步骤
标称位速率
用户通过对CAN控制器预设定位速率来确定位时间
位时间的内部结构
位时间分割为四个时间段:
同步段 (Synchronization Segment - SYNC_SEG): 这是位的起始段,固定为1个时间量子(Time Quantum, tq)的长度。CAN总线上的信号边沿(从隐性’1’到显性’0’的跳变)应该发生在这个段内。
传播段 (Propagation Time Segment - PROP_SEG): 用于补偿信号在整个CAN网络物理传播中的延迟。
相位缓冲段1 (Phase Buffer Segment 1 - PHASE_SEG1): 一个可伸缩的缓冲区域,用于补偿节点的时钟相位误差。
相位缓冲段2 (Phase Buffer Segment 2 - PHASE_SEG2): 另一个可伸缩的缓冲区域,同样用于补偿相位误差。
采样点 (Sample Point) 位于PHASE_SEG1的末尾。这是CAN控制器实际读取总线电平,并判定其为“0”还是“1”的精确时刻。通常设置在位时间的75%~85%处,以确保信号已经稳定。
同步与重同步
硬同步:
仅在帧起始位(SOF)时发生,当总线处于空闲状态(隐性)时,所有节点都在等待SOF(一个显性位)。
当SOF的下降沿出现时,每个节点都会强制将自己的位定时器复位,以确保所有节点在每一帧的开始都是完全对齐的。
重同步:
在一帧的传输过程中,每当出现从隐性(1)到显性(0)的跳变沿时,就有可能触发重同步。
当跳变沿早于或晚于同步段到达,就意味着该节点的本地时钟与发送方的时钟存在相位误差。
为了补偿这个误差,节点会动态地延长或缩短当前的位时间。
如果边沿来得早了,说明本地时钟偏慢,控制器就会缩短PHASE_SEG1。
如果边沿来得晚了,说明本地时钟偏快,控制器就会延长PHASE_SEG2。
SJW (Synchronization Jump Width - 同步跳转宽度) 是一个非常重要的配置参数。它定义了每次重同步时,PHASE_SEG1和PHASE_SEG2可以被延长或缩短的最大量(以tq为单位)。SJW的存在限制了调整的幅度,防止了过度校正,保证了网络的稳定性。
位填充
由于总线上长时间处于同一电位,没有从1到0的跳变,重同步机制就无法触发。CAN总线的解决方法是加入位填充机制。
帧起始、仲裁域、控制域、数据域以及CRC校验和域,均通过位填充方法编码。位填充是指,无论何时,发送器只要检测到位流中有5个连续相同逻辑的位,便会自动在位流中插入一个补码位。举例来说,如果连续5个显性位,则在5个显性位之后自动插入1个隐性位。接收器会自动删除这个插入的填充位。
数据帧或远程帧的剩余位域(CRC界定符、应答域和帧结尾域)形式固定,不填充。错误帧和过载帧也不填充。
CAN网络同步需要足够多的上升沿,这是CAN协议规定位填充的目的之一。位填充的其它作用:确保数据帧不会被当作错误帧(由6个连续的显性或隐性位组成)、确保正确识别帧结束标志(7个连续隐性位)。
MAC层(数据链路1层)
通信方式
半双工:可挂载多设备,多设备同时发送数据时,通过仲裁决定发送顺序,支持11位(标准格式)/29位(扩展格式)报文ID,用于区分消息功能,同时决定优先级
应答方式
ACK、NACK
消息的帧化
-
数据帧:用于发送节点向接收节点传输数据的帧
-
远程帧:用于接收节点向具有相同ID的发送节点请求数据的帧
-
错误帧:用于当检测出错误时向其他节点通知错误的帧
-
过载帧:用于通知远端节点,当前节点尚未做好接收准备的帧
-
帧间隔:用于将数据帧及远程帧与前面的帧分离开来的帧
帧结构
非扩展:
| 段名 | 帧起始 | 仲裁段 | 控制段 | 数据段 | CRC段 | ACK段 | 帧结束 | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 含义 | SOF | ID | RTR | IDE | R0 | DLC | Data | CRC | DEL | ACK | DEL | EOF |
| 长度 | 1 | 11 | 1 | 1 | 1 | 4 | 0~64 | 15 | 1 | 1 | 1 | 7 |
扩展:
| … | 仲裁段 | 控制段 | … | ||||||
|---|---|---|---|---|---|---|---|---|---|
| ID | SSR | IDE | EID | RTR | r1 | r0 | DLC | ||
| 11 | 1 | 1 | 18 | 1 | 1 | 1 | 4 |
帧起始:表示数据帧开始的段
- SOF:Start Of Frame 帧起始标志位-1bit,默认值为显性电平(逻辑0)
仲裁段:表示帧优先级的段
- ID:Identifier 标识符-11bit,用来确定报文的优先级,此域的数值越小,优先级越高
- SRR:Substitute Remote Request 代替远程请求位-1bit,为隐性(逻辑1)。当标准帧与扩展帧发送相互冲突并且扩展帧的基本标识符与标准帧的标识符相同时,标准帧优先级高于扩展帧。
- IDE:Identifier Extension 为隐性(逻辑1)表示标志位扩展帧,18位EID紧跟着IDE位
- EID:Extended Identifier 相比标准数据帧,增加18位扩展标识符
- RTR:Remote Transmission Request 远程发送请求位-1bit,作用是区分数据帧和远程帧。数据帧,RTR位为显性(逻辑0),表示该帧携带实际数据;远程帧,RTR位为隐性(逻辑1),用于请求其他节点发送特定标识符的数据帧
控制段:表示数据的字节数及保留位的段
- IDE:Identifier Extension 扩展标识符位-1bit,为显性(逻辑0)时表示这是一个标准CAN格式,为隐性(逻辑1)表示这是扩展CAN格式
- R1:Reserved Bit 保留位-1bit(替换掉了原本的IDE位)
- R0:Reserved Bit 保留位-1bit(可能将来标准修订会使用)
- DLC:Data Length Code 数据长度编码位-4bit,表示传输数据的字节数目,一帧CAN最多传输8字节用户数据
数据段
CRC段:检查帧的传输错误的段
- CRC:Cyclic Redundancy Check CRC校验码-15bit,用来校验用户数据区之前的(包含数据区)传输数据段是否有传输错误
- DEL:界定符-1bit,作用是用于标识CRC序列的结束,其固定为隐性(逻辑1),用于区分数据位与CRC校验位
ACK段:表示确认正常接收的段
- ACK:Acknowledge Field 应答位-1bit。当接收器正确地接收到有效的报文,接收器会在应答位期间向发送节点发送一个显性位(逻辑0),表示应答。如果接收器发现这帧数据有错误,则不向发送节点发送ACK应答,发送节点会稍后重传这帧数据
- DEL:应答界定符-1bit。作用是用于标识ACK的结束,其固定为隐性(逻辑1)
帧结束:表示数据帧结束的段
- EOF:End Of Frame 帧结束标志位-7bit,全部为隐性位(逻辑1)。如果这7位出现显性位(逻辑0),则会引起填充错误
标准帧和扩展帧的判定
当节点接收完11位ID后,开始接收RTR或者SRR(第13位)和IDE(第14位)
通过IDE来判断第13位的含义
如果IDE为1,表示这是扩展帧,这时候第13位的SRR(代替远程请求位)必定为1,若不为1则会报错
如果IDE为0,表示这是标准帧,这时候第13位的含义则是RTR,为0则是数据帧,为1则是远程帧
连接控制方式
竞争方式(支持多点传送)
数据冲突时的仲裁
根据仲裁,ID越小优先级越高,优先级高的ID可继续被发送
当两个或多个节点同时发送信息时,优先级较低的消息会被自动停止发送,以避免数据冲突
错误检测
所有单元都可随时监测错误
错误通知
CRC错误、填充位错误、位错误、ACK错误、格式错误
故障扩散抑制功能
自动判别暂时错误和持续错误,排除故障节点
LCC层(数据链路2层)
接收消息的选择(可接受消息的过滤)
单播、广播、组播
过载通知
通知接受准备尚未完成
错误恢复功能
重传
传输层
再发送控制
永久再尝试