CAN总线协议详解
CAN总线定义:
CAN(Control Area Network)属于现场总线的范畴,是一种高性能、高可靠性、易于开发和低成本的串行总线。
CAN是由德国Bosch公司在1986年为汽车监测和控制而设计的。由于其高性能、高可靠性、实时性等优点,随后也广泛用于工业自动化、多种控制设备、交通工具、医疗仪器以及建筑、环境控制等多种领域,其在每个领域的广泛使用促进了标准化的进程。
1991年9月PHILIPS SEMICONDUCTORS制订并发布了CAN技术规范V2.0,该技术规范包括A和B两部分。2.0A曾在CAN技术规范1.2中定义的CAN报文格式,提供11位地址;而2.0B给出了标准和扩展的两种报文格式,提供29位地址。此后ISO在1993年11月也正式发布了CAN的国际标准ISO11898。其中ISO11898-1定义了CAN数据链路层;ISO11898-2定义了非容错CAN物理层;ISO11898-3定义了11898-3的容错物理层。CAN总线协议只定义了物理层和数据链路层,要将CAN总线应用于实际的工程项目和产品开发中必须制定上层应用协议。目前汽车上应用的协议有:ISO15675(传输层协议)、ISO14229(应用层协议)等。
CAN总线的特点
1、 多主控制方式。在总线空闲时,所有单元都可往总线上发送消息(多主控制)。最先访问总线的单元可获得发送权(采用CSMA/CA方式)。当多个单元同时发送时,CANID小的节点获得发送权。
2、 非破坏性总线仲裁技术。当总线发生冲突时,高优先级报文可以不受影响的进行传输,保证高优先级的实时性要求;而低优先级的报文退出传输。
3、 高可靠性。每帧都有位填充,CRC校验等多种错误检测,保证了极低的错误率;发送期间丢失仲裁或者由于错误而破坏了的数据帧可自动重发(这一点由CAN控制器自己重发,无需人为重新装载发送数据)。
4、 自动关闭总线。CAN控制器可以检测和判断总线上的错误类型,是短暂的数据错误(如外部噪声),还是持续数据错误(如单元内部故障、驱动器故障、短路故障等)。当错误为持续性故障时,CAN控制器可自动关闭,脱离总线,以免影响总线上的其他节点正常通信。
CAN总线拓扑图
CAN控制器根据两根线上的电位差来判断总线电平。总线电平分为显性和隐性电平,二者必居其一。发送方通过使总线电平变化,将消息发送给接收方。下图1是一个CAN总线连接示意图。
下图1由两个CAN网络组成,其中一个网络通信速率为500K,另外一个为125K。每个CAN网络由CANH和CANL两根线组成,各个节点(ABS、SAS、ETM、ECM)分别连接在CANH和CAHL上。在每个CAN网络的头尾分别连接了两个终端电阻,终端电阻的大小为120欧姆。
下图1左边阴影部分是某个节点的内部电路模块,包含CPU、CAN控制器(CAN Controller,一般单片机都集成了CAN控制器模块)以及CAN收发器(CAN transceiver)。其中CPU负责将需要发送的数据传递给CAN控制器,以及接收从CAN控制器中解析的数据;CAN控制器将Rx脚的二进制的0/1转换为具体的报文,然后将报文传递给CPU,以及将CPU需要发送的报文转换为二进制0/1,然后通过Tx脚传递给CAN收发器。CAN控制器的主要功能是电平转换,将CANH和CANL上的电平转换为Rx脚上的0/1,将Tx脚上的0/1在CANH和CANL进行转换。
图1
信号电平
高速CAN,定义 当CANH 和 CANL 电压相同(CANH = CANL = 2.5V)时为逻辑“1”,CANH和CANL 电压相差 2V(CANH = 3.5V, CANL = 1.5V) 时为逻辑“0”。高速CAN收发器在共模电压范围内(-12V ~ 12V),将CANH和CANL电压相差大于 0.9V 解释为显性状态(Dominant),而将CANH和CANL电压相差小于 0.5V 解释为为隐性状态(Recessive)。
CAN总线采用不归零码位填充技术,也就是说CAN总线上的信号有两种不同的信号状态,分别是显性的(Dominant)逻辑0和隐形的(recessive)逻辑1,信号每一次传输完后不需要返回到逻辑0(显性)的电平。
CAN信号传输
图2 a
发送过程:CAN控制器将CPU传来的报文转换为逻辑电平(即逻辑0-显性电平或者逻辑1-隐性电平)通过Tx脚传递给CAN收发器。CAN收发器接收逻辑电平之后,再将其转换为差分电平输出到CAN总线上。
图2 b
接收过程:CAN收发器将CAN_H 和 CAN_L 线上传来的差分电平转换为逻辑电平输出到CAN控制器的Rx脚,CAN控制器再把该逻辑电平转化为相应报文发送到CPU上。
图2 c
报文传输
帧类型
CAN总线在报文传输中,可传输以下4种不同类型的帧报文:
数据帧:数据帧装载的是发送数据,它将数据从发送节点传输到接收节点;
远程帧:远程帧请求具有相同标识符(CANID)的数据帧的发送,实际很少使用;
错误帧:任何节点检测到总线错误时都可以发送错误帧。由于总线错误帧没有CANID,所以当检测到错误帧时,只知道有错误,但无法定位该错误帧是哪个模块发送的;
过载帧:过载帧用于在先行的和后续的数据帧之间提供附加的延时。
帧格式
在CAN2.0B规范中,数据帧和远程帧有两种帧格式,其区别主要在于标识符(即CANID)的长度:具有11位标识符的称为标准帧,而具有29位的帧称为扩展帧,如下图3所示。数据帧和远程帧都可以使用标准帧或远程帧格式。帧与帧之间是通过帧间隔进行分开。
数据帧格式
数据帧由7部分组成:帧起始、仲裁段、控制段、数据段、CRC段、ACK段、帧结束。
图3
帧起始
长度为1位,帧起始(SOF)表示数据帧的起始,由一个单独的显性位组成。CAN节点发送数据的原则是先监听后发送,即如果CAN节点需要发送数据,先监听总线是否空闲,如果总线空闲,则往总线发送帧起始(SOF),获得发送权,否则一直等待直到总线空闲才发送帧起始(SOF)。
仲裁段
标准帧和扩展帧的仲裁段不同,长度分别是12bit和32bit。如上图3所示,在标准帧格式中,仲裁段由11位标识符(CANID)和远程发送请求位(RTR)组成。在扩展帧中,仲裁段由29位标识符(CANID)、代替远程请求位(SRR)、扩展位(IDE)、远程发送请求位(RTR)组成。扩展帧标识符由11位基本ID和18位扩展ID组成。在标准帧中,远程发送请求位(RTR)和IDE固定位0。而扩展帧中,代替远程请求位(SRR)和IDE固定为1, 远程发送请求位(RTR)固定位0。
标识符(CANID):用于区分发送数据内容,比如我们定义ID 234发送某传感器采集到的温度值,ID 235发送某传感器采集到的电流值。对于发送节点来讲,当它需要发送温度数据值,只需要将温度值装入ID为234的报文,需要发送电流数据时,只需要将采集到的电流数据装入ID为235的报文。对报文接收节点来讲,一旦收到ID为234时,就知道里面装载的是温度值,一收到ID为235时,就知道里面装载的是电流值。
代替远程请求位(SRR):SRR是一个隐性位。在扩展帧中11位标识符的下一位是SRR位,而在标准帧中11位标识符的下一位是RTR位,因此SRR称作代替远程请求位。当标准帧和扩展帧冲突时,并且扩展帧的基本标识符与标准帧的标识符相同时,标准帧优先级高于扩展帧。
标识符扩展位(IDE):表示该报文为标准格式或扩展格式。为显性时,表示为标准帧,为隐性时,表示为扩展帧。
注:如前所述,CAN模块采用先监听后发送的原则,即如果CAN模块需要发送数据时,先监听总线,如果发现总线空闲,则开始发送报文。如果网络上两个CAN模块刚好同时需要发送报文,他们同时检测到总线空闲。且同时发送帧起始(SOF)。那么CANID小的模块发送优先级高,抢占发送权。
控制段
控制段表示数据段的数据段的长度,由保留位和数据长度码共6bit组成,如下图3所示。发送数据段的长度是可变的,具体长度由控制段决定。长度位0-8字节。DLC编码和数据段长度对应关系如下表所示。
表1
保留位:在标准格式由R1(显性)和R0(隐形)组成。
CRC段
包括CRC序列(15bit)和CRC界定符(1位,固定为隐性),图下图3所示。
CRC序列:该序列是对帧起始、帧仲裁段、控制段、数据段的进行CRC计算。
CRC界定符:CRC界定符是一个位隐性位。
ACK段
ACK段包含2bit,包括应答位和应答界定符。
在ACK段,发送节点发送两个隐性位。当接收节点正确接收到有效报文后,接收模块就会在ACK段的第一位发送隐性位来告知发送模块数据被正常接收了。应答界定符固定为高电平。
帧结束(EOF):
帧结束由7个隐性位组成,每个数据帧和远程帧都必须包含完整的帧结束分。
标准数据帧的长度
因此一帧报文最大长度为:1(SOF)+11(ID)+1(RTR)+6(控制段)+64(数据段)+15(CRC)+1(CRC界定符)+2(ACK)+7(EOF)+3(帧间隔)=111位。在不考虑位填充的情况下,一帧8个字节的标准帧,需要占用111位。
当考虑位填充时,通过示波器测量数据和ID全位0和全位1的数据帧占用总线时间。
当ID和Data全为1时,波特率位500K,报文占用总线时间为254us。
当ID和Data全为0时,波特率位500K,报文占用总线时间为252us。
通过以上测试,可以看出当我们需要以最快速度在CAN总线上传输报文时,最快速度大概是250us每帧报文,也就说最快1s能够传输不到4000条报文。
远程帧格式
包含帧起始、仲裁段、控制段、CRC段、ACK段、帧结束。与数据帧相比,RTR位为1,且缺少数据段。
图4
错误帧格式
错误帧由两部分组成:错误标志,错误界定符。错误标志长度为6个位,由于总线网络中有多个节点,每个检测到错误的节点都会发送错误帧,考虑到错误叠加,错误标志长度位6-12位。根据错误节点所处的状态不同,错误标志也是不一样的。当节点处于主动错误时,发送的错误标志为显性,当节点处于被动错误时,发送的错误标识为隐性。错误界定符由8个隐性位组成。
注:当某个节点因为本身原因,持续检测到错误,为了防止该节点一直发送错误帧而对其他正常工作的节点正常工作产生影响,所以该节点进入被动错误后,节点发送的错误帧为隐性,这样就不会影响其他节点正常工作。
图5
过载帧格式
过载帧由两部分组成:过载标志和过载界定符。
以下3中情况,都会引发过载帧的发送。
1、 CAN控制器要求延迟下一个数据帧或远程帧的发送。
2、 在帧间隔段的第1和第2位检测到显性(数据帧或者远程帧的发送需要等到3位长度的帧间隔发送完后才可以尝试发送);
3、 如果一个CAN节点在出错界定符或者过载界定符的第8位(最后1位)采样到1个显性位,节点就会发送一个过载帧(而非错误帧),此时错误计数器不会增加(数据帧或者远程帧的发送需要等错误界定符或者过载界定符发送完毕后,再等3个位长都的帧间隔才能发送数据)。
注:由上述1-3可以看出,为了阻止后续数据帧、远程帧的发送可以插入过载帧。
过载标志由6个显性位组成。过载标志和主动错误标志一样。过载标志的形式破坏了帧间隔,因此,所有其他节点检测到上述过载条件将发出过载标志。如果在帧间隔段的第3位检测到一个显性位,则该位将解释为帧起始。
过载界定符由8位隐性位组成。过载界定符的形式和错误界定符的形式一样。在过载标志位被发送后,节点一直检测总线,直到检测到一个从显性到隐性位的跳变。此时,总线上的每个节点都完成了过载标志的发送,并开始同时发送剩余的隐性位。
图6
帧间隔的格式
数据帧和远程帧通过帧间隔与总线上的其他帧(数据帧、远程帧、错误帧和过载帧)分隔开。过载帧和错误帧与他们之前的帧之间没有帧间隔,多个超载帧之间也没有帧间隔。
帧间隔包含间隔和总线空闲。对于处于被动错误状态的节点来说,其间隔帧除了包含间歇、总线空闲外,还包含延时发送。间歇包含3个隐性位。间歇期间,所有节点均不允许发送数据帧和远程帧,其唯一的作用是标示一个过载条件(第三位除外)。
总线空间的时长可以是任意长度。在此期间,总线被认为是空闲的,任何需要发送报文的节点在此期间都可以发送报文。一条因为其他报文正在发送而被挂起的报文,将在其延时结束后的第1位(如果此时总线还是空闲的情况下)开始发送,此时检测到总线的一个显性位将认为一个帧起始
延时传送是指节点发送一个报文后,在开始发送下一报文或者认可总线处于空闲前,在间隔后发出8个隐性位。如果在此期间由其他节点开始发送报文。延时传送降低了被动错误节点向总线发送报文的优先级,这样做是为了降低被动错误状态节点因自生故障干扰总线的可能性。
图7
数据发送优先级
在总线空闲时,最先开始发送的节点获得发送权。
当多个节点同时开始发送时,各发送节点从仲裁段的第一位开始进行仲裁。连续输出显性电平最多的单元可继续发送。仲裁过程如下图所示,节点1仲裁失败。
图8
位填充
由于CAN总线传输时,没有类似其他串行通信的CLK线,所以如果连续传输多个相同位时会有时钟误差的累加。为了解决此问题,引入位填充的概念。当同样的电平持续5位时添加一个位的反型数据,当电平发生跳变时,进行再同步,以解决时钟误差累加问题。位填充的构成如下图所示。
图9
错误种类
位错误
CAN节点在发送位的同时也会对总线进行监测,如果所发送的位值与所检测到的位值不相符,则认为检测到一个位错误。位错误是由总线上发出数据帧、远程帧、错误帧、过载帧的节点和发出ACK的节点检测到的。但以下情况除外:在仲裁段发出隐性电平,但是实际检测到显性电平,将被认为仲裁失败而非位错误;在仲裁段作为位填充发出隐性电平,但实际检测到显性电平,将被认为填充错误,而非位错误。发送节点在发送ACK段发送隐性电平,但检测到显性电平是,将判定位其他接收单元发送的ACK应答,而非位错误。发送被动错误(6个隐性位)但检测出显性电平,间不被认为位错误。
检测节点:发送节点和接收节点
填充错误
如果在报文发送期间,检测出6个连续显性或者隐性位,则将认为是一个填充错误。
检测节点:发送节点和接收节点
CRC错误
如果接收节点在接收数据过程中计算的CRC值与发节点发送的CRC不一致,则接收节点会发送一个错误帧。
检测节点:接收节点
格式错误
当一个固定形式的位检测出1个或多个非法位,则被认为是格式错误。具体包括数据帧和远程帧的CRC界定符、ACK界定符、EOF界定符以及错误界定符、超载界定符。
检测节点:接收节点
ACK错误
只要在应答间隙检测到显性,则发送节点认为这是一个ACK错误。
检测节点:发送节点
错误帧发送时间点
当任意节点检测到错误时,将会输出错误帧。处于主动错误的节点输出主动错误,处于被动错误的节点输出被动错误。
当节点检测到位错误、填充错误、格式错误、ACK错误,从检测出错误的下1位开始发送错误标志。
当节点检测到CRC错误时,在ACK界定符后的下1位发送错误标志。
注意:对于数据帧和远程帧来讲,需要在各种帧(数据帧、远程帧、错误帧、过载帧)发送结束后的再插入一个间隔帧,才可以数据帧。所以我们可以大致计算出当一帧数据发送失败后,大概多长时间CAN控制器才会才重发这帧报文(即错误帧长度再加上一个帧间隔,根据发送节点所处的是主动错误还是被动错误状态,帧间隔长度会不一样,所以计算时需要注意)。
错误计数器的加减规则
具体如下表。
表2
注:第3点当发送节点发送一个错误标志时,发送错误计数器值加8。这里有两个例外情况:一是当发送节点处于被动错误时,并检测到一个应答错误或者发送被动错误标志期间没有检测到显性位(这种情况是因为整个网络中只有发送节点一个节点存在,所以不能因为只有发送节点存在而一直将发送错误计数器往上加,直至发送节点进入bus off状态)二是发送节点因为仲裁期间发生填充错误而发送错误标志。以上两种情况,发送错误计数器值不变。
错误状态变化
当节点的发送错误计数器值在0-127之间且接收错误计算器值在0-127之间时,节点处于主动错误状态;
当节点的发送错误计数器值在128-255之接或者接收错误计数器值在128-255之间,节点处于被动错误。
当发送错误计数器值大于255时候,节点进入总线关闭(bus off),接收错误用于不会大于255,即接收错误不会使节点进入bus off。
注:只有发送错误才能让节点进入总线关闭。另外需要注意,当总线关闭可以设置CAN控制器时自动恢复(即检测到128次11个连续隐性位自动恢复到主动错误状态)还是不自动恢复。在汽车行业,一般都是不让CAN控制器自动恢复,而是人为控制进入快慢恢复过程。
图10
位时间要求
标称位时间
标称位时间,是指理想情况下发送1位所需要的时间,例如对于速率为500k的CAN总线,标称为时间=1/500k=2us
一个标称位时间可以划分为4个不重叠的段,分别为同步段(SS)、传播时间段(PTS)、相位缓冲段1(PBS1)、相位缓冲段2(PBS2)。
同步段(SS):多个连接在总线上的节点通过此段实现位时序调整,同步每个位的发送和接收工作。由隐性到显性或者显性到隐性电平变换最好发生在这个段中。
传播时间段(PTS):用于吸收网络上的物理延迟的段。所谓网络上的物理延时指发送节点的输出延迟、总线上信号的传播延迟、接收单元的输入延迟。这个段的时间为以上各延时时间的和的两倍。
相位缓冲段1(PBS1)和相位缓冲段2(PBS2):当信号边沿不能包含于SS段中时,可在此段进行补偿。由于各发送节点、接收节点以各自独立的内部时钟工作,细微的时钟误差会累计起来,PBS段可用于吸收此误差。通过对相位缓冲段加减SJW。
如下图所示,假设1个位由10个Tq组成,可以通过改变PTS和PBS1以及PBS2段的大小来实现不同的采样点。一般情况下传输速率越高采样点越低。对于500K传输速率来讲,采样点一般选择在75%-81.25%之间。采样点分为单点采样和多点采样,一般情况下,单点采样就可以满足要求。
注:一般直接选择单片机的外部晶振作为CAN总线的时钟源,而非PLL倍频再分频的时钟作为时钟源。
图11
采样点:所谓采样点是读取总线电平,并将读取到的电平作为位值的点。位置在PBS1结束处。
硬件同步
接收单元在空闲状态检测出帧起始时进行的同步调整。在检测出边沿时不考虑SJW的值而认为是SS段。硬同步如下图所示。
图12
再同步
在接收过程中检测出总线上的电平变化时进行的同步调整。每当检测出边沿时,根据边沿出现的位置加长PBS1段或者缩短PBS2段,以调整同步。调整的幅度大小为SJW。
如下图所示,当边沿出现在SS段后时,说明接收节点的SS段早于发送节点的SS段,接收节点为了在尽可能靠近发送节点的采样点处进行采样,在PBS1插入一个SJW。
图13
如下图所示,当边沿出现在SS段前时,说明接收节点的SS段晚于发送节点的SS段,接收节点为了在尽可能靠近发送节点的采样点处进行采样,再将上1位的PBS2减少一个SJW。
图14
硬同步和再同步的规则
1、1个位中只进行一次同步调整
2、只有当上次采样点的总线值和边沿后的总线值不同时,该边沿才能用于调整同步(即电平发生变化)
3、在总线空闲且存在隐性电平到显性电平边沿,则一定要进行硬件同步。
4、在总线非空闲检测到的隐性电平到显性电平的边沿如果满足条件1和2,将进行再同步。