帧格式
1. 数据帧 (Data Frame - 携带数据)
-
目的: 发送实际数据(如车速、温度、开关状态等)。
-
结构 (标准帧为例):
-
SOF (Start of Frame - 1位 - 显性
0): 标志帧的开始,同步所有节点。 -
仲裁场 (Arbitration Field):
-
Identifier (ID - 11位): 消息的唯一标识符。值越小,优先级越高。决定哪个节点在总线冲突时赢得发送权(仲裁)。
-
RTR (Remote Transmission Request - 1位 - 显性
0): 固定为显性0,表示这是数据帧 (与远程帧区分)。
-
-
控制场 (Control Field - 6位):
-
IDE (Identifier Extension - 1位 - 显性
0): 固定为显性0,表示这是标准帧 (11位ID)。 -
保留位 (r0 - 1位 - 显性
0): 保留位,必须发显性0。 -
DLC (Data Length Code - 4位): 指定数据场包含的数据字节数 (0-8字节)。
-
-
数据场 (Data Field - 0-8字节): 实际要传输的数据内容。长度由DLC指定。
-
CRC场 (CRC Field - 16位):
-
CRC (Cyclic Redundancy Check - 15位): 根据帧内容计算的校验码,用于接收方检查传输错误。
-
CRC 界定符 (1位 - 隐性
1): 标志CRC字段结束。
-
-
ACK场 (Acknowledge Field - 2位):
-
ACK 槽 (ACK Slot - 1位): 发送方发送隐性
1。所有正确接收到该帧的节点(无论是否需要该数据)会在此时刻发送一个显性0覆盖它,表示“收到了,没错误”。 -
ACK 界定符 (1位 - 隐性
1): 标志ACK场结束。
-
-
EOF (End of Frame - 7位 - 隐性
1): 标志帧的结束。
-
2. 远程帧 (Remote Frame - 请求数据)
-
目的: 请求具有特定ID的节点发送其对应的数据帧。本身不携带数据。
-
结构 (标准帧为例): 与数据帧非常相似,关键区别有两点:
-
RTR位 (1位 - 隐性
1): 固定为隐性1,表示这是远程帧。 -
DLC (4位): 可以包含请求者希望收到的数据长度(0-8),但被请求的节点通常忽略此值,按自己的数据长度发送。有时用于请求特定格式。
-
无数据场: 远程帧没有数据场。
-
-
工作原理: 节点A发送一个ID=X, RTR=
1的远程帧。拥有ID=X数据帧的节点B看到这个请求后,会尽快发送一个ID=X, RTR=0的数据帧作为响应。
3. 错误帧 (Error Frame - 报告错误)
-
目的: 任何节点检测到错误(如CRC校验失败、格式错误、位填充错误等)时,立即主动打断当前总线传输,向所有节点报告错误。
-
结构 (两部分):
-
错误标志 (Error Flag):
-
主动错误标志 (6位显性
0): 由检测到错误且处于主动错误状态的节点发出。 -
被动错误标志 (6位隐性
1): 由检测到错误但处于被动错误状态的节点发出。 -
无论哪种,这6个连续的相同位都违反了CAN的位填充规则(每5个相同位后必须插入一个相反位),从而强制总线上的所有其他节点也检测到错误并参与发送错误标志。
-
-
错误界定符 (Error Delimiter - 8位隐性
1): 在错误标志之后,由所有节点发送8个隐性1位,提供一个恢复期,标志错误帧结束。总线随后恢复空闲。
-
4. 过载帧 (Overload Frame - 请求暂停)
-
目的: 当一个节点内部处理不过来(如缓冲区满、CPU太忙),无法及时处理接收到的帧时,在帧间间隔(IFS)期间发送,请求延迟发送下一个数据帧或远程帧。使用相对较少。
-
结构: 与错误帧非常相似:
-
过载标志 (Overload Flag - 6位显性
0): 由需要延迟的节点发出(主动错误状态节点发6个0,被动节点发6个1)。 -
过载界定符 (Overload Delimiter - 8位隐性
1): 标志过载帧结束。
-
5. 帧间隔 (Interframe Space - IFS - 帧间休息区)
-
目的: 分隔连续的数据帧或远程帧。提供节点处理时间,并包含总线空闲期。错误帧和过载帧后没有IFS,它们之后可以直接跟新的帧。
-
结构:
-
间隔段 (Intermission - 3位隐性
1): 强制的最小间隔。 -
总线空闲 (Bus Idle - 任意长度隐性
1): 真正的空闲时间,任何节点都可以在此后尝试发送(以SOF开始)。 -
对于刚刚成功发送帧的节点,IFS还包含一个额外的“挂起传输”段(3位隐性
1),使其在发送下一帧前有更长的延迟。
-
关键概念补充:
-
显性位 (
0) vs. 隐性位 (1):-
显性位 (
0): 逻辑“0”。在总线上表现为低电平。具有总线访问优先权(0会覆盖1)。 -
隐性位 (
1): 逻辑“1”。在总线上表现为高电平。当总线上没有节点驱动显性位时,表现为隐性位。
-
-
仲裁: 多个节点同时开始发送时,通过逐位比较ID(从最高位MSB开始)决定谁赢。节点发送ID位时,同时监听总线。如果它发送了隐性
1但监听到显性0,说明有更高优先级(ID值更小)的节点在发送,它立即停止发送转为接收模式。赢得仲裁的节点继续完成帧发送。 -
位填充 (Bit Stuffing): 为了保证同步,避免长时间相同电平导致时钟漂移。在SOF到CRC界定符之间,每当连续出现5个相同位(5个
0或5个1)后,发送方自动插入一个相反的位(在5个0后插1,在5个1后插0)。接收方会删除这些填充位。错误帧和过载帧的设计利用了违反位填充规则来快速通知所有节点。
位同步
核心目标: 确保总线上所有节点都能在正确的时间点读取总线上的电平(0或1)。想象大家围着桌子传纸条,必须同时低头看纸条内容,否则就乱了。
为什么需要同步?
-
时钟不同步: 每个节点都有自己的内部时钟(晶振),不可能100%精确相同,总有微小差异(误差)。
-
信号延迟: 信号在长长的总线电缆上传输需要时间,距离控制器远的节点会稍晚一点看到信号变化。
-
位长度: CAN总线上的每一位(0或1)占据一个固定时间段(称为位时间)。节点必须在这个时间段内的最佳位置采样总线电平,才能准确判断是0还是1。
1.硬同步 (Hard Synchronization) - “大复位”
-
时机: 只发生在帧的开头,即检测到
SOF(起始帧)的下降沿(从隐性1变显性0)时。 -
作用: 像一声发令枪!所有节点(接收方)一检测到这个下降沿,立即重置自己的内部位定时计数器,从零开始计时当前位时间。
-
效果: 确保所有节点(无论是接收方还是发送方)对第一位(SOF位)的计时起点完全对齐,同时对其相同的计时器起始点。
-
缺陷:每个接收设备的秒表都会存在误差,即使是进行了硬同步,秒表在后续计时的过程中也会存在不同步的情况,导致采样点逐渐偏离,所以要进行再同步(重同步)。
2.重同步 (Resynchronization) - “小调整”(接收方调整时钟)
-
时机: 发生在帧传输过程中,每次检测到从隐性位(1)到显性位(0)的跳变沿时(除了SOF那个边沿)。
-
作用: 不是完全重置,而是进行微调。节点计算检测到的边沿与自己内部时钟预期的边沿位置之间的偏差(相位误差)。
-
怎么调? 根据这个偏差是提前了还是落后了,节点会稍微延长或缩短当前位时间(通过调整
相位缓冲段即同步补偿宽度值(SJW)的长度),让内部时钟的预期边沿位置向实际检测到的边沿位置靠拢一点。 -
效果: 在整个帧传输过程中,持续不断地纠正因时钟误差和传输延迟造成的微小偏移,防止误差累积导致采样点错位。
3.位填充 (Bit Stuffing) - “保证有跳变”
-
规则: 在数据帧/远程帧的
SOF到CRC之间,如果连续出现5个相同极性的位(5个0或5个1),发送节点必须自动插入一个相反极性的位(第6位)。 -
目的: 强制制造跳变沿!确保数据流中至少每6位就有一个边沿(从0变1或1变0)。
-
重要性: 为重同步提供“抓手”!如果没有位填充,发送一长串0或1,中间就没有边沿,节点就失去了进行重同步调整的机会,时钟误差会累积直到采样出错。
-
接收端: 接收节点在接收过程中会自动删除这些插入的填充位,恢复原始数据。
位时间结构 (理解调整的基础):
-
同步段 (Sync_Seg): 期望边沿发生的位置。硬同步和重同步的基准点。
-
传播段 (Prop_Seg): 补偿信号在物理总线上的传播延迟时间。
-
相位缓冲段1 (Phase_Seg1) & 相位缓冲段2 (Phase_Seg2): 重同步发生的地方! 检测到边沿时:
-
如果边沿出现在
Phase_Seg1之前(比预期早),说明节点内部时钟慢了,就延长Phase_Seg1(增加当前位时间)。 -
如果边沿出现在
Sync_Seg之后但在Phase_Seg2结束之前(比预期晚),说明节点内部时钟快了,就缩短Phase_Seg2(减少当前位时间)。
-
-
采样点 (Sample Point): 通常位于
Phase_Seg1结束处。这是节点实际读取总线电平(决定是0还是1)的关键时刻!所有同步机制的核心目标就是让采样点对准总线电平最稳定的位置。
问题: 时钟不准 + 线路延迟 = 大家容易看错位。
方案:
硬同步 (发令枪): 开头强制所有人对齐。
重同步 (微调师): 过程中遇到跳变就微调时钟,跟紧节奏。
位填充 (节奏制造者): 强制插入跳变,保证有足够多的机会让“微调师”工作。
目标: 让每个节点的采样点都精准地落在每位数据的稳定区域,确保读到的0/1是正确的。
仲裁
核心目标: 当多个节点同时想发送信息时,决定谁先发,谁后发,避免数据在总线上撞车(冲突),并且让最重要的信息(高优先级)优先通过。
关键原理:
-
“线与”逻辑 (物理基础):
-
CAN总线是“线与”逻辑:显性电平 (
0) 是强信号,隐性电平 (1) 是弱信号。 -
结果:只要有一个节点发送显性
0,整个总线就被拉成显性0。只有所有节点都发送隐性1时,总线才是隐性1。 -
简单说:
0能覆盖1! 这是仲裁能进行的物理基础。
-
-
优先级由ID决定:
-
每条消息都有一个唯一的标识符 (ID)。ID值越小,优先级越高! (例如,ID=0x100 比 ID=0x200 优先级高)。
-
为什么? ID在数据帧/远程帧的仲裁场最先发送,且从最高位(MSB) 开始逐位发送,因此才能判断ID是否为最小,如果提前检测到有隐形1的话,就拉低这个节点的电平,直到总线空闲。
-
-
边发边听,愿赌服输 (仲裁过程):
想象多个节点在SOF(起始位)后同时开始发送它们的ID:-
每个节点一边发送自己的ID位,一边监听总线上的实际电平。
-
当某个节点发送了一个隐性位(
1),但监听到总线是显性位(0)时:-
它立刻明白:总线上有另一个节点在发送更高优先级(ID值更小) 的消息(因为对方在相同位置发的是
0,覆盖了我的1)。 -
它立即、优雅地停止发送,转为接收模式,准备接收胜出者的完整消息。
-
-
这个过程从ID的最高位(MSB)开始,逐位比较,直到决出胜负。
-
赢得仲裁的节点感觉不到任何冲突,继续完成它整个数据帧的发送。
-
举个简单例子 (假设2个节点):
-
节点A 想发送消息,ID = 0x201 (二进制:
0010 0000 0001) -
节点B 想发送消息,ID = 0x202 (二进制:
0010 0000 0010) -
优先级:0x201 (更小) > 0x202
为什么叫“非破坏性”仲裁?
-
只有ID参与竞争,在仲裁阶段就决出胜负。
-
输掉的节点在数据部分开始前就退出了,没有发生真正的数据碰撞(不会像以太网那样碰撞后要重传碎片)。
-
赢得仲裁的节点不受任何影响,它的帧被完整无损地发送出去。
-
总线时间没有被浪费在冲突后的恢复上。
仲裁阶段的关键点:
-
发生在哪里? 在仲裁场,主要是ID字段(和RTR、IDE位,它们也参与优先级比较)。
-
何时结束? 当某个节点发送一个隐性位(
1) 但监听到显性位(0) 时,它立即退出。如果所有位都相同(罕见,ID需唯一),先发送RTR/IDE等控制位的节点也可能胜出(显性位优先)。 -
谁赢? ID值最小的节点赢得仲裁(最高优先级)。
-
输家怎么办? 输家默默退出,等总线空闲后重新尝试发送。
注意
1、当节点A发送数据帧时,总线状态在忙,即使是优先级更高的节点B想要进来总线进行仲裁也要等节点A发送完才可以。只有两个节点都在仲裁场才可以进行ID优先级仲裁。
2、ID号相同时,数据帧优先级高于遥控帧。
3、标准格式11位ID号和扩展格式29位ID号的高11位一样时,标准格式的优先级高于扩展格式
错误处理
1. 强大的错误检测能力
CAN能在位级、帧级、报文级检测多种错误:
-
位错误 (Bit Error): 节点发送一个位后,回读总线电平。如果发送的是显性
0但读到隐性1(被别人覆盖),或发送隐性1但读到显性0(本应没人覆盖),立即报错!(仲裁期间发送隐性位1但读到显性0不算错,那是仲裁输了) -
位填充错误 (Stuff Error): 在不允许出现连续6个相同位的区域(SOF到CRC界定符之间),如果检测到连续6个相同位,报错! (位填充规则被破坏)
-
CRC错误 (CRC Error): 接收节点根据收到的数据重新计算CRC,与发送节点发来的CRC值比较。如果不匹配,报错! (数据传输过程有误)
-
格式错误 (Form Error): 检测到固定格式位出现非法值(如ACK界定符、CRC界定符、EOF必须是隐性
1,但实际读到了显性0),报错! -
ACK错误 (Acknowledgment Error): 发送节点在ACK槽位发送隐性
1,但没有监听到任何节点发来的显性0(表示无人正确接收),报错! (消息无人应答)
2. 错误帧 (Error Frame)
-
作用: 任何节点检测到以上任何一种错误时,立即(在下一个位时间)发出错误帧,强行打断当前的总线传输。
-
结构:
* 错误标志 (Error Flag): 发出 6个连续的显性位0(主动错误状态) 或 6个连续的隐性位1(被动错误状态)。这直接破坏了位填充规则!
* 错误界定符 (Error Delimiter): 接着发出 8个连续的隐性位1,提供一个“冷静期”,标志错误帧结束。 -
效果:
* 所有节点看到6个连续相同位(违反规则),都意识到有错误发生,所有节点(无论是否检测到原始错误)都会参与发送错误界定符。
* 当前传输被强制中止。发送节点知道出错,稍后会自动重传该帧。
* 广播式警报: 瞬间通知全网错误发生。
3. 自动重传 (Automatic Retransmission) - 再来一次!
-
触发: 发送节点如果因为自己检测到错误(如位错误、ACK错误)或接收到错误帧而发送失败。
-
动作: 发送节点不会等待指令,一旦总线恢复空闲,会立即自动尝试重新发送同一帧数据。
-
优点: 快速恢复,提高数据最终送达的可能性。
4. 错误计数器 & 错误状态管理
-
目的: 区分偶尔犯错的好节点和持续捣乱的坏节点,限制坏节点的影响。
-
机制:
* 每个节点有两个计数器:发送错误计数器 (TEC) 和 接收错误计数器 (REC)。
* 检测到错误/发出错误帧: 相应计数器增加(增加量取决于错误类型和节点角色)。
* 成功发送/接收帧: 相应计数器减少(降到0为止)。
5. 故障界定 (Fault Confinement) - 隔离坏节点
-
通过错误计数器和状态转换,能有效识别并隔离持续故障的节点:
* 被动错误状态: 限制其发送破坏性错误标志的能力(只能发弱弱的被动标志)。
* 总线关闭状态: 彻底将其物理隔离在通信之外,防止其持续发送错误破坏总线。
错误处理全过程示例 (节点A发送数据):
发送中出错: 节点A发送数据时,节点B检测到一个CRC错误。
拉响警报: 节点B(主动状态)立即发出错误帧(6个连续的
0)。集体响应: 所有节点收到警报,都参与发送错误界定符(8个
1)。传输中断: 节点A的发送被强行中止。
计数变化:
节点B (检测者):REC可能+1 (检测到错误)。
节点A (发送者):TEC大幅增加 (如+8,因为发送失败且收到错误帧)。
自动重传: 总线空闲后,节点A自动重发同一帧。
状态管理:
如果节点A只是偶尔出错:重传成功,TEC逐渐减少,保持主动状态。
如果节点A持续故障(如硬件损坏):
连续发送失败导致其TEC持续飙升。
当TEC >= 128:进入被动错误状态(发错误帧时只能发6个
1,影响小)。当TEC >= 256:进入总线关闭状态(被踢出总线,网络恢复平静)。
7174

被折叠的 条评论
为什么被折叠?



