文章目录
- 0. 前言
- 1. CAN简介
- 2. 主流通讯协议对比
- 3. CAN 硬件电路
- 4. CAN 电平标准
- 5. CAN 收发器
0. 前言
博客内容来自B站上CAN总线入门教程视频讲解,博客中的插图和内容均为视频中的内容。视频链接 CAN总线入门教程
1. CAN简介
先来看看一它名字的意思,can总线,英文全称是 Controller Area Network Bus, 直译是控制器局域网总线,简称 C A N 总线,一般就读作CAN总线,从名字也可以看出来,CAN总线构建的是一种局域网网络,每个挂载在 CAN 总线的设备都可以利用这个局域网去发送自己的消息,也可以接收局域网的各种消息,每个设备都是平等的,都在共享这个局域网的通信资源。这是CAN总线的设计理念。
CAN 总线是由 BOSCH 公司开发的一种简洁易用、传输速度快、易扩展、可靠性高的串行通讯总线,广泛应用于汽车、嵌入式、工业控制等领域。CAN总线最初就是为了汽车而设计的,所以其对可靠性和稳定性的要求非常高。 待会我们也可以了解到,CAN总线的差分信号、应答机制、 CRC 校验、错误处理等设计无处不体现出其严谨和安全。
在满足这么多功能和性能的同时,CAN 总线仍然能保持一个非常简洁易用的硬件电路,所以说CAN 总线的设计还是非常成功的。现在 CAN 总线已经成为一种通用的通信方式,不仅限于汽车领域,在其他很多领域也都有 CAN 总线的身影。另外近几年新能源汽车的火热发展,也促使了很多人来学习CAN总线。
接下来概括的看一下 CAN 总线的特性:
- CAN 总线只有两根通信线,CAN_High和CAN_Low,简称CAN_H 和CAN_L,线路少,且无需共地。也就是说CAN 总线总共就只需要两根线,就能实现任意设备的互相通信了,而且不需要共地,因为它是差分信号,所以CAN 总线的线路非常少。
比如说 I2C 通信,它也只有两根通信线 SCL 、SDA,但是 I2C 是单端信号,必须得共地,所以实际上 I2C 至少得 3 根线。
-
CAN 总线采用差分信号通信,CAN_H 和CAN_L 就是一对差分线,差分线的好处就是抗干扰能力强。如果线路产生干扰,则一般两根线的电压都会同时出现波动,但是两根线的电压差值仍然是不变的,所以利用这个电压插值来传递数据就能极大地避免干扰。
-
目前 CAN 总线分为了两种标准,高速 CAN 和低速 CAN。高速 CAN 在国际标准中叫 ISO 11898,其传输速率为 125k ~ 1Mbps,传输距离 < 40m。低速 CAN 叫 ISO 11519,传输速率为10k ~ 125 kbps, 传输距离 < 1 km。可以看出高速 CAN传出快,但是距离较短,低速CAN传速慢,但是距离很远,这个可以根据应用场景选择。当然本课程侧重学习的是高速 CAN ,这个应用广一些。低速CAN也有涉及,所以着重学习高速 CAN即可。
-
CAN总线是异步的,无需时钟线,通讯速率由设备各自约定。这点和串口非常类似。
-
CAN总线是半双工的,不可以同时发送和接收。CAN总线可挂载多设备,每个设备都可以占用CAN总线来发送自己的数据,多设备同时发送数据时会通过仲裁判断先后顺序。也就是让大家排好队,消息都是可以发出去的,这个后续还会详细介绍。
-
11位 /29位 报文 ID ,用于区分消息功能,同时决定优先级。CAN总线是通过发送方广播自己的消息来实现多设备互相通信。每个设备都可以广播消息,那自然,每个消息也最好都加一个 ID,用于区分功能。否则谁知道每个消息都什么意思呢,对吧?
报文 ID 有11位的,叫标准格式,后来又扩增至29位,叫扩展格式。同时,报文 ID 不仅可以区分消息功能,当不同消息想要同时占用总件发送时,报文 ID 还决定优先级, ID 号小的优先发送,这是报文 ID 的作用。
-
CAN总线的一个数据帧可以配置 1~ 8 字节的有效载荷。这个类比串口,串口一次只能发一个字节,而CAN总线比较强大,它最大一次可以发 8 个字节,并且可以灵活指定数据长度,1~8字节随意配展。
-
CAN 总线可以实现广播式和请求式两种传输方式。刚那么看到示例属于广播式传输方式,就是一个设备发送数据,其他所有设备都能收到,然后接收方根据报文 ID, 来决定用不用这个数据。大概的场景就是,发送方说:管你们要不要,我反正把数据发出去了,你们谁要谁拿走,这是广播式,也是CAN总线最常用的方式,我们主要学习广播式即可。
除了广播式,CAN总线还可以有请求式,请求式的场景是数据发送方不会主动广播自己的数据,而是只有收到接收方发出的请求,发送方才会发数据,这样一个数据的传输就需要先请求再接收,一来一回两个过程,这是请求式。
-
CAN总线的设计,还包括应答、 CRC 校验、位填充、位同步、错误处理等诸多特性,这里简介大家有个印象就行,接下来再慢慢细说。
2. 主流通讯协议对比
回顾一下其他主流的通信协议,有 UART 串口、I2C 和 SPI。
CAN 总线的设计,跟这些协议有诸多相似的地方。尤其是 UART 和 I2C。在我看来 CAN 总线就是 UART 和 I2C 的结合体,当然需要再加一点点细节。 CAN 总线既继承了 UART 的方便易用,又拥有像 I2C 一样的多主机特性。在差分信号的设计上,又和 RS485 异曲同工。可以说,如果你对 UART 串口和 I2C 很熟悉,那么 CAN总线 就已经学会一半了。
但是如果你不会 UART 和 I2C,那本课程理解起来可能有点困难,不过也不要害怕,虽然原理部分你可能不能完全理解,但是本课程只要你有个大体上的概念即可,因为CAN 总线的底层操作,STM32 都已经包办了,最终写程序的时候,并不需要你对底层原理完全了解,那 UART 和 I2C 的知识点这里就不再讲了。
对比这几种通信协议,我总结了它们的一般应用场景:
-
比如串口,就是点对点的两个设备互相通信。左下角这个图是串口的电路,比如单片机和电脑的串口助手点对点通信,或者单片机和一些模块点对点通信,串口的使用是最简单的,但是串口的弊端就是只能两个设备点对点的通信。
-
下一个 I2C 通信,它的电路是中间这个图,一般的应用场景就是:一个单片机当作主控,然后外挂多个被动的传感器、存储器等模块。虽然 I2C 也有和 CAN 类似的多主机设计,但是 I2C 的多主机不太方便,应用也不多。所以 I2C 的主要场景,还是一主多从。
-
然后 SPI 通信协议的场景和 I2C 类似,也是一主多从的模型,其通信电路如右下图所示,SPI 的线路更多,但是其通信速率是最快的,轻松达到 Mbps, 比本节我们讲的 CAN 总线还快。SPI 主要应用于高速通信的场景。
那么总结以上场景:I2C 和 SPI 一般都是一主多从的,只能有一个主控。 UART 虽然两个设备都可以是主控,但是它只能点对点的通信,主控的数量有限。所以如果我的应用场景是需要有很多个主控,单片机互相进行通信,比如5个或10个 STM 32,它们之间想任意互相传数据,这该怎么办呢?
显然,以上三种通信协议都难以胜任这个工作,而我们本节所讲的CAN总线最大的优势就是可以实现多个主控互相通信。它的应用场景就是超过两个的单片机主控系统之间进行通信,我们可以用两根线的CAN总线将每个主控串起来,这样就直接可以实现任意的数据传输了。
CAN 总线的设计目的,以及什么场景下需要用CAN总线,我们就清楚了。
接下来本节课的内容主要分为 5 章:
- 第 1 章是 CAN 总线的硬件电路如何接线、电平标准是什么,CAN 收发器有什么用,以及CAN 物理层特性的总表。
- 第 2 章是 CAN总线的帧格式,也就是如何将要发送的数据编码为CAN总线上的时序波形,这里主要学习 CAN 总线的 5 种帧类型,数据帧、遥控帧、错误帧、过载帧以及帧间隔,之后了解位填充的规则,就可以分析CAN总线的实际波形了。
- 第 3 章是 CAN 总线接收方要考虑的问题,发送方发出一段波形,接收方该如何采样得到数据呢?首先抛出两个问题,之后针对这两个问题,CAN 总线定义位时序,并且设计了硬同步和再同步的规则来解决以上两个问题。最后波特律的计算方法也了解一下。
- 第 4 章是 CAN 总线多设备同时发送的处理方法,两个设备想同时发送,但是CAN 总线只能承载一个波形,如何分配通信资源,这是CAN总线要考虑的。在这里 CAN 总线定义有先占先得和非破坏性仲裁 两个资源分配规则,其中仲裁过程以及各类型帧的优先级也会学习。
- 第 5 章是CAN 总线的错误处理,总共有哪些错误,以及如何处理这些错误。
3. CAN 硬件电路
下面这两个图就是CAN 总线的电路接法
左图为闭环 CAN 总线是高速 CAN的接法。右图为开环 CAN总线是低速CAN的接法,重点学习高速 CAN。
- 每个设备通过 CAN 收发器挂载在 CAN 总线网络上。
这里画了3个设备作为 CAN 的节点,每个设备都可以是一个 CAN 的主控系统,比如 STM32、单片机,有更多的设备也都是类似的接法。那每个设备都得通过一个CAN 收发器接入到 CAN 总线,CAN收发器就是一个芯片,主要实现电平转换、输出驱动和输入采样几个功能。
- CAN 控制器引出的 TX 和 RX与 CAN 收发器相连,CAN 收发器引出的CAN_H 和CAN_L 分别与总线的CAN_H 和CAN_L 相连。
下图也可以看出,在每个CAN 节点里的主控设备会内置有 CAN 控制器,比如 STM32 中的CAN外设电路,CAN 控制器只会引出 TX 和 RX 两个端口,这两个端口不能直接接到 CAN 总线,必须要借助 CAN 收发器来接入,CAN 收发器会有 TX 、RX 、 CAN_H 和CAN_L 等引脚。CAN 控制器的TX、RX 就和收发器相连,TX 接 TX,RX 接 RX,无需交叉。然后 CAN 收发器的CAN_H 和CAN_L就直接和 CAN 总线相连。CAN_H 接CAN_H,CAN_L 接 CAN_L 这样每个节点就成功挂载到了总得 CAN 总线上。
~
下面这两根线就是串联各个节点的CAN 总线,CAN 总线里走的是差分信号,一般会用双绞线作为载体,避免干扰,
- 高速 CAN使用闭环网络,CAN_H 和CAN_L两端添加120Ω 的终端电阻。可以看到这两根 CAN主线串联每个节点后,它的两端要分别接一个120Ω 的电阻,使 CAN 主线形成一个闭合的环路。所以叫闭环 CAN 总线。
那加这两个终端电阻主要作用有两个:
第一个作用是防止回拨反射,尤其是高频信号远距离传输的场景,回拨反射是不能忽略的问题。关于回波反射具体原因,可以学学"传输电理论",这里仅解释现象。如果不加终端电阻,信号波形会在线路终端反射,进而干扰原始信号,最终的波形可能是当信号跳变时,它会在边沿震荡几下,这会干扰数据的正确传输。
~
如果加上终端电阻且阻抗匹配,则信号的跳变沿就会变得非常平稳,这是终端电阻的第一个作用。
~
第二个作用是在没有设备操作时,将两根差分线的电压"收紧",使其电压一致。这里我用一个比较直白的词,“收紧”。它的意思就是在没有设备操作总线的情况下,这个电阻就像一根弹簧一样,会将两根线的电压拉到同一水平,也就是所说的收紧。
这一点其实和 I2C 的上拉电阻一样,I2C 是这样的,两根通信线各加一个上拉电阻,默认拉高至高电平。当有设备想发送 0 时,就把线路强制拉低至低电平,当有设备发送 1 时,不是把线路强制拉高至高电平,而是不去碰这个线路。
~
线路由上拉电阻,默认拉高至高电频,这样的好处是可以防止电平冲突,同时,这还能实现"线与"的特性,对总监仲裁十分重要。
那这个上拉电阻就也类似一个弹簧,默认把电压拉高至高电平,在CAN总线这里也采用了类似的设计,因为 CAN 总线是差分信号有两根线,所以两边的终端电阻可以将两根线"收紧"至电压一致状态,代表的就是默认的1状态,并且这两个电阻的阻值并不大,所以这个收紧的速度是比较快的,使得CAN总线支持的最大速率也比较快,但是代价是CAN总线的功耗也会比较大,这里当某个设备想要发送0时,它就会操作总线,把发动线拉开,使其呈现 0 状态。当设备想发送 1 时,就不去碰总线,总线在终端电阻的收缩下自动归位默认状态1,这一点尤其重要。
一定要注意,当设备想发送 1 时,它无需对动线进任何操作,因为总线的默认状态就是1。 这是高速 CAN的电路,以及高速 CAN如何发送0和1的操作方式。
-
低速 CAN 使用开环网络,CAN_H 和CAN_L 其中一端添加 2.2 kΩ 的终端电阻,也就是右下角这样,两根线没有形成环路,所以叫开环CAN总线。
其中这个电阻的接法比较特殊,其一端接到总线,另一端是悬空的,根据电路的原理,这个电阻应该是没有任何作用的,因为电路只有形成回路才有效。但在这里它可以有防止回波反射的作用。
另外这个电阻没有连接两根线,所以这两个电阻并没有"收紧"作用。以上就是 CAN 的硬件电路。
对于其连接方式和要点,大家务必掌握,因为用 CAN 总线肯定避免不了接线。那线路看好了,我们再看一下,CAN 的电平标准。
4. CAN 电平标准
-
CAN 总线采用差分信号,即两线电压差(VCAN_H - VCAN_L) 传输数据位。
-
刚才我们也形象地介绍了如何利用这两根线传输 1 和 0,现在来看一下它的具体规定。首先,高速 CAN 的规定是电压差为 0 V时表示逻辑1(隐性电平),电压差为 2V 时表示逻辑 0(显性电平)。
这里注意一下,逻辑1又称隐性电平,逻辑0又称显性电平,这个定义是反直觉的,正常的想法应该1表示显性,0表示隐性,那为什么这里是反着定义的,1表示隐性,而0却表示显性呢?
我们对照下面这个图分析一下,这里有两种波形表示方式,一种是逻辑电平表示,高电频表示逻辑1,低电频表示逻辑0。
一种是查分电平表示,这里有两根线,红线表示CAN_H 线的电压,蓝线表示CAN_L 线的电压。当 CAN_H 和CAN_L 对地的电压都为 2.5V 时,两线电压相等,电压差为 0V,表示当前CAN总线处于逻辑1的状态。当CAN_H 对地电压3.5V,CAN_L对地电压1.5V时,两线电压差为2V,表示当前CAN总线处于逻辑0的状态。
比如 CAN总线想发送101的数据流,那么CAN总线就会呈现出两线收紧,两线张开,两线收紧这样的状态。
当然这里逻辑表示和差分表示完全等效,在CAN总线里实际传输的是差分电平,而在STM32的引脚以及常见的时序画法里会出现逻辑电平表示,因为实际画时序波形的时候总是画两根线难免比较麻烦。况且这两根线实际只有1和0两种状态,所以我们就可以简化一下,画个逻辑表示就行了,比如后面的帧时序,为了简便,使用的都是逻辑电平画法,时许里只有一根高低电平的线,但是大家要知道,它这里画的高低电瓶并不直接表示CAN总线里传输的是高低电平,而是表示总线收紧还是总线张开的状态,这一点要注意一下,然后继续看,这里总线收紧状态称为隐性电平,总线张开状态称为显性电平。
因为总线收紧状态被定义为了逻辑1,所以就会出现,1又称隐性电平的反逻辑,显性和隐性表示的是总线的状态,两线收紧没有电压差是默认状态,所以叫隐性。两线张开产生电压差是需要设备干预的状态,所以叫显性。这样定义显性、隐性是符合常识的。
在和逻辑电平的对应上,因为电路约定俗成的习惯,就是默认状态为高电平1,所以默认的隐性电平就和逻辑1绑定了,显性和0绑定,另外,显性电平和隐形电平同时出现时,总线会表现出显性电平状态,这也能对应电路中,常用的"0强于1"的规定。
这是一对应隐性,0对应显性的设计原因。简单来说,显隐性描述的是总线的状态,1和0是为了与电路约定俗成的规则对应。这就是高速 CAN的电平标准定义。
-
低速CAN的电平规定,电差为-1.5V时,表示逻辑1(隐性电平)。电压差为3V时,表示逻辑0显性电平。
右下角是低速CAN的波形图,当低速CAN想要发送101的数据流时,总线就会呈现这样的状态,CAN_L 为3.25 V,CAN_H 为1.75 V,电压差为-1.5 V时,表示1。CAN_L 为1V,CAN_H 为4V,电压差为3V时表示 0 。在规定上,其实和高速 CAN差不多,但是低速CAN 传输距离更远。
考虑线路会有压降,所以把1和0电平电压的差距加大了,由此1和0变化的行程更长了,这样即使有一些压降,也能明显地区分出1和0的电平差异。同时,也看出低速CAN默认的逻辑1,隐性电平 CAN_H 和 CAN_L 电压并不相等,所以对应起电路,总线两端就不能用终端电阻闭合连在一起了。如果像高速 CAN 一样连在一起了,那么终端电阻就有收紧两线电压的趋势,这样就和低速CAN默认两线电压不相等的设计相悖了,对于高速 CAN 默认的隐性电平,两线电压就是相等的,所以总线两端加闭合的终端电阻就更有利于总线快速回归隐形电平。
高速CAN总线回归隐形电平快,传输速度就会快,低速CAN总线回归隐性电平慢,传输速度自然就慢。这是高速 CAN和低速CAN的设计思路。
5. CAN 收发器
好,电平标准定义看完了,接着简单看一下,CAN 收发器的内部框图。
刚才我们说了,每个 CAN 设备都得通过 CAN 收发器挂在总线上,那CAN收发器有什么用?
可以干哪些工作呢?
看一下这个框图就知道了,这里介绍的CAN收发器型号是 TJA1050,是一个高速 CAN的收发器,左边是芯片内部框图,右上角是芯片的引脚布局,右下角是引脚描述。
这个芯片总共有8个角,GND和 VCC 需要提供5V的供电。TXD 和RXD 与设备的CAN控制器相连,CAN_H 和 CAN_L 与CAN总线相连,Vref是参考电压输出,可以不用 。S是高速模式还是静默模式,可以理解为是一个开关,也可以不用,所以这个芯片的接线非常简单,一看就懂,然后看这个芯片内部可以干点啥呢?
首先右边CAN_H和 CAN_L 就是CAN总线,左边接收器可以时刻检测总线电压差并输出到左边这根线,如果总线有电压差就输1,如果总线没有电压差就输出0,这个1和0通过两个场效应管的输出驱动器输出到 RXD 引脚。这两个管,可当成是电子开关,右边为1时,上管断开,下管导通,输出0。右管为0时,上管导通,下管断开,输出1,所以这两个管还有个电瓶反向的功能。最终整体上看,当CAN总线有电压差时,输出RXD 引脚为低电平0,表示显性电平。CAN总线没有电压差时,输出RXD 引脚为高电平1表示隐性电平,所以RXD 这一块,就是输入部分。那上面 TXD 这一块就输出部分了,当 TXD 为1时,后面这个驱动器就会让这边两个场效应管都断开。相当于不对总线进任何操作,总线在外边终端电阻的收紧作用下,呈现默认的隐形电平。
另外,可以看出,内部这里还有两个电阻,这个电阻叫“中拉电阻”,通过这两个电阻可以把CAN_H和CAN_L 两根线都拉到0.5倍 VCC 的中间电平,也就是CAN_H和CAN_L 的默认对地电压都是2.5伏左右。
同时,这两个电阻也有一定的收紧作用,不过它们的阻值比较大,所以收紧作用主要还是靠外面的终端电阻来实现,这是这个问题。
当 TXD 给 0 时,后面这个驱动器就会让这边两个场效应管都导通,这就相当于有两只手,上面的手将CAN_H 电压拽高,下面的手将 CAN_L 的电压拽低,这样两线就会分开,产生电压差,总线呈现显性电平0的状态,这就是发送0的操作。
最后这里还有几块,左边这个是电流源上拉,类似于上拉电阻,作用是如果 TXD 悬空了,那么这里会保持默认输入1的状态,防止输入引脚电平不确定造成误操作。然后这里是 TXD 显性超时计时器,作用是,如果 TXD 出现异常,始终输入显性电平0,始终拽着总线不放,那么CAN总线将始终呈现显性电平0状态,这样整条总线将会瘫痪,并且没有设备可以阻止这一情况,所以在这里,收发器加了一层保险,如果设备异常,始终拽着总线不放,那么等一段时间后,收发器将会自动去释放总线,防止总线瘫痪。
然后这个是一个开关控制 ,S引脚可以选择是否静默,S 引脚有个下拉的电流源,可以看出,如果 S 悬空则会默认输入0,最后这个是温度保护,如果温度异常,则会控制驱动器切断输出,以免干扰CAN总线,那这一块就输出部分了。
整体来说就是,如果 TXD 给1,则不会对总线进行任何操作,总线呈现默认的隐形电平1,如果 TXD 悬空,则默认也是给1。如果 TXD 给0,则驱动器会把CAN_H 拉高 ,CAN_L 拉低,输出显性电平 0。
如果 TXD 一直给0出错了,则显性超时,收发器会主动释放CAN总线。好,这就是收发器的全部内容。
最后,通过这个CAN 物理层特性的表,来总结下第一章的内容。
-
首先 ISO 11898 是高速 CAN,最高1Mbps,最长40米,总线最高挂载30个节点设备,隐性电平时,CAN_H和CAN_L的对地电压均为2.5V。电压差为0表示的是隐性电平,逻辑1。显性电平时,CAN_H 3.5V,CAN_L 1.5V,电压差为2V,表示的是显性电平逻辑0。当然,这些电压都会有一些容差范围,在这个范围内均可,高速 CAN的差分信号,一般使用双绞线传输,是闭环总线,阻抗120Ω,终端电阻也是120Ω。
-
然后右边是 ISO11519-2,杠几就是标准的第几次修订板哈。那它是低速CAN,最高125kbps,最大长度1 km,当然在最大长度时,其速率只能支持到40 kbps,低速CAN 最高挂载20个节点设备,其使用的也是双绞线,不过是开环的总线,阻抗是120Ω,终端电阻是2.2 kΩ,其他的参数自己看。
好,这是 CAN 总线的第一章,CAN 物理层的全部规定了。CAN 物理层规定了硬件电路该怎么接,电平定义是什么,以及如何发送显性电平0和隐性电平1。至此,我们就学会了CAN总线是如何发送一个数据位的,那实际应用中,我们肯定不满足于只发送一位数据,对吧?
这样,就需要连续发送多位数据来组成数据流,既然需要发送数据流,那每一位都是什么意思?谁先发谁后发?该如何编码和解析数据?这是第二章 CAN 总线帧格式所要规定的内容。