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字节的有效载荷 可实现广播式
(发送者向接收者写入数据,这个lan网络下的其他设备被动接收,可根据ID确定要不要接收)和
请求式(发一个数据就需要先请求再接收)两种传输方式 应答、CRC校验、位填充、位同步、错误处理等特性
主流通信协议对比
名称 | 引脚 | 双工 | 时钟 | 电平 | 设备 | 应用场景 |
---|---|---|---|---|---|---|
UART | TX、RX | 全双工 | 异步 | 单端 | 点对点 | 两个设备互相通信 |
I2C | SCL、SDA | 半双工 | 同步 | 单端 | 多设备 | 一个主控外挂多个模块 |
SPI | SCK、MOSI、MISO、SS | 全双工 | 同步 | 单端 | 多设备 | 一个主控外挂多个模块(高速) |
CAN | CAN_H、CAN_L | 半双工 | 异步 | 差分 | 多设备 | 多个主控互相通信 |
CAN结合了UART和IIC
UART
IIC
SPI
CAN: 如果想实现 有很多 主控单片机 相互进行通讯 比如 5个STM32 之间任意通信
这时候就可以利用到 CAN总线了 , USART I2C SPI 都难以实现这个要求
一、CAN硬件电路
-
每个设备通过CAN收发器挂载在CAN总线网络上
-
CAN控制器引出的TX和RX与CAN收发器相连,CAN收发器引出的CAN_H和CAN_L分别与总线的CAN_H和CAN_L相连
-
高速CAN使用闭环网络,CAN_H和CAN_L两端添加120Ω的终端电阻
电阻作用:
1.防止回波反射 尤其是 高频信号、远距离传输的场景 如果不加终端电阻 信号波形会在线路终端反射,进而干扰原始信号 。加了终端电阻 且 阻抗匹配 则电平跳变会比较平稳
2.在没有设备操作时 将两根差分线的电压 “收紧” (收紧为 电平1 呈隐性) 使其电压一致。
收紧:在没有设备操作总线的情况下 电阻就和弹簧一样 将两根线(CAN_H CAN_L) 的电压拉到同一个电平 和I2C的上拉电阻很像。
这里CAN总线的上拉电阻也就类似一个弹簧,可以将两根线“收紧”至电压一致状态,代表的就是默认1的状态,并且这两个电阻的阻值并不大,所以收紧的速度是很快的,使得CAN总线支持的最大速率也比较快,但是代价是CAN总线的功耗也会比较大。
如果某个设备想要发送 0 时 , 设备会操作总线,把总线拉开(总线的电平拉开) 使其呈现0状态。当设备想要发送1时 ,就不去碰总线 。总线在终端电阻的收缩下自动默认为1状态。注意当设备想发送1时,它无需对总线进行任何操作,因为总线默认的是1。
-
低速CAN使用开环网络,CAN_H和CAN_L其中一端添加2.2kΩ的终端电阻
低速CAN这里一端接到总线另一端悬空,没有形成环路,这里电阻无效,因为电路只有形成回路才有效,但是它可以防止回波反射,这两个电阻没有“收紧”作用。
1.电平标准:
1为隐性 0为显性
•CAN总线采用差分信号,即两线电压差(VCAN_H-VCAN_L)传输数据位
•高速CAN规定:
电压差为0V时表示逻辑1(隐性电平)
电压差为2V时表示逻辑0(显性电平)
•低速CAN规定:
电压差为-1.5V时表示逻辑1(隐性电平)
电压差为3V时表示逻辑0(显性电平)
2.高速CAN总线
电压差为0V 表示 逻辑1 (隐性电平) 因为没有压差
电压差为2V 表示 逻辑0 (显性电平) 因为有压差
上图有两种表示方式 一种是逻辑电平另一种是差分电平(有两根线 CAN_H和 L)
当CAN_H和CAN_L对地的电压都为2.5V时(压差为0): 表示当前 CAN总线 处于逻辑1的状态
当CAN_H对地电压为3.5 CAN_L对地电压1.5V (压差 2V):表示当前处于逻辑0的状态
如果 CAN 想发送101数据流 ,则CAN总线就会呈现出 :两线收紧、 两线张开 、两线收紧的状况
总线 收紧状态:成为 隐性电平 张开状态(电压差增大 就很像张开):称为显性电平
显性和隐性表现的是总线的状态 没有电压差 为 默认状态 所以叫隐性
两线张开 产生电压差 需要设备干预 所以为 显性。
如果显性电平和隐性电平同时出现时表现为显性状态,也就是0强于1。
3.低速CAN总线
电压差 -1.5V 表示 逻辑1 (隐性电平) 因为没有压差
电压差 3V 表示 逻辑0 (显性电平) 因为有压差
因为低速CAN 传输距离更远 考虑到线路会有压降 所以把1和0的 电压差的 差距增大了
高速CAN总线回归隐性电平快,传输速度快,低速CAN总线回归隐性电平慢,传输速度慢。
4.CAN收发器
TJA1050(高速CAN)
芯片内部框图
芯片引脚布局
这里的TXD和RXD与设备的CAN控制器相连
CANH和CANL与CAN总线相连
引脚描述
5.CAN物理层特性
二、CAN总线帧格式
•CAN协议规定了以下5种类型的帧:
帧类型 | 用途 |
---|---|
数据帧 | 发送设备主动发送数据(广播式) |
遥控帧 | 接收设备主动请求数据(请求式) |
错误帧 | 某个设备检测出错误时向其他设备通知错误 |
过载帧 | 接收设备通知其尚未做好接收准备 |
帧间隔 | 用于将数据帧及遥控帧与前面的帧分离开 |
1)数据帧
数据帧各部分用途简介
•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 ):帧结束,表示数据位已经传输完毕
2)遥控帧
遥控帧无数据段,RTR为隐性电平1,其他部分与数据帧相同
遥控帧无数据段,RTR为隐形电平1,其他部分与数据帧相同。所以学会了数据帧 遥控帧学起来就非常简单。看一下图, 首先遥控帧和数据帧通过RTR进区分, 数据帧RTR是显性0,遥控帧RTR是隐形1,当第二方收到RTS为1后,就会按照遥控帧的格式解析,遥控帧的DLC后免没有数据段,直接跟的是CRC校验码。
当某个设备发出遥控帧时,代表他想请求这个数据,请求自然不需要数据段,一次完整的请求需要遥控帧和数据帧配合。请求方发出遥控帧,遥控帧的ID表示要请求的数据,响应请求的一方,通过相同ID的数据帧反馈数据。当请求和反馈数据同时发生时,数据帧拥有更高的优先级。 这是遥控帧的作用和请求流程。
3)错误帧
总线上所有设备都会监督总线的数据,一旦发现“位错误”或“填充错误”或“CRC错误”或“格式错误”或“应答错误” 这五种错误,这些设备便会发出错误帧来破坏数据,同时终止当前的发送设备。
其中错误帧的用途是,某个设备检测出错误时向其他设备通知错误。当某个设备发现总线上的波形不对,产生错误了,他就会发出错误帧,错误帧可以叠加在数据帧上,并且可以破坏数据帧的数据,意思就是我发现这一帧数据有错,现在我破坏了这个数据,大家都不要用了,这是一种错误处理机制。了解即可。
下面是错误帧的定义。错误分为主动错误和被动错误。设备默认处于主动错误状态,处于主动错误状态的设备,检测出错误时会连续发6个显性位,发显性位就是拉开总线,总线只要有一个设备拉开了,就必然处于显性状态,即0和1相遇时,总线总是处于0状态,这是线与特性。
所以主动错误标志的6个显性位,必然会破坏正常传输的数据,当其他设备检测到错误标志时就会抛弃这个数据,主动错误产生太频繁,说明这个设备不太可靠,设备就会进入被动错误状态。 处于被动错误状态的设备检测出错误时会连续发6个隐性位,发出隐性位就是不去碰总线,不碰总线就不会破坏总线上别的设备发的数据。但是会破坏自己发的数据,自己的数据有问题,自己破坏掉,这样就不会影响到别的设备发的数据。所以这里是主动错误标志为显性,被动错误标志为隐性。 上图中错误标志为6位,发完错误标志后,再跟8个隐性1作为错误鉴定符,这就是错误帧的定义。
那这里为什么要跟0-6位的延长时间呢? 这是因为一个设备发出的错误标志,可能会引发其他设备连带产生错误标志,多个设备的错误标志叠加起来,这个标注位的长度就可能不止6位了。所以上面的图画的是错误标志可能会延长0-6位的时间,图下面也标了这是错误标志的重叠部分,这个错误帧,先知道一下就行,暂时不必深究。
4)过载帧
当接收方收到大量数据而无法处理时,其可以发出过载帧,延缓发送方的数据发送,以平衡总线负载,避免数据丢失。
当发送方发数据太快,接收方处理不了数据的时候,由接收方产生过载帧,因为数据是发送方主动发出的,接收方无法直接调整发送方的发送频率。那怎么应该办呢?只能产生一个和错误帧类似的过载帧。将数据破坏掉,发送方发不出去就会重试,在这个破坏和重试的过程中,发送数据就被延误了,同时也间接告诉发送方接收方收不了。如果发送方有相应的处理逻辑,它就会降低一点发送频率。
5)帧间隔
将数据帧和遥控帧与前面的帧分离开
帧间隔分为主动错误状态和被动错误状态。主动错误状态的帧间隔是3位。被动错误状态的帧间隔也是3位,另加8位延迟传输,被动状态表示设备不太可靠,加8位延迟传送表示:不可靠你就别那么着急发数据了,延迟传输会将设备置于仲裁不利的途径。
6)位填充
位填充规则:发送方每发送5个相同电平后,自动追加一个相反电平的填充位,接收方检测到填充位时,会自动移除填充位,恢复原始数据
例如:
即将发送: 100000110 10000011110 0111111111110
实际发送: 1000001110 1000001111100 011111011111010
实际接收: 1000001110 1000001111100 011111011111010
移除填充后:100000110 10000011110 0111111111110
位填充作用:
-
增加波形的定时信息,利于接收方执行“再同步”,防止波形长时间无变化,导致接收方不能精确掌握数据采样时机
-
将正常数据流与“错误帧”和“过载帧”区分开,标志“错误帧”和“过载帧”的特异性(六个相同电平,一旦出现错误帧或过载帧就能发现)
-
保持CAN总线在发送正常数据流时的活跃状态,防止被误认为总线空闲
三、位同步
1)接收方数据采样
-
CAN总线没有时钟线,总线上的所有设备通过约定波特率的方式确定每一个数据位的时长
-
发送方以约定的位时长每隔固定时间输出一个数据位
-
接收方以约定的位时长每隔固定时间采样总线的电平,输入一个数据位
-
理想状态下,接收方能依次采样到发送方发出的每个数据位,且采样点位于数据位中心附近
接收方数据采样遇到的问题
1.接收方以约定的位时长进行采样,但是采样点没有对齐数据位中心附近
2.接收方刚开始采样正确,但是时钟有误差,随着误差积累,采样点逐渐偏离
2)位时序
为了灵活调整每个采样点的位置也就是实现位同步,使采样点对齐数据位中心附近,CAN 协议把每一个数据位的时序分解成 位时序分解,分为
同步段(SS)、
传播时间段(PTS)、
相位缓冲段1(PBS1)和
相位缓冲段2(PBS2),每个段又由若干个最小时间单位(Tq)构成。
1 位分为4 个段,每个段又由若干个Tq 构成,这称为位时序。通过设定位时序,多个单元可同时采样,也可任意设定采样点。
上图第一张图设定CAN 通讯信号每一个数据位的长度为10Tq,其中SS 段占1Tq,PTS 段占3Tq,PBS1段占3Tq,PBS2 段占3Tq。(PBS2至少占两个)
信号的采样点位于PBS1 段与PBS2 段之间,通过控制各段的长度,可以对采样点的位置进行偏移,以便准确地采样,例如上图第二第三张图。
3)硬同步
每个设备都有一个位时序计时周期,当某个设备(发送方)率先发送报文,其他所有设备(接收方)收到SOF的下降沿时,接收方会将自己的位时序计时周期拨到SS段的位置,与发送方的位时序计时周期保持同步 硬同步只在帧的第一个下降沿(SOF下降沿)有效 经过硬同步后,若发送方和接收方的时钟没有误差,则后续所有数据位的采样点必然都会对齐数据位中心附近。
4)再同步
若发送方或接收方的时钟有误差,随着误差积累,数据位边沿逐渐偏离SS段,则此时接收方根据再同步补偿宽度值(SJW)通过加长PBS1段,或缩短PBS2段,以调整同步。再同步可以发生在第一个下降沿之后的每个数据位跳变边沿。
前面的硬同步只是当存在帧起始信号时才起作用,如果在一帧很长的数据内,节点信号与总线信号相位有偏移时,这种同步方式就无能为力了。因而需要引入再同步方式,它利用普通数据位的隐性至显性电平的跳变沿来同步。重新同步与硬同步方式相似的地方是它们都使用SS 段来进行检测,同步的目的都是使节点内的SS 段把跳变沿包含起来。
同步的方式分为超前和滞后两种情况,以总线跳变沿与SS 段的相对位置进行区分。
-
相位超前:
假设节点从总线的边沿跳变中,检测到它内部的时序比总线的时序相对超前2Tq,这时控制器在下一个位时序中的PBS1 段增加2Tq 的时间长度,使得节点与总线时序重新同步。
(加长PBS1)
-
相位滞后:
假设节点从总线的边沿跳变中,检测到它的时序比总线的时序相对滞后2Tq,这时控制器在前一个位时序中的PBS2 段减少2Tq 的时间长度,获得同步。
(缩小PBS2)
在重新同步的时候,PBS1 和PBS2 中增加或减少的这段时间长度被定义为“重新同步补偿宽度SJW (reSynchronization Jump Width)”。一般来说CAN 控制器会限定SJW 的最大值,如限定了最大SJW=3Tq 时,单次同步调整的时候不能增加或减少超过3Tq 的时间长度,若有需要,控制器会通过多次小幅度调整来实现同步。当控制器设置的SJW 极限值较大时,可以吸收的误差加大,但通讯的速度会下降,所以SJW不是越大越好。
5)波特率的计算
波特率 = 1 / 一个数据位的时长 = 1 / (TSS + TPTS + TPBS1 + TPBS2)
例如: SS = 1Tq,PTS = 3Tq,PBS1 = 3Tq,PBS2 = 3Tq Tq = 0.5us
波特率 = 1 / (0.5us + 1.5us + 1.5us + 1.5us) = 200kbps
四、资源分配规则与仲裁
多设备同时发送遇到的问题
CAN总线只有一对差分信号线,同一时间只能有一个设备操作总线发送数据,若多个设备同时有发送需求,该如何分配总线资源? 解决问题的思路:制定资源分配规则,依次满足多个设备的发送需求,确保同一时间只有一个设备操作总线
1)资源分配规则1 - 先占先得
-
若当前已经有设备正在操作总线发送数据帧/遥控帧,则其他任何设备不能再同时发送数据帧/遥控帧(可以发送错误帧/过载帧破坏当前数据)
-
任何设备检测到连续11个隐性电平,即认为总线空闲,只有在总线空闲时,设备才能发送数据帧/遥控帧
-
一旦有设备正在发送数据帧/遥控帧,总线就会变为活跃状态,必然不会出现连续11个隐性电平,其他设备自然也不会破坏当前发送
-
若总线活跃状态其他设备有发送需求,则需要等待总线变为空闲,才能执行发送需求
2)资源分配规则2 - 非破坏性仲裁
若多个设备的发送需求同时到来或因等待而同时到来,则CAN总线协议会根据ID号(仲裁段)进行非破坏性仲裁,ID号小的(优先级高)取到总线控制权,ID号大的(优先级低)仲裁失利后将转入接收状态,等待下一次总线空闲时再尝试发送 实现非破坏性仲裁需要两个要求:
-
线与特性:总线上任何一个设备发送显性电平0时,总线就会呈现显性电平0状态,只有当所有设备都发送隐性电平1时,总线才呈现隐性电平1状态,即:0 & X & X = 0,1 & 1 & 1 = 1
-
回读机制:每个设备发出一个数据位后,都会读回总线当前的电平状态,以确认自己发出的电平是否被真实地发送出去了,根据线与特性,发出0读回必然是0,发出1读回不一定是1
3)非破坏性仲裁过程
数据位从前到后依次比较,出现差异且数据位为1的设备仲裁失利
位填充的作用范围是帧起始、仲裁场、控制场、数据场以及CRC序列,但是位填充并不会影响仲裁的正确性
仲裁场会有位填充,位填充插入的位也会参与仲裁,但是插入的这些填充位并不会影响仲裁,也不会改变原有ID号的优先级
4)数据帧和遥控帧的优先级
数据帧和遥控帧ID号一样时,数据帧的优先级高于遥控帧
5)标准格式和扩展格式的优先级
标准格式11位ID号和扩展格式29位ID号的高11位一样时,标准格式的优先级高于扩展格式(SRR必须始终为1,以保证此要求)
-
RTR 位(Remote Transmission Request Bit),译作远程传输请求位,它是用于区分数据帧和遥控帧的,当它为显性电平0时表示数据帧,隐性电平1时表示遥控帧。数据帧就是写入,遥控帧就是读取。
-
SRR 位(Substitute Remote Request Bit),只存在于扩展格式,它用于替代标准格式中的RTR 位。由于扩展帧中的SRR 位为隐性位,RTR 在数据帧为显性位,所以在两个ID 相同的标准格式报文与扩展格式报文中,标准格式的优先级较高。
-
IDE 位(Identifier Extension Bit),译作标识符扩展位,它是用于区分标准格式与扩展格式,当它为显性电平时表示标准格式,隐性电平时表示扩展格式。
五、错误处理
1)错误类型
错误共有5种: 位错误、填充错误、CRC错误、格式错误、应答错误
注:位错误:想发的位和总线上回读的位不一致(不包括仲裁段(仲裁失利)和应答位(发送方会发1读0))
2)错误状态
主动错误状态的设备正常参与通信并在检测到错误时发出主动错误帧 被动错误状态的设备正常参与通信但检测到错误时只能发出被动错误帧 总线关闭状态的设备不能参与通信 每个设备内部管理一个TEC和REC,根据TEC和REC的值确定自己的状态
3)错误计数器
4)波形示例
设备处于主动错误状态,发送标准数据帧,正常传输
设备处于主动错误状态,发送标准数据帧,检测到ACK错误
设备处于被动错误状态,发送标准数据帧,检测到ACK错误
未完待续......