CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO 国际标准化的串行通信协议。在当前的汽车产业中,出于对安全性、舒适性、方便性、低公害、低成本的要求,各种各样的电子控制系统被开发了出来。为适应“减少线束的数量”、“通过多个 LAN,进行大量数据的高速通信”的需要, 1986 年德国电气商博世公司开发出面向汽车的 CAN 通信协议。此后, CAN 通过 ISO11898 及ISO11519进行了标准化,现在在北美和西欧已是汽车网络的标准协议。
如今, CAN 的高性能和可靠性已被认同,并被广泛地应用于工业自动化、船舶、医疗设备、工业设备等方面。现场总线是当今自动化领域技术发展的热点之一,被誉为自动化领域的计算机局域网。它的出现为分布式控制系统实现各节点之间实时、可靠的数据通信提供了强有力的技术支持。
目录
前言
在学习stm32通信的过程中,USART、I2C、SPI有很多优秀的视频和文章供大家学习和应用,而CAN却不容易掌握。本文章是作者在学习CAN的过程中查阅大量资料后,将知识点融汇贯通,内容较多,但相信读者在仔细阅读和认真思考后会有醍醐灌顶的感觉。此外,若文章有错误或者需要改进的地方,请评论或私信作者。望共勉!
一、CAN的数据指标和特点
1.数据指标
-
有一个CAN总线(stm32f103c8t6 )
-
可以发送和接收11位标识符的标准帧
-
可以发送和接收29位标识符的扩展帧
-
3个发送邮箱
-
2个FIFO
-
3级14个可调节的滤波器
2.特点
-
多主控制 总线空闲时,所有单元都可发送消息,而两个以上的单元同时开始发送消息时,根据标识符(ID,非地址)决定优先级。两个以上的单元同时开始发送消息时,对各消息ID的每个位进行逐个仲裁比较。仲裁获胜(优先级最高)的单元可继续发送消息,仲裁失利的单元立刻停止发送而进行接收工作
-
系统柔软性 连接总线的单元没有类似“地址”的信息(地址需要分配),因此,在总线上添加单元时,已连接的其他单元的软硬件和应用层都不需要做改变
-
速度快距离远 最高1Mbps(距离 < 40m),最远可达10km(速率 < 5kbps)
-
具有错误检测、错误通知和错误恢复功能 所有单元都可以检测错误(错误检测功能),检测出错误的单元会立即同时通知其他所有单元(错误通知功能),正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制结束发送的单元会不断反复地重新发送此消息直到成功发送为止(错误恢复功能)
-
故障封闭功能 CAN可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。由此功能,当总线上发生持续数据错误时,可将引起此故障的单元从总线上隔离出去
-
连接节点多 CAN总线是可同时连接多个单元的总线。可连接的单元总线理论上是没有限制的。但实际上可连接的单元数受总线上的时间延迟及电器负载的限制。降低通信速度,可连接的单元数增加;提高通信速度,可连接的单元数减少。
-
波特率 由于 CAN 属于异步通讯,没有时钟信号线,连接在同一个总线网络中的各个节点会像串口异步通讯那样,节点间使用约定好的波特率进行通讯,特别地, CAN 还会使用“位同步”的方式来抗干扰、吸收误差,实现对总线电平信号进行正确的采样,确保通讯正常。
CAN总线是基于相同波特率通信的,所以设备介入前要知道总线上的波特率是多少
波特率 = 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
-
数据数量 一次最多只能发送8个字节的数据,多于8个的需要第二次再发送,或者做一个上层的连续多数据发送的函数
3.其他功能
- 工作模式:正常,睡眠,测试
- 测试模式中包括:静默、环回、环回静默
- 时间接触通信模式
- 寄存器访问保护
- 中断
- 记录接收SOF时刻的时间戳
这些功能在CAN总线基本的收发之外,提供了更多的应用方式
二、结构
1.控制器与收发器 
可以看到,CPU如果想要通过CAN总线发送和接收消息其实还需要两个“帮手”——CAN控制器和CAN收发器 。如果是使用8051单片机则需要连接SIA1000等CAN控制器,而stm32则已经集成了CAN的控制器,只需要接TJA1050(ISO 11898标准)或其他CAN收发器即可。
TJA1050采用的是ISO11898
控制器与收发器之间通过 CAN_Tx 及CAN_Rx 信号线相连,收发器与 CAN 总线之间使用 CAN_High 及 CAN_Low 信号线相连。其中CAN_Tx 及 CAN_Rx 使用普通的类似 TTL 逻辑信号,而 CAN_High 及 CAN_Low 是一对差分信号线(抗干扰能力强)。
CAN 控制器与 CAN收发器的关系如同 TTL 串口与 MAX3232 电平转换芯片的关系, MAX3232 芯片把 TTL 电平的串口信号转换成 RS-232 电平的串口信号,CAN 收发器的作用则是把 CAN 控制器的 TTL 电平信号转换成差分信号 (或者相反) 。
2.闭环总线网络
CAN 物理层的形式主要有两种,分别为闭环总线网络和开环总线网络
图中的 CAN 通讯网络是一种遵循 ISO11898 标准的高速、短距离“闭环网络”,它的总线最大长度为 40m,通信速度最高为 1Mbps,总线的两端各要求有一个“120 欧”的电阻
120Ω终端电阻作用:
- 用来做阻抗匹配,以减少回波反射
- 在没有设备操作总线的时候,将两根线的电压拉到同一水平。
当某个设备想发送0时,他就会操作总线,把总线“拉开”,也就是产生电压差,使其呈现0状态;当设备想发送1时,就不去碰总线,总线在终端电阻的收缩下,自动归位默认状态1。(与I2C的上拉电阻相似)
3.开环总线网络
图中的CAN 通讯网络是遵循 ISO11519-2 标准的低速、远距离“开环网络”,它的最大传输距离为 1km,最高通讯速率为 125kbps,两根总线是独立的、不形成闭环,要求每根总线上各串联有一个“2.2千欧”的电阻。
4.差异
- 总线电平 = CAN_H的电压 - CAN_L的电压
- 显性电平对应逻辑0 = 总线电平为2V左右
- 隐性电平对应逻辑1 = 总线电平为0V左右
- 显性电平具有优先权,只要有一个单元输出显性电平,总线上即为显性电平
- 隐形电平则具只有所有的单元都输出隐形电平,总线上才为隐形电平
- 显性电平比隐形电平更强,优先级高
三、通信过程
通过CAN总线发送和接收的是报文。CPU先将报文存放在发送邮箱中再进行发送,发送邮箱有三个。当发送节点想要发送新数据但发送邮箱已被其他数据占用时,它会不断尝试发送数据,直到发送成功或达到了预设的重传次数。这种重传机制使得即使发送邮箱繁忙,数据也不会被丢弃,而是会被推迟发送,直到发送邮箱可用。而在接收过程中,报文会先被过滤器筛选,只有通过过滤器的报文才会被存储到FIFO0或者FIFO1接收邮箱中。
1.空闲状态
在CAN协议中,当总线上的上出现连续的11位隐性电平时,表示总线就处于空闲状态。也就是说对于任意一个节点而言,只要它监听到总线上连续出现了11位隐性电平,那么该节点就会认为总线当前处于空闲状态。
怎么让总线连续出现11位隐形电平呢?由于显性电平的高优先级特性,必须所有CAN主机都连续发送11个隐性电平,或者不发送时,总线才能出现连续11个隐性电平,即处于空闲状态。
通过后续报文的学习,我们可以知道,11位隐性电平其实是1位ACK界定符+7位帧结束EOF段+3位帧间隔
2.发送
蓝色虚线框表示单片机内部的CAN总线控制器
在发送过程中首先需要了解几个名词,后续会有详细介绍
-
报文(数据包/帧):CAN设备一次发送出去的完整数据信息
-
邮箱:用于发送报文的发送调度器
-
帧种类:不同用途的报文种类。数据帧、遥控帧、错误帧、过载帧、帧间隔
-
数据帧:用于发送单元向接收单元传送数据的帧(广播式)
-
遥控帧/远程帧:用于接收单元向具有相同的ID的发送单元请求数据的帧(请求式)
-
错误帧:用于当检测出错误时向其他单元通知错误的帧
-
过载帧:用于接收单元通知其尚未做好接收准备的帧
-
帧间隔:用于将数据帧及遥控帧于前面的帧分离开来的帧
-
用户控制的只有前两个
-
-
帧格式:一个报文里包含的内容格式
-
标识符:CAN总线上的设备可以用此判断数据是不是发给自己的
数据帧和遥控帧有标准格式和扩展格式两种格式
3.接收
-
所有设备都会接收报文,但标识符不符的报文会被过滤器删除
-
接收邮箱于发送邮箱有所不同
接收邮箱
-
FIFO:表面的意思是“先入先出”,是指有层级深度的接收邮箱
-
STM32F103系列单片机上有2个FIFO邮箱,每个FIFO有3层深度。即可以存放6组数据
-
与过滤器匹配的报文会被放入FIFO邮箱
四、报文
在 SPI 通讯中,片选、时钟信号、数据输入及数据输出这 4 个信号都有单独的信号线,I2C 协议包含有时钟信号及数据信号 2 条信号线,异步串口包含接收与发送 2 条信号线,这些协议包含的信号都比 CAN 协议要丰富,它们能轻易进行数据同步或区分数据传输方向。而 CAN 使用的是两条差分信号线,只能表达一个信号,简洁的物理层决定了 CAN 必然要配上一套更复杂的协议,如何用一个信号通道实现同样、甚至更强大的功能呢?CAN 协议给出的解决方案是对数据、操作命令 (如读/写) 以及同步信号进行打包,打包后的这些内容称为报文。
在原始数据段的前面加上传输起始标签、片选 (识别) 标签和控制标签,在数据的尾段加上 CRC校验标签、应答标签和传输结束标签,把这些内容按特定的格式打包好,就可以用一个通道表达各种信号了,各种各样的标签就如同 SPI 中各种通道上的信号,起到了协同传输的作用。当整个数据包被传输到其它设备时,只要这些设备按格式去解读,就能还原出原始数据,这样的报文就被称为 CAN 的“数据帧”。