参考链接:
- CAN入门书 (uml.com.cn)
- [野火]瑞萨RA系列FSP库开发实战指南——基于野火启明开发板 — [野火]瑞萨RA系列FSP库开发实战指南——基于野火启明开发板 文档 (embedfire.com)
- CAN总线协议_can协议-CSDN博客
- CAN总线基础知识+硬件知识_can线基础知识讲解-CSDN博客
说明:本文主要讲CAN的原理。
一、不同通信协议间的比较
CAN是一种异步半双工的通信协议,并不是以时钟信号来进行同步的, 它只具有 CAN_High 和 CAN_Low 两条信号线,共同构成一组差分信号线,以 差分信号的形式进行通讯。
注:差分信号的意思后面有讲。
二、CAN的分类(物理层结构)
2.1按速率分类
- 低速 CAN(ISO11519标准) 通信速率 10~125Kbps ,总线长度可达1000 米。
- 高速 CAN(ISO11898标准) 通信速率 125Kbps~1Mbps ,总线长度≤40 米。(传统 CAN)
- CAN FD 通信速率可达 5Mbps ,并且兼容传统 CAN。
2.1.1 低速CAN(开环总线网络)
图 CAN 开环总线通讯网络中的是遵循 ISO11519-2 标准的低速、远距离“开环网络”,它的最大 传输距离为 1km,最高通讯速率为 125kbps,两根总线是独立的、不形成闭环,要求每根总线上 各串联有一个“2.2 千欧”的电阻。
2.1.2 高速CAN(闭环总线通讯网络)
这是CAN 闭环总线通讯网络,遵循 ISO11898 标准的高速、短距离“闭环网络”,它的总线最大长度为 40m,通信速度最高为 1Mbps, 总线的两端各要求有一个“120 欧”的电阻。
2.1.3 CAN FD (传统CAN的升级)
CAN FD (CAN with Flexible Data-Rate),字面意思上看,相较于 CAN 多了 FD (Flexible Data-Rate), 也就是“灵活数据速率”。CAN FD 协议的物理层与传统 CAN 协议是一样的,都是闭环总线通讯。
2.2 按位置分类
CAN的组成一般有两种方式:
- CPU与CAN控制器集成到一起、再外接CAN收发器;
- 另一种是CPU与CAN控制器分开的,使用的时候需要配置CAN接口电路,比较麻烦。
STM32中就是采用第一种方式,将CAN接口集成在芯片内,使用的时候再外接CAN收发器(顾名思义,可发送,可接收),常用的有TJA1050或者82C250。
三、CAN的物理层标准
这里我们以传统的CAN为例子:
CAN 总线上可以挂载多个通讯节点,节点之间的信号经过总线传 输,实现节点间通讯。由于 CAN 通讯协议不对节点进行地址编码,而是对数据内容进行编码的, 所以网络中的节点个数理论上不受限制,只要总线的负载足够即可,可以通过中继器增强负载。
CAN 通讯节点由一个 CAN 控制器及 CAN 收发器组成,控制器与收发器之间通过 CAN_Tx 及 CAN_Rx 信号线相连,收发器与 CAN 总线之间使用 CAN_High 及 CAN_Low 信号线相连。其中 CAN_Tx 及 CAN_Rx 使用普通的类似 TTL 逻辑信号,而 CAN_High 及 CAN_Low 是一对差分信号线,使用比较特别的差分信号。
CAN_Tx (Transmission):
信号源:
CAN_Tx
引脚是微控制器用来向CAN总线发送数据的输出端口。当MCU想要发送数据时,它会通过CAN_Tx
引脚输出一系列逻辑电平,这些电平通常是TTL或CMOS逻辑级别的电压(例如,逻辑1通常约为5V,逻辑0约为0V,具体取决于MCU的电源电压和逻辑电平标准)。逻辑电平到差分信号:MCU输出的这些逻辑电平信号被连接到CAN收发器的输入端。CAN收发器内部会将这些单端信号转换成差分信号,即
CAN_High
和CAN_Low
。差分信号中,当CAN_High
比CAN_Low
高时代表显性位(逻辑0),两者电压相等或接近时代表隐性位(逻辑1)。
CAN_Rx (Reception)
差分信号到逻辑电平:当有信号从CAN总线上传输过来时,CAN收发器会将接收到的差分信号转换回单端的逻辑电平信号,然后通过
CAN_Rx
引脚送回给MCU。这个过程是实时的,确保MCU能够准确地读取总线上的数据。数据解码:MCU通过
CAN_Rx
引脚接收到来自总线的信号,并将其解码为相应的数据帧、远程帧、错误帧或过载帧等,依据CAN协议规范进行处理
差分信号 CAN_H 与 CAN_L
差分信号所指的就是差模和共模两种形式,但是CAN通信中的差分信号与模电中差分放大器的差分信号有所不同,这里我们只讲CAN里面的差分信号。以下图片是CAN中的差分信号计算,可以简单理解为两个输入的差值。
3.1 显性信号与隐性信号
现在我们已经知道了当 CAN_H = 2.5 V ,CAN_L = 2.5 V 时, 他们之间的电位差为
VH-VL=0V ,当CAN_High 比CAN_Low 高时代表显性位(逻辑0),两者电压相等或接近时代表隐性位(逻辑1)。
需要注意的是:CAN通信属于半双工,在一个时刻只能进行发送或接收,假设A节点想要发送信号时在帧起始位要先发送显性信号,意思是告诉其他节点,“我要开始发信号了哦,你们注意一下”,此时B节点也想要发送信号就也要在帧起始位先发送显性信号,此时根据二者信号的优先级判断谁能够发送信号,ID更小的优先级越高,则优先发送信号。比如A的优先级高于B的,此时B的帧起始位相对A而言表现为“隐性电平”,B就不能发送信号,只能选择接收了。
由于 CAN 总线协议的物理层只有 1 对差分线,在一个时刻只能表示一个信号,所以对通讯节点 来说,CAN 通讯是半双工的,收发数据需要分时进行。在 CAN 的通讯网络中,因为共用总线, 在整个网络中同一时刻只能有一个通讯节点发送信号,其余的节点在该时刻都只能接收。
在 CAN 总线中,必须使它处于隐性电平 (逻辑 1) 或显性电平 (逻辑 0) 中的其中一个状态。假如 有两个 CAN 通讯节点,在同一时间,一个输出隐性电平,另一个输出显性电平,类似 I2C 总线 的“线与”特性将使它处于显性电平状态,显性电平的名字就是这样来的,即可以认为显性具有优先的意味。
四、CAN的通讯逻辑(协议层)
4.1 位时序分解
位时序是指在CAN总线上传输每个二进制位时的物理层信号表示方式,包括位的分段(如同步段、传播段、相位缓冲段1和相位缓冲段2)以及如何通过显性电平(通常为逻辑0)和隐性电平(通常为逻辑1)来编码信息。位时序确保了网络上所有节点能够同步并正确解读信号,即便它们的晶振存在微小的频率偏差。例如,位时序定义了位的采样点位于哪里,以确保数据的准确读取
SS 段、 PTS 段、PBS1 段、PBS2 段,这四段的长度加起来即为一个 CAN 数据位的长度。分解后最小的 时间单位是 Tq,而一个完整的位由 8~25 个 Tq 组成。。信号的采样点位于 PBS1 段与 PBS2 段之间,通过控制各段的长度,可以对采样点的位置进行偏移,以便准确地采样。
4.1.1 SS 段 (SYNC SEG)
SS 译为同步段,若通讯节点检测到总线上信号的跳变沿被包含在 SS 段的范围之内,则表示节点 与总线的时序是同步的,当节点与总线同步时,采样点采集到的总线电平即可被确定为该位的电 平。SS 段的大小固定为 1Tq。
4.1.2 PTS 段 (PROP SEG)
PTS 译为传播时间段,这个时间段是用于补偿网络的物理延时时间。是总线上输入比较器延时和 输出驱动器延时总和的两倍。PTS 段的大小可以为 1~8Tq。
4.1.3 PBS1 段 (PHASE SEG1)
PBS1 译为相位缓冲段,主要用来补偿边沿阶段的误差,它的时间长度在重新同步的时候可以加 长。PBS1 段的初始大小可以为 1~8Tq。
4.1.4 PBS2 段 (PHASE SEG2)
PBS2 这是另一个相位缓冲段,也是用来补偿边沿阶段误差的,它的时间长度在重新同步时可以 缩短。PBS2 段的初始大小可以为 2~8Tq。
4.2 通讯的波特率
总线上的各个通讯节点只要约定好 1 个 Tq 的时间长度以及每一个数据位占据多少个 Tq,就可以 确定 CAN 通讯的波特率。
例如,假设上图中的 1Tq=1us,而每个数据位由 19 个 Tq 组成,则传输一位数据需要时间 T1bit =19us,从而每秒可以传输的数据位个数为:
1x10^6 /19 = 52631.6 (bps)
这个每秒可传输的数据位的个数即为通讯中的波特率。
4.3 CAN 的报文种类及结构
在 SPI 通讯中,片选、时钟信号、数据输入及数据输出这 4 个信号都有单独的信号线,I2C 协议 包含有时钟信号及数据信号 2 条信号线,异步串口包含接收与发送 2 条信号线,这些协议包含的 信号都比 CAN 协议要丰富,它们能轻易进行数据同步或区分数据传输方向。而 CAN 使用的是 两条差分信号线,只能表达一个信号,简洁的物理层决定了 CAN 必然要配上一套更复杂的协议, 如何用一个信号通道实现同样、甚至更强大的功能呢?CAN 协议给出的解决方案是对数据、操 作命令 (如读/写) 以及同步信号进行打包,打包后的这些内容称为报文。
4.3.1 数据帧
数据帧则是CAN协议中用于实际传输数据的基本单元,它由多个有序的位域组成。数据帧中的每一个位都是按照位时序的规则进行发送和接收的。因此,位时序定义了数据帧中每个位的物理表现形式,而数据帧则是在这一时序基础上组织起来的、具有特定结构和意义的信息包。简而言之,位时序是CAN通信的物理基础,而数据帧是这个基础之上承载的实际数据和控制信息的结构化表达。
数据帧是在 CAN 通讯中最主要、最复杂的报文,它以一个显性位(逻辑 0)开始,以 7 个连续的隐性位(逻辑 1)结束。在它们之间,分为仲裁段、控制段、数据段、CRC 段和 ACK 段,以标准数据帧为例。
域段 | 域段名 | 位宽:bit | 描述 |
---|---|---|---|
帧起始 | SOF(Start Of Frame) | 1 | 数据帧起始标志,固定为1bit显性('b0) |
仲裁段 | Identify(ID) | 11 | 本数据帧的 ID 信息, ID 信息的作用:① 如果同时有多个节点发送数据时,作为优先级依据(仲裁机制);② 目标节点通过 ID 信息来接受数据(验收滤波技术) |
RTR | Remote Transmission Request BIT | 1 | RTR标识是否是远程帧(0,数据帧;1,远程帧),在数据帧里这一位为显性('b0) |
IDE | Identifier Extension Bit | 1 | IDE用于区分标准格式与扩展格式,在标准格式中 IDE 位为显性(‘b0),在扩展格式里 IDE 位为隐性(’b1) |
SRR | (Substitute Remote Request Bit | 只存在于扩展格式,它用于替代标准格式中的 RTR 位。 由于扩展帧中的 SRR 位为隐性位,RTR 在数据帧为显性位,所以在两个 ID 相同的标准格式报文 与扩展格式报文中,标准格式的优先级较高 | |
R0 R1 | 保留位 | 1 | 1bit保留位,默认设置为显性位,固定为1'b0 |
DLC | data length | 4 | 由 4 位组成,MSB 先行(高位先行),它的二进制编码用于表示本报文中的数据段含有多少个字节,DLC 段表示的数字为0到8,若接收方接收到 9~15 的时候并不认为是错误 |
数据段 | data | 0~64 | 据帧的核心内容,它由 0~8 个字节(0 ~ 64位)组成,MSB 先行 |
CRC段 | CRC | 15 | 段用于检查帧传输错误,发送方以一定的方法计算包括:帧起始、仲裁段、控制段、数据段;接收方以同样的算法计算 CRC 值并进行比较,如果不同则会向发送端反馈出错信息,重新发送;计算和出错处理一般由 CAN 控制器硬件完成或由软件控制最大重发数。 |
CRC界定符 | 1 | CRC 界定符(用于分隔的位),为隐性位(1'b1),主要作用是把CRC 校验码与后面的 ACK 段间隔起来 | |
ACK 槽 | ACK slot | 1 | 在 ACK 槽位中,发送端发送的为隐性位,而接收端则在这一位中发送显性位以示应答;发送 ACK/返回 ACK这个过程使用到回读机制,即发送方先在 ACK 槽发送隐性位后,回读到的总线上的电平为显性0,发送方才知道它发送成功了,不用重发 |
ACK界定符 | 1 | 在 ACK 槽和帧结束之间由 ACK 界定符间隔开,为隐性位 | |
帧结束 | EOF | 7 | 由发送端发送 7 个隐性位表示结束 |
比如总线上有3个节点,节点1设置ID为000101 00010,节点2验收滤波ID表中有节点1的ID号,而节点3中的验收滤波ID表中没有节点1的ID号,节点1向节点2发送1字节的信息。
报文信息:
通过总线发送时,在ID信息发送阶段,只有节点2才能收到总线上的数据,因为节点3的验收滤波ID表中没有节点1的ID号
在报文发送到ACK槽时,会等待并回读节点2的反馈,从节点2的角度看,此时总线为空闲状态,当验证CRC正确,则向总线发送显性电平,接着当节点1回读到显性电平,才会继续发送剩下的EOF
4.3.2 遥控帧
接收单元向发送单元请求发送数据所用的帧。遥控帧由 6 个段组成。遥控帧没有数据帧的数据段。举个例子,车钥匙需要知道车门的状态,一个远程帧过去,车门把自己的状态发回来了。
遥控帧与数据帧的不同之处:
- 遥控帧的 RTR 位为隐性位,没有数据段;
- 没有数据段的数据帧和遥控帧可通过 RTR 位区别开来;
- 遥控帧的数据长度码以所请求数据帧的数据长度码表示;
4.3.3 错误帧
用于在接收和发送消息时检测出错误通知错误的帧。错误帧由错误标志和错误界定符构成。
(1) 错误标志
错误标志包括主动错误标志和被动错误标志两种。
① 主动错误标志:6 个位的显性位。
② 被动错误标志:6 个位的隐性位。
(2) 错误界定符
错误界定符由 8 个位的隐性位构成。
(3)错误标志之后还有0~6个错误标志重叠部分
处于主动错误状态的节点检测到错误时会发送主动错误标志,6个连续显性位会违反位填充规则和位场的固定形式,进而造成其它节点也检测到错误并发送错误标志。所有节点所发送的显性序列叠加组成错误标志重叠部分,错误标志重叠部分的长度在6-12个显性位之间。
对主动错误和被动错误的通俗理解:
首先建议把广泛使用的“主动错误”和“被动错误”概念换成“主动报错”和“被动报错”。
1.主动报错站点
只要检查到错误,它立即“主动地”发出错标识。所谓“出错标识“,它本身就是一个“错误的位序列”(连续的6 个显性位,不满足CAN协议的“最多5个连续的同性位”要求),目的是“主动地”告诉大家:即使你们没有发现“刚才我已发现”的错误,现在我“以身作则”出错啦!你们该看到这个错误了吧!
2.被动报错站点
如果检查到错误,它只能干瞪眼“被动地”等别人(主动报错站点)报错,等待的时候它可不能去动总线,直到识别出由主动报错站点发出的“错误的位序列”,它才松了一口气:有人正式报错了!然后他就可以去竞争总线,该干啥干啥。
4.3.4 过载帧
过载帧是接收节点向总线上其它节点报告自身接收能力达到极限的帧,可以理解为:接收节点Node_A接收报文的能力达到极限了,于是Node_A就会发出过载帧来告诉总线上的其它节点(包括发送节点),我接收节点Node_A已经没有能力处理你们发来的报文了。过载帧由过载标志和过载界定符构成。
(1) 过载标志
6 个位的显性位。
过载标志的构成与主动错误标志的构成相同。
(2) 过载界定符
8 个位的隐性位。
过载界定符的构成与错误界定符的构成相同。
4.3.5 帧间隔
帧间隔是用于分隔数据帧和遥控帧的帧。数据帧和遥控帧可通过插入帧间隔将本帧与前面的任何帧(数据帧、遥控帧、错误帧、过载帧)分开。过载帧和错误帧前不能插入帧间隔。
(1) 间隔
3 个位的隐性位。
(2) 总线空闲
隐性电平,无长度限制(0 亦可)。
本状态下,可视为总线空闲,要发送的单元可开始访问总线。
(3) 延迟传送(发送暂时停止)
8 个位的隐性位。
只在处于被动错误状态的单元刚发送一个消息后的帧间隔中包含的段。
硬件相关
1、CAN收发器芯片
芯片有:TJA1050、TJA1042、SIT1050T、ISO1050