文章目录CAN总线简介通信协议复习差分信号CAN的帧格式数据帧遥控帧错误帧过载帧帧间隔位填充错误的种类和错误处理错误的种类CAN的错误处理机制CAN的信任度管理系统逻辑线与数据采样波特率计算位时序同步机制硬同步再同步发生冲突(多设备同时发送数据)CAN总线简介CAN 是 Controller Area Network 的缩写以下称为 CAN是 ISO*1 国际标准化的串行通信协议。在当前的汽车产业中出于对安全性、舒适性、方便性、低公害、低成本的要求各种各样的电子控制系统被开发了出来。由于这些系统之间通信所用的数据类型及对可靠性的要求不尽相同由多条总线构成的情况很多线束的数量也随之增加。为适应“减少线束的数量”、“通过多个 LAN进行大量数据的高速通信”的需要1986 年德国电气商博世公司开发出面向汽车的 CAN 通信协议。此后CAN 通过 ISO11898 及 ISO11519 进行了标准化现在在欧洲已是汽车网络的标准协议。现在CAN 的高性能和可靠性已被认同并被广泛地应用于工业自动化、船舶、医疗设备、工业设备等方面。图1是车载网络的构想示意图。CAN 等通信协议的开发使多种 LAN 通过网关进行数据交换得以实现。图2是CAN的应用示例通信协议复习CAN总线是基于此环境下诞生那么它的特点是什么我们不妨根据我们学习过过的通信方式对比查看一下。USARTUSART通常是在板级距离的通信主要用作调试功能。支持全双工通信使用方便只用两个引脚即可。因为他是逐位传输的所以即使收到干扰也是只有单个字节受到影响所以抗干扰能里比较强通信时速率一般设为115200也就是115.2kbps速度不算快。USART在多机通信上会出现短板但是也可以通过设置9bit模式来实现。I2CI2C则是适用于多机通信的场景采用的是一主多从的通信模式由主机控制时钟线通过逻辑线与的机制来实现通信和通信仲裁。I2C只需要两个引脚所以在多机通信的场景下是性价比之选。通信速率标准模式是100kbps快速模式为400kbps如果想要达到Mbps级别的传输速率则需要硬件支持比如stm32F4系列。但是I2C的通信是半双工的并且一般是多机场景这就导致一次通讯中会有大量的无效数据。是典型的牺牲效率换取资源SPISPI可以用一句话概括牺牲了所有的换取了效率很轻易的就来到了Mbps级别的通讯速率。支持多机通信但是每多一个设备就需要多接一根CSS线并且在通信中没有任何数据帧格式总线上发送的都是有效数据。我们知道I2C和SPI都是有时钟线控制通信节奏的所以很明显这是同步通信那么USART只有收发两条线所以是异步通信。以上就是简单的回顾了之前学习过的通信协议下面让我们简单了解一下CAN总线的同步。可以先简单概括一下CAN是一个很稳定数据传输能力有限并且支持多机的异步通信协议。差分信号首先先介绍一下差分信号。了解差分信号之前就要先了解什么是单端信号。那么什么是单端信号呢我们已经接触过了在我们学习上面三个通信协议画的时序图就是单端信号。单端信号是一根信号线和一根地线以地线为基准根据信号线的电平大小输出高低电平所以这种情况下有外部干扰的话地线是不会变的而信号线就很容以收到影响那么就会改变原来的电平状态。而差分信号线是一对信号线同时输出电压根据两根信号线的电势差来判断是高电平还是低电平。所以当出现干扰的时候两根信号线的收的干扰程度是一样的所以电势差是不变的则输出的电平状态不变所以抗干扰能力强。就好比你去爬山一直以地面为参考那么就会越来越高但是如果你已自己的鞋为参考你的高度始终如一。高速CAN规定电压差为0V时表示逻辑1隐性电平电压差为2V时表示逻辑0显性电平低速CAN规定电压差为-1.5V时表示逻辑1隐性电平电压差为3V时表示逻辑0显性电平CAN的帧格式关于CAN为什么数据传输十分有限我们可以先看一下它的数据帧CAN有很多数据帧格式都会讲到我们先看一下数据帧。可以看到它的数据帧格式是比较严格的所以如果多帧拼接还是比较麻烦的而且这里显示数据段是0-64bit也就是8字节。这也是很符合它诞生的场景在开篇已经了解是为了汽车工业领域进行控制所以只是传输指令或传感器内容自然不需要过多的数据位所以我们在使用CAN时也应该考虑到这一点不能用CAN像串口一样进行大量数据的收发。既然CAN发送的数据量比较有限又支持多机通信并且也没有使用多个引脚也是和USART一样只有两个引脚Tx和Rx所以很明显也是一种异步通信协议那么他是怎么维护通信的呢一个是帧格式一个是过滤器。CAN是一个多主机通信的通信协议正如上文所说他不能通过上述这些东西进行控制所以它设置了很多帧类型用来在特定的场合进行发送。但其实就练习而言只需要一个数据帧也是够的。下面我们逐个讲解这些帧数据帧如上图所示数据帧由7个段构成帧起始:SOFStart of Frame帧起始表示后面一段波形为传输的数据位仲裁段:IDIdentify标识符区分功能同时决定优先级RTRRemote Transmission Request 远程请求位区分数据帧和遥控帧控制段:IDEIdentifier Extension扩展标志位区分标准格式和扩展格式r0/r1Reserve保留位为后续协议升级留下空间DLCData Length Code数据长度指示数据段有几个字节数据段Data数据段的1~8个字节有效数据CRC段CRCCyclic Redundancy Check循环冗余校验校验数据是否正确ACK段ACKAcknowledgement应答位判断数据有没有被接收方接收CRC/ACK界定符为应答位前后发送方和接收方释放总线留下时间帧结束EOFEnd of Frame 帧结束表示数据位已经传输完毕数据帧的发展历史可以看到上图有两种数据帧第一个是1.0版本第二个是2.0版本主要是因为ID不够用所以更新了一个扩展帧的格式所以为了区分这是标准格式还是扩展帧格式那么之前预留位r1就显示出了他的作用用来区分当前帧是标准格式还是扩展格式。但是总体不会影响我们的使用。遥控帧我在另一个参考文档中也看到叫远程帧他的作用就是发送给目的主机让他发送一个数据帧根据功能来讲的话我们也可以叫它请求帧。那么遥控帧的结构相较于数据帧也只是少了一个数据段所以不再单列其他都是一样的。错误帧用于在接收和发送消息时检测出错误通知错误的帧。错误帧由错误标志和错误界定符构成。错误帧没有一个固定的格式任何帧都可以是一个错误帧当发现发送的消息出现了问题的时候会自行作废该帧怎么知道该帧是废帧呢?就是连着六个相同的位这部分涉及到CAN的资源分配规则我们可以在后面细讲在这里知道有一个错误帧就可以了另外可以了解一下错误帧有两种一个是主动错误就是6个显性位也就是6个1另外一个就是被动错误那么也就是6个隐性位就是6个0过载帧过载帧是用于接收单元通知其尚未完成接收准备的帧。过载帧由过载标志和过载界定符构成。过载帧的格式也是六个显性位那么这里就出现了一个问题了这与错误帧的主动错误是一样的该怎恶魔区分呢过载真当接收方收到大量数据而无法处理时其可以发出过载帧延缓发送方的数据发送以平衡总线负载避免数据丢失。所以这里我们就应该会有一个简单的想法过载帧应该是在帧结束之后的而错误帧是在正在发送的帧种出现的帧间隔帧间隔是用于分隔数据帧和遥控帧的帧。数据帧和遥控帧可通过插入帧间隔将本帧与前面的任何帧数据帧、遥控帧、错误帧、过载帧分开。过载帧和错误帧前不能插入帧间隔。间隔3 个位的隐性位。总线空闲隐性电平无长度限制0 亦可。本状态下可视为总线空闲要发送的单元可开始访问总线。延迟传送发送暂时停止8 个位的隐性位。只在处于被动错误状态的单元刚发送一个消息后的帧间隔中包含的段。在这里上面的问题就可以得到回答了简单概括就是6个显性位出现在帧中间就是主动错误帧出现在帧与帧之间的间隔期就是过载帧。以上就是CAN的5种帧格式位填充位填充是为防止突发错误而设定的功能。当同样的电平持续 5 位时则添加一个位的反型数据。发送单元的工作在发送数据帧和遥控帧时SOFCRC 段间的数据相同电平如果持续 5 位在下一个位第 6 个位则要插入 1 位与前 5 位反型的电平。接收单元的工作在接收数据帧和遥控帧时SOFCRC 段间的数据相同电平如果持续 5 位需要删除下一个位第 6 个位再接收。如果这个第 6 个位的电平与前 5 位相同将被视为错误并发送错误帧。所以在这里就可以解释前面错误帧的问题了CAN规定了这种位填充的机制所以连续六个相同的bit位就是非法的所以将这种非法帧当作错误帧作为一种错误机制。错误的种类和错误处理错误的种类在CAN种规定了5种错误多种错误可能同时发生。分别是:位错误填充错误CRC错误格式错误ACK错误具体相关内容我们可以看一下手册种的这张表从这张表中我们看最右侧的一栏——检测单元。我们发现一个问题检测错误可以是自己也可以是其他节点。因为CAN是广播的所以就是所有节点都是接收单元这种感觉就是教室里一个同学起来回答问题所有同学都在看着他一样。即一个节点发送节点CAN总线上所有检点都去监督数据的正确性。那么如果检测出非法帧或错误发送节点和其他节点是怎么处理的呢CAN的错误处理机制首先先是要检测到错误然后要知道检测到错误的是哪一个节点主要确定是否是发送节点最后检测出错误的处理办法是什么错误的类型我们已经在上图种列出来了错误类型触发条件谁检测到位错误Bit Error发送的位与回读的总线电平不一致发送方填充错误Stuff Error检测到连续6个相同电平违反位填充规则所有节点CRC错误接收端计算的CRC值 ≠ 帧中的CRC值接收方格式错误Form Error固定格式字段出现非法位接收方应答错误ACK Error发送方在ACK槽未检测到显性位无人应答发送方那么我们可能会盲猜一下之前我们学了错误帧是有两种一个是主动错误一个是被动错误所以是不是由发送放自己检测出来的错误就是主动错误由其它节点检测出来的就是被动错误。这是一种错误的想法对于主动被动的区分不是用来区分检测对象是谁个人感觉这样做的意义也确实不是很大错了重发就好了不需要附带一个额外信息。CAN的信任度管理系统主动错误和被动错误是CAN协议中节点的两种工作状态核心区别在于对总线的控制能力不同。在CAN总线上的每个节点内部都维护着两个计数器TECTransmit Error Counter发送错误计数器RECReceive Error Counter接收错误计数器状态条件主动错误TEC 128 且 REC 128被动错误TEC ≥ 128 或 REC ≥ 128总线关闭TEC ≥ 256这两者的差异是什么呢是如何实现对总线控制的呢对比项主动错误被动错误错误标志6个显性位6个隐性位能否打断总线✅ 能❌ 不能能否正常收发✅ 完全正常✅ 可以收发但错误标志无效对总线的威胁正常参与者被限制干扰能力也就是说如果是被动错误状态是不能够打断状态的那么就可以简单理解为该节点不再具备监督权就好像所有同学都在听在回答问题的同学说话但是这个节点被老师再门外罚站了自然是没有监督里面同学的权力但是该同学如果要求回到教室内部就需要在全班面前开口接受所有同学监督。当然如果有同学频繁犯错那就不只是门外罚站而是联系家长回家反省了这种情况也是对应CAN总线对此的管理模式主动错误 “可信节点”你犯错少协议信任你允许你用显性位打断总线来报告错误被动错误 “可疑节点”你犯错太多了协议限制你的权限你的错误标志变成隐性位无法打断别人Bus Off “隔离节点”你犯错太多且持续不改直接把你踢出总线状态转换过程如下正常节点TEC0, REC0 │ │ 偶尔出错TEC逐渐增长 ▼ 主动错误状态TEC128, REC128 │ │ 频繁出错TEC≥128 或 REC≥128 ▼ 被动错误状态 │ │ 持续出错TEC≥256 ▼ 总线关闭Bus Off关于计数器的增减规则了解一下就好了这其实与我们写代码的关系不大。事件TEC变化发送时检测到位错误8发送时检测到其他错误填充、CRC、格式8发送ACK错误1成功发送一帧-1最低到0事件REC变化接收时检测到位错误1接收时检测到填充/CRC/格式错误1发送错误标志主动错误状态8发送错误标志被动错误状态8成功接收一帧-1最低到0ok 我们再回到错误检测的问题上现在搞清了这里边存在一个信任管理机制受信任的节点可以有更多的总线管理权限也就是说依据对应的错误类型所有受信任的节点都可以打断。那么是如何打断的呢逻辑线与我们在学习I2C的时候学习过他的仲裁模式就是非破坏性仲裁通过逻辑线与实现也就是谁先发0谁获取总线控制权。那么在CAN种也是通过逻辑线与实现的。当出现类似位错误的时候发送节点自己会自己废弃该帧连续发送6个相同电平视为错误帧。如果是其它节点检测出来的错误那么他们也是依靠这样的机制由于逻辑线与的机制我们也就能看出来为什么被动错误是隐性电平主动错误是显性电平也是同I2C一样的逻辑显性电平可以改变整体的总线信号。(CAN总线也是通过开漏上拉实现的逻辑线与)但是在这里你可能会有这样一个问题就是CAN总线中有多个设备那么肯定不会只有一个节点检测出错误其它节点检测不出来所以会不会出现不止6个连续相同的bit位。是的是会出现这样的结果出现错误帧的时候不见得是严格的6位甚至更多但是这个并不影响我们的结果。而且因为逻辑线与的存在也解决了一个问题就是发送节点不知到自己出错还是会继续发送数据但是这时候电平已经被其它节点变为显性状态了不会导致总线上的电平混乱。那么在这里也可以提一嘴CAN的仲裁方式也是非破坏性仲裁当某个发送节点出现位错误时也就自行放弃了。数据采样因为CAN是异步多主机通信没有统一的时钟管理。我们在学习USART的时候学到过随着时间的推移其可靠性就会越来越差。就是采样点的偏移。而我们CAN的诞生是为了处理汽车上的指令这需要有高可靠性所以关于数据采样它也有自己比较完善的机制用来解决采样时机偏移的情况由发送单元在非同步的情况下发送的每秒钟的位数称为位速率。一个位可分为 4 段。同步段(SS)传播时间(PTS)相位缓冲段1(PBS1)相位缓冲段2(PBS2)这些段又由可称为 Time Quantum以下称为 Tq的最小时间单位构成。1 位分为 4 个段每个段又由若干个 Tq 构成这称为位时序。1 位由多少个 Tq 构成、每个段又由多少个 Tq 构成等可以任意设定位时序。通过设定位时序多个单元可同时采样也可任意设定采样点。所谓采样点是读取总线电平并将读到的电平作为位值的点。位置在 PBS1 结束处。波特率计算由此我们可以知道传输一个bit位是多长时间了所以就可以计算他的波特率因为这些时间段在我们编程中是我们自己设置的所以波特率也是由我们自己控制一般工作时间设置为250kbps500kbps。波特率 1 / 一个数据位的时长 1 / ( T S S T P T S T P B S 1 T P B S 2 ) 波特率 1 / 一个数据位的时长 1 / (TSS TPTS TPBS1 TPBS2)波特率1/一个数据位的时长1/(TSSTPTSTPBS1TPBS2)例如S S 1 T q P T S 3 T q P B S 1 3 T q P B S 2 3 T q , T q 0.5 u s SS 1TqPTS 3TqPBS1 3TqPBS2 3Tq, Tq 0.5usSS1TqPTS3TqPBS13TqPBS23Tq,Tq0.5us波特率 1 / ( 0.5 u s 1.5 u s 1.5 u s 1.5 u s ) 200 k b p s 波特率 1 / (0.5us 1.5us 1.5us 1.5us) 200kbps波特率1/(0.5us1.5us1.5us1.5us)200kbps位时序为了灵活调整每个采样点的位置使采样点对齐数据位中心附近CAN总线对每一个数据位的时长进行了更细的划分分为同步段SS、传播时间段PTS、相位缓冲段1PBS1和相位缓冲段2PBS2每个段又由若干个最小时间单位Tq构成下表就是手册中各段的作用同步机制这里的同步机制分为硬件同步和再同步它们遵从如下规则。1 个位中只进行一次同步调整。只有当上次采样点的总线值和边沿后的总线值不同时该边沿才能用于调整同步。在总线空闲且存在隐性电平到显性电平的边沿时则一定要进行硬件同步。在总线非空闲时检测到的隐性电平到显性电平的边沿如果满足条件1和2将进行再同步。但还要满足下面条件。发送单元观测到自身输出的显性电平有延迟时不进行再同步。发送单元在帧起始到仲裁段有多个单元同时发送的情况下对延迟边沿不进行再同步。硬同步接收单元在总线空闲状态检测出帧起始时进行的同步调整。在检测出边沿的地方不考虑 SJW 的值而认为是 SS 段。硬件同步的过程如下图所示。硬同步只在帧的第一个下降沿SOF下降沿有效经过硬同步后若发送方和接收方的时钟没有误差则后续所有数据位的采样点必然都会对齐数据位中心附近每个设备都有一个位时序计时周期当某个设备发送方率先发送报文其他所有设备接收方收到SOF的下降沿时接收方会将自己的位时序计时周期拨到SS段的位置与发送方的位时序计时周期保持同步再同步在接收过程中检测出总线上的电平变化时进行的同步调整。每当检测出边沿时根据 SJW 值通过加长 PBS1 段或缩短 PBS2 段以调整同步。但如果发生了超出 SJW值的误差时最大调整量不能超过 SJW 值。若发送方或接收方的时钟有误差随着误差积累数据位边沿逐渐偏离SS段则此时接收方根据再同步补偿宽度值SJW通过加长PBS1段或缩短PBS2段以调整同步再同步可以发生在第一个下降沿之后的每个数据位跳变边沿发生冲突(多设备同时发送数据)CAN中有多种处理机制。首先是非破坏性仲裁原理是和I2C一样的不熟悉的同学可以复习一下I2C章节第二就是先来先得也就是说如果有设备在发送数据是不允许被打断的只能等待数据发送完毕才可以由其它节点发送当然也不是绝对不可以打断就是我们上面已经讲过的错误检测是可以打断的也就只有这一种情况可以打断当前正在传输的数据帧第三就是CAN中有对于不同帧有不同的优先级比如数据帧是高于遥控帧的第四就是根据ID号其实三四的本质也还是基于逻辑线与的机制实现的。具体感兴趣大家可以研究一下这写数据帧是如何设置的如果发生仲裁的话是如何仲裁最后判断的。