目录
学习视频:CAN总线入门教程-全面细致 面包板教学 多机通信_哔哩哔哩_bilibili
CAN简介
CAN总线(Controller Area Network Bus)控制器局域网总线
CAN总线是由BOSCH公司开发的一种简洁易用、传输速度快、易扩展、可靠性高的串行通信总线,广泛应用于汽车、嵌入式、工业控制等领域
CAN总线特征:
两根通信线(CAN_H、CAN_L),线路少
差分信号通信,抗干扰能力强
高速CAN(ISO11898):125k~1Mbps, <40m
低速CAN(ISO11519):10k~125kbps, <1km
异步,无需时钟线,通信速率由设备各自约定
半双工,可挂载多设备,多设备同时发送数据时通过仲裁判断先后顺序
11位/29位报文ID,用于区分消息功能,同时决定优先级
可配置1~8字节的有效载荷
可实现广播式和请求式两种传输方式
应答、CRC校验、位填充、位同步、错误处理等特性
主流通信协议对比
CAN硬件电路
每个设备通过CAN收发器挂载在CAN总线网络上
CAN控制器引出的TX和RX与CAN收发器相连,CAN收发器引出的CAN_H和CAN_L分别与总线的CAN_H和CAN_L相连
高速CAN使用闭环网络,CAN_H和CAN_L两端添加120Ω的终端电阻
低速CAN使用开环网络,CAN_H和CAN_L其中一端添加2.2kΩ的终端电阻
终端电阻作用:1、防止回波反射,使信号变得平稳。2、在没有设备操作时,将两根差分线的电压“收紧”(像弹簧一样将两根线电压拉到同一水平,类似上拉电阻),使其电压一致。
当设备想要发送0时,操作总线把总线“拉开”使其呈现0状态。当设备想要发送1时,就不去碰总线,总线在终端电阻的作用下自动归为默认状态1。
当设备想发送1时无需对总线进行操作,因为高速CAN总线的默认状态就是1。
CAN电平标准
CAN总线采用差分信号,即两线电压差()传输数据位
高速CAN规定:
电压差为0V时表示逻辑1(隐性电平)总线收紧,没有电压差,默认状态是1所以是隐性。
电压差为2V时表示逻辑0(显性电平)总线张开
低速CAN规定:
电压差为-1.5V时表示逻辑1(隐性电平)
电压差为3V时表示逻辑0(显性电平)
显性电平和隐性电平同时出现时,总线会表现出显性电平。(对应电路中常用“0强于1”的规定。)
显隐性描述的是总线的状态,1和0是为了与电路的规则对应。
CAN收发器—TJA1050(高速CAN)
CAN物理层特性
帧格式
数据帧
报文ID功能:1、表示后面数据的功能。2、还用于区分优先级。(当多个设备同时发送时,报文ID小的优先发送,ID大的报文等待下次总线空闲再重试发送)
RTR(远程请求标志位):用于区分数据帧(显性0)还是遥控帧(隐性1)。
ID+RTR为仲裁段,仲裁主要靠ID来实现,RTR加入的目的是相同的数据帧和遥控帧,数据帧的优先级大于遥控帧。(数据帧和遥控帧的ID可以相同)
IDE(ID扩展标志位):用于区分标准格式还是扩展格式。(标准格式固定为显性0,扩展格式固定为隐性1。)
r0:保留位
DLC:表示数据段的长度。
数据段:0-8字节,0-64位。
CRC:会对前面所有的数据位(SOF到Data)进行CRC算法计算,计算得到一个校验码附在后面。接收方收到数据和较验码后也会调用CRC算法进行计算,看看计算的校验码是否一致,以判断传输是否有误。
CRC界定符:1位,必须是隐性电平1。
ACK槽:应答,发送方发出数据,是否有设备收到,靠ACK位来实现。在ACK槽这位发送方发送隐性1,如果接收方存在,接收方要发送显性0(接收方有短暂控制权),以提示发送方有设备收到数据。(允许多个接收方共同拉开总线)
ACK界定符:接收方必须及时释放总线,交出控制权。
发送方和接收方共同完成整个波形,发送方发送1位,接收方就立刻收到那1位,数据帧还没结束,接收方就已经接收完了,在ACK槽短暂交接权力,让接收方操作总线产生应答,应答之后发送方的整个数据帧才结束。
标准帧ID为11位,范围是0x000 ~ 0x7FF
拓展帧ID为29位,范围是0x0000 0000 ~ 0x1FFF FFFF
数据帧各部分用途
SOF(Start of Frame):帧起始,表示后面一段波形为传输的数据位
ID(Identify):标识符,区分功能,同时决定优先级
RTR(Remote Transmission Request ):远程请求位,区分数据帧和遥控帧
IDE(Identifier Extension):扩展标志位,区分标准格式和扩展格式
SRR(Substitute Remote Request):替代RTR,协议升级时留下的无意义位
r0/r1(Reserve):保留位,为后续协议升级留下空间
DLC(Data Length Code):数据长度,指示数据段有几个字节
Data:数据段的1~8个字节有效数据
CRC(Cyclic Redundancy Check):循环冗余校验,校验数据是否正确
ACK(Acknowledgement):应答位,判断数据有没有被接收方接收
CRC/ACK界定符:为应答位前后发送方和接收方释放总线留下时间
EOF(End of Frame ):帧结束,表示数据位已经传输完毕
遥控帧
遥控帧(请求式)无数据段,RTR为隐性电平1,其他部分与数据帧相同
请求方发出遥控帧,遥控帧的ID表示要请求的数据,响应请求的一方,通过相同的ID的数据帧反馈数据。当请求和响应同时发生时,数据帧拥有更高的优先级。
请求式传输,每次传输数据都需要一来一回两个过程,适合那种使用频率低,但偶尔又需要集中用几次的数据。
使用频率高的数据用广播式。
错误帧
总线上所有设备都会监督总线的数据,一旦发现“位错误”或“填充错误”或“CRC错误”或“格式错误”或“应答错误” ,这些设备便会发出错误帧来破坏数据,同时终止当前的发送设备。
设备默认处于主动错误状态,会连续发6个显性位(拉开总线),总线只要有一个设备拉开了,就必然处于显性状态,必然会破坏正常传输的数据。
主动错误产生太频繁了,就会进入被动错误状态,连续发6个隐性位,不去碰总线,不会破坏总线别人发的数据,但是会破坏自己发的数据。
过载帧
当接收方收到大量数据而无法处理时,其可以发出过载帧,延缓发送方的数据发送,以平衡总线负载,避免数据丢失
帧间隔
将数据帧和遥控帧与前面的帧分离开
位填充
位填充规则:发送方每发送5个相同电平后,自动追加一个相反电平的填充位,接收方检测到填充位时,会自动移除填充位,恢复原始数据(位填充机制只存在SOF到CRC界定符之间)
例如:
即将发送: 100000110 10000011110 0111111111110
实际发送: 1000001110 1000001111100 011111011111010
实际接收: 1000001110 1000001111100 011111011111010
移除填充后: 100000110 10000011110 0111111111110
(位填充插入的数据位,要和后续的数据位合并,进行新的位填充判断)
位填充作用:
1、增加波形的定时信息,利于接收方执行“再同步”,防止波形长时间无变化,导致接收方不能精确掌握数据采样时机
2、将正常数据流与“错误帧”和“过载帧”区分开,标志“错误帧”和“过载帧”的特异性
3、保持CAN总线在发送正常数据流时的活跃状态,防止被误认为总线空闲(11个隐性1)
波形实例
标准数据帧,报文ID为0x555,数据长度1字节,数据内容为0xAA
标准数据帧,报文ID为0x666,数据长度2字节,数据内容为0x12, 0x34
扩展数据帧,报文ID为0x0789ABCD,数据长度1字节,数据内容为0x56
标准遥控帧,报文ID为0x088,数据长度1字节,无数据内容
位同步
接收方数据采样
CAN总线没有时钟线,总线上的所有设备通过约定波特率的方式确定每一个数据位的时长
发送方以约定的位时长每隔固定时间输出一个数据位
接收方以约定的位时长每隔固定时间采样总线的电平,输入一个数据位
理想状态下,接收方能依次采样到发送方发出的每个数据位,且采样点位于数据位中心附近
接收方数据采样遇到的问题
接收方以约定的位时长进行采样,但是采样点没有对齐数据位中心附近
采样点的初始位置没有对齐,如果能以第一次跳变沿为参考,延迟半个数据位左右的时间进行第一次采样,后续按照固定采样间隔进行采样,就可以解决采样没对齐。(硬同步)
接收方刚开始采样正确,但是时钟有误差,随着误差积累,采样点逐渐偏离
当数据采样点距离前面的跳变沿有点久了,可以将下一次的采样间隔给缩小一点,这样后面所有的采样点位置都会往前提,就能弥补接收方采样太慢的问题。相反,采样太快时可以延长一次数据采样间隔,这样后面所有采样点位置都会往后拖一拖。(再同步)
位时序
为了灵活调整每个采样点的位置,使采样点对齐数据位中心附近,CAN总线对每一个数据位的时长进行了更细的划分,分为同步段(SS)、传播时间段(PTS)、相位缓冲段1(PBS1)和相位缓冲段2(PBS2),每个段又由若干个最小时间单位(Tq)构成。
SS = 1Tq
PTS = 1~8Tq
PBS1 = 1~8Tq
PBS2 = 2~8Tq
Tq最小时间单位可自己设定。
采样点在PBS1和PBS2之间。通过控制PBS1和PBS2来控制采样点的前后。
硬同步
每个设备都有一个位时序计时周期,当某个设备(发送方)率先发送报文,其他所有设备(接收方)收到SOF的下降沿时,接收方会将自己的位时序计时周期拨到SS段的位置,与发送方的位时序计时周期保持同步
硬同步只在帧的第一个下降沿(SOF下降沿)有效
经过硬同步后,若发送方和接收方的时钟没有误差,则后续所有数据位的采样点必然都会对齐数据位中心附近
再同步
若发送方或接收方的时钟有误差,随着误差积累,数据位边沿逐渐偏离SS段,则此时接收方根据再同步补偿宽度值(SJW)(最大限制)通过加长PBS1段,或缩短PBS2段,以调整同步
再同步可以发生在第一个下降沿之后的每个数据位跳变边沿
SJW=1~4Tq
例如误差2Tq,SJW设置3Tq,实际补偿还是2Tq。误差2Tq,SJW设置1Tq,实际补偿是1Tq。
波特率计算
波特率 = 1 / 一个数据位的时长 =
例如:
SS = 1Tq,PTS = 3Tq,PBS1 = 3Tq,PBS2 = 3Tq
Tq = 0.5us
波特率 = 1 / (0.5us + 1.5us + 1.5us + 1.5us) = 200kbps
仲裁
多设备同时发送遇到的问题
CAN总线只有一对差分信号线,同一时间只能有一个设备操作总线发送数据,若多个设备同时有发送需求,该如何分配总线资源?
解决问题的思路:制定资源分配规则,依次满足多个设备的发送需求,确保同一时间只有一个设备操作总线
资源分配规则
先占先得
若当前已经有设备正在操作总线发送数据帧/遥控帧,则其他任何设备不能再同时发送数据帧/遥控帧(可以发送错误帧/过载帧破坏当前数据)
任何设备检测到连续11个隐性电平,即认为总线空闲,只有在总线空闲时,设备才能发送数据帧/遥控帧
一旦有设备正在发送数据帧/遥控帧,总线就会变为活跃状态,必然不会出现连续11个隐性电平,其他设备自然也不会破坏当前发送
若总线活跃状态其他设备有发送需求,则需要等待总线变为空闲,才能执行发送需求
不允许“半路入伙”。
非破坏性仲裁
若多个设备的发送需求同时到来或因等待而同时到来,则CAN总线协议会根据ID号(仲裁段 ID+RTR)进行非破坏性仲裁,ID号小的(优先级高)取到总线控制权,ID号大的(优先级低)仲裁失利后将转入接收状态,等待下一次总线空闲时再尝试发送
实现非破坏性仲裁需要两个要求:
线与特性:总线上任何一个设备发送显性电平0时,总线就会呈现显性电平0状态,只有当所有设备都发送隐性电平1时,总线才呈现隐性电平1状态,即:0 & X & X = 0,1 & 1 & 1 = 1
回读机制:每个设备发出一个数据位后,都会读回总线当前的电平状态,以确认自己发出的电平是否被真实地发送出去了,根据线与特性,发出0读回必然是0,发出1读回不一定是1。
(发送方也会接收一下数据,确认自己发出的电平是否真实发送,例如我发送1,但有别的设备发送0,根据线与导致总线为0状态,则我的数据被别人损坏了。当我感受到别的设备和我有冲突,这时候我就退出,不跟别的设备抢总线资源。)
非破坏性仲裁过程
数据位从前到后依次比较,出现差异且数据位为1的设备仲裁失利
数据帧和遥控帧的优先级
数据帧和遥控帧ID号一样时,数据帧的优先级高于遥控帧
遥控帧RTR为1,数据帧RTR为0.
标准格式和拓展格式的优先级
标准格式11位ID号和扩展格式29位ID号的高11位一样时,标准格式的优先级高于扩展格式(SRR必须始终为1,以保证此要求)
当拓展数据帧和标准遥控帧相遇时,会在仲裁段后的IDE位分出胜负。拓展数据帧IDE为1,标准遥控帧IDE为0,所以拓展数据帧仲裁失利,转入接收状态。
错误处理
错误类型
错误共有5种: 位错误、填充错误、CRC错误、格式错误、应答错误
检测到错误,会发出错误帧,进行错误通知。
错误状态
主动错误状态的设备正常参与通信并在检测到错误时发出主动错误帧(如果它频繁报告错误,说明这个设备不太可靠,转到被动错误状态。)
被动错误状态的设备正常参与通信但检测到错误时只能发出被动错误帧(如果在被动错误状态还在频繁报告错误,就转到总线关闭状态。)
总线关闭状态的设备不能参与通信
每个设备内部管理一个TEC(发送错误计数器,每发送一次错误TEC加1,每进行一次正常的发送后TEC减1)和REC(接收错误计数器,接收时每发现一次错误加1,正常接收一次减1)根据TEC和REC的值确定自己的状态
错误计数器
波形示例
设备处于主动错误状态,发送标准数据帧,正常传输
设备处于主动错误状态,发送标准数据帧,检测到ACK错误
设备处于被动错误状态,发送标准数据帧,检测到ACK错误