前言
CAN通信与IIC、SPI等通信协议不太一样,它是一种局域网络通信,是由博世最早开发的。最开始主要用于汽车,现在很多地方都用到了。
汽车通信网络如下图
CAN通信主要有以下几个特点:
- 多主控制:总线空闲时,所有单元都可以发送消息,多个单元同时发送消息时,根据标识符ID(表示访问总线优先级)进行仲裁
- 系统柔软性:与总线相连的各个单元没有地址,所以增加单元时不需要改什么
- 通信速度快、距离远:最高 1Mbps(距离小于 40M),最远可达 10KM(速率低于 5Kbps)
- 具有错误检测、错误通知和错误恢复功能:所有单元都可以检测错误(错误检测功能),检测出错误的单元会立即同时通知其他所有单元(错误通知功能),正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制结束发送的单元会不断反复地重新发送此消息直到成功发送为止(错误恢复功能)
- 故障封闭功能:CAN 可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。由此功能,当总线上发生持续数据错误时,可将引起此故障的单元从总线上隔离出去。
电器属性
CAN 总线使用两根线来连接各个单元: CAN_H 和 CAN_L。CAN 总线电平分为显性电平和隐性电平两种。显性电平表示逻辑“0”,此时 CAN_H 电平比 CAN_L 高,分别为 3.5V 和 1.5V,电位差为 2V。隐形电平表示逻辑“1”,此时 CAN_H 和 CAN_L 电压都为 2.5V 左右,电位差为 0V。如图
总线空闲状态的时候一直处于隐性,CAN 网络中的所有单元都通过 CAN_H 和 CAN_L 这两根线连接在一起,如图
CAN协议标准
CAN 协议提供了 5 种帧格式来传输数据:数据帧、遥控帧、错误帧、过载帧和帧间隔。
其中数据帧和遥控帧有标准格式和扩展格式两种,标准格式有 11 位标识符(ID),扩展格式有 29 个标识符(ID)。
数据帧
如下图:
看到这图可能很多人觉得太复杂,我们一点一点的分析(灰色是显性,白色隐形)
帧起始:起始就是发送一个显性电平
仲裁帧:仲裁帧表示优先级,标准格式和扩展格式的仲裁段不同。标准格式的 ID 为 11 位,发送顺序是从 ID10 到 ID0,最高 7 位 ID10~ID4 不能全为隐性,也就是禁止 0X1111111XXXXX这样的ID。扩展格式的 ID 为 29 位,基本 ID 从 ID28 到 ID18,扩展 ID 由 ID17 到 ID0,基本ID 与标准格式一样,禁止最高 7 位都为隐性。
怎么仲裁?
单元 1 和单元 2 同时开始向总线发送数据,开始部分他们的数据格式是一样的,故无法区分优先级,直到 T 时刻,单元 1 输出隐性电平,而单元 2 输出显性电平, 此时单元 1 仲裁失利转入接收状态,单元2继续发送。与我们的ID对比,就是0是显性,1是隐形。.
控制段:控制段由 6 个位构成,表示后面数据段的字节数。标准格式和扩展格式的控制段略有不同
扩展格式中上面IDE处为r1,r1 和 r0 为保留位,保留位必须以显性电平发送。DLC 段有效值范围为 0~8(因为后面数据段最多8字节)
数据段:数据段标准格式和扩展格式相同,可以包含 0~8 个字节的数据。
CRC段:CRC 段保存 CRC 校准值,用于检查帧传输错误,标准格式和扩展格式相同。CRC 段由 15 位的 CRC 值与 1 位的 CRC 界定符组成。 CRC 值的计算范围包括:帧起始、仲裁段、控制段、数据段,接收方以同样的算法进行计算,然后用计算得到的 CRC 值与此 CRC 段进行比较,如果不一致的话就会报错。
ACK段:ACK 段由 ACK 槽(ACK Slot)和 ACK 界定符两部分组成。 发送单元的 ACK,发送 2 个隐性位,而接收到正确消息的单元在 ACK 槽(ACK Slot)发送显性位
帧结束:由7位隐性位组成。
遥控帧
遥控帧结构基本和数据帧一样,最主要的区别就是遥控帧没有数据段。遥控帧的 RTR 位为隐性的,数据帧的 RTR 位为显性,因此可以通过 RTR 位来区分遥控帧和没有数据的数据帧,如图:
错误帧
当接收或发送消息出错的时候使用错误帧来通知,错误帧由错误标志和错误界定符两部分组成,错误标志有主动错误标志和被动错误标志两种,主动错误标志是 6 个显性位,被动错误标志是 6 个隐性位,错误界定符由 8 个隐性位组成。如图:
过载帧
接收单元尚未完成接收准备的话就会发送过载帧,过载帧由过载标志和过载界定符构成,过载标志由 6 个显性位组成,过载界定符由 8 个隐性位组成。如图:
间隔帧
帧间隔用于分隔数据帧和遥控帧,数据帧和遥控帧可以通过插入帧间隔来将本帧与前面的任何帧隔开,过载帧和错误帧前不能插入帧间隔。如图:
间隔由 3 个隐性位构成,总线空闲为隐性电平,长度没有限制,本状态下表示总线空闲,发送单元可以访问总线。延迟发送由 8 个隐性位构成,处于被动错误状态的单元发送一个消息后的帧间隔中才会有延迟发送。(只知道是间隔的,有点没太懂这个图)
CAN通信速率
CAN通信以帧形式发送数据,帧由位构成,一个位由 4 个段构成:
①、同步段(SS)
②、传播时间段(PTS)
③、相位缓冲段 1(PBS1)
④、相位缓冲段 2(PBS2)
每个段又由若干个 Tq (Tq 是 CAN 总线的最小时间单位)组成。通过设定位时序,多个单元可同时采样,也可任意设定采样点。各段的作用和 Tq 数如图:
这多了个SJW,后面写代码的时候再来看看这些各个段
到这里基本要点都讲完了,总结来看协议主要格式就是三部分:电器属性(线性电平和隐性电平)、CAN里特有的几个帧格式(每种帧有哪几个段)、位格式(一位数据里包含哪些)
imx6ull里的CAN外设
I.MX6ULL 带有 CAN 控制器外设,叫做 FlexCAN, FlexCAN 符合 CAN2.0B 协议。 FlexCAN
完全符合CAN协议,支持标准格式和扩展格式,支持 64个消息缓冲。这里就不介绍了
FlexCAN 支持四种模式:正常模式(Normal)、冻结模式(Freeze)、仅监听模式(Listen-Only)和回环模式(Loop-Back),另外还有两种低功耗模式:禁止模式(Disable)和停止模式(Stop)。大家感兴趣可以自行查阅
看看原理图
这里连接的TJA1050 是 CAN 收发器,通过 TJA1050向外界提供 CAN_H 和 CAN_L 总线
驱动代码待续……