CAN总线协议和应用示例

您所在的位置:网站首页 can总线数据报文格式 CAN总线协议和应用示例

CAN总线协议和应用示例

2024-07-12 07:00| 来源: 网络整理| 查看: 265

1 CAN总线介绍 1.1 什么是CAN

CAN ( Controller Area Network),也就是控制局域网络,简称为 CAN。CAN 最早是 由德国 BOSCH(博世)开发的,目前已经是国际标准(ISO 11898),是当前应用最广泛的现场总线 之一。BOSCH 主要是做汽车电子的,因此 CAN 一开始主要是为汽车电子准备的,事实也是如此,CAN 协议目前已经是汽车网络的标准协议。

下图以汽车电子为例,汽车上有空调、车门、发动机、大量传感器等,这些部件都是通过 CAN 总线连在一起形成一个局域网络。

image

can总线下有分不同的can网络,每个can网络速率会不一样比如125Kbps的网络和500Kbps,每个网络下的can单元就是一个节点,同一网络下的单元速率必须保持统一。

1.2 应用领域

CAN 总线主要应用于汽车电子和工业领域,尤其是汽车领域,汽车上大量的传感器与模块都是通过 CAN 总线连接起来的。CAN 总线目前广泛的应用于工业自动化、船舶、汽 车、医疗和工业设备等方面。

1.3 CAN 的特点 多主控制

在总线空闲时,所有单元都可以发送消息(多主控制),而两个以上的单元同时开始发送消息时,根据标识符(Identifier 以下称为 ID)决定优先级。ID 并不是表示发送的目的地址,而是表示访问总线的消息的优先级。两个以上的单元同时开始发送消息时,对各消息ID的每个位进行逐个仲裁比较。仲裁获胜(被判定为优先级最高)的单元可继续发送消息,仲裁失利的 单元则立刻停止发送而进行接收工作。

系统的柔软性

与总线相连的单元没有类似于“地址”的信息。因此在总线上增加单元时,连接在总线上的其它单元的软硬件及应用层都不需要改变。

通信速度快,距离远

最高 1Mbps(距离小于 40M),最远可达 10KM(速率低于 5Kbps)

CAN 总线传输速度可达 1Mbps/S,最新的 CAN-FD 最高速度可达 5Mbps/S,甚至更高。CAN 传输速度和总线距离有关, 总线距离越短,传输速度越快。

具有错误检测、错误通知和错误恢复功能

所有单元都可以检测错误(错误检测功能),检测出错误的单元会立即同时通知其他所有单 元(错误通知功能),正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制结束 发送的单元会不断反复地重新发送此消息直到成功发送为止(错误恢复功能)。

故障封闭功能

当总线上某个单元发生持续数据错误时,可将引起此故障的单元从总线上隔离出去。

连接节点多

CAN 总线是可同时连接多个单元的总线。可连接的单元总数理论上是没有限制的。但实际 上可连接的单元数受总线上的时间延迟及电气负载的限制。降低通信速度,可连接的单元数增 加;提高通信速度,则可连接的单元数减少。

1.4 CAN 电气属性 1.4.1 can总线逻辑电平

image

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 这两根线连接在一起:

image

每个单元的CAN_H 接总线的CAN_H、CAN_L接总线的CAN_L,CAN 总线两端要各接一个 120Ω的端接电阻,用于匹配总线阻抗, 吸收信号反射及回拨,提高数据通信的抗干扰能力以及可靠性。

1.5 CAN硬件原理图

image

TJA1050 是 一个CAN 收发器,通过 TJA1050 向外界提供 CAN_H 和 CAN_L 总线,R10 是一个 120 欧的端接匹配电阻。

2 CAN 协议 2.1 5种帧类型

CAN 协议提供了 5 种帧格式来传输数据:

帧类型 帧用途 数据帧 用于 CAN 节点单元之间进行数据传输的帧 遥控帧 用于接收单元向具有相同 ID 的发送单元请求数据的帧 错误帧 用于当检测出错误时向其它单元通知错误的帧 过载帧 用于接收单元通知其尚未做好接收准备的帧 间隔帧 用于将数据帧及遥控帧与前面的帧分离开来的帧

那么数据帧和遥控帧有标准格式和扩展格式两种,标准格式有 11 位标识符(ID),扩展格式有 29 个标识符(ID).

2.1.1 数据帧结构

image

可以看到无论是标准格式还是扩展格式,一共7个字段:

帧起始,表示数据帧开始的段。 仲裁段,表示该帧优先级的段。 控制段,表示数据的字节数及保留位的段。 数据段,数据的内容,一帧可发送 0~8 个字节的数据。 CRC 段,检查帧的传输错误的段。 ACK 段,表示确认正常接收的段。 帧结束,表示数据帧结束的段。 2.1.1.1 帧起始

无论是标准格式还是扩展格式,都是由一个位的显性电平 0 来表示帧起始。

2.1.1.2 仲裁段

表示帧的优先级,如下:

image

标准格式的ID为11位,ID10 到 ID0,最高 7 位 ID10~ID4 不能全为隐性(1),也就是禁止 0X1111111XXXX。

扩展格式的ID为29位,基本 ID [ID28~ID18],扩展 ID[ID17~ID0]。 基本 ID 与标准格式一样,禁止最高 7 位都为隐性。

2.1.1.3 控制段

表示数据的字节数及保留位。

image

前面r1 和 r0 为保留位,保留位必须以显性电平发送。DLC 为数据长度,高位在前,DLC 段有效值范围为 0~8。

2.1.1.4 数据段

image

传输的数据包含 0~8 个字节。MSB高位先传。上面数据段的 0~64 为 bit,对应到字节就是 0~8 字节。

2.1.1.5 CRC段

用来数据校验,CRC 校准。检查帧传输错误。

image

CRC 段由 15 位的 CRC 值与 1 位的 CRC 界定符组成。计算帧的CRC值 与此CRC段进行比较,不一样就校验不成功。

2.1.1.6 ACK段

用来确认接收是否正常.

image

ACK 段包含 ACK 槽(ACK Slot)和 ACK 界定符。

发送ACK: 发送单元的 ACK,发送 2 个隐性位:11. 接收ACK: 接收单元在 ACK 槽(ACK Slot)发送显性位:0 2.1.1.7 帧结束

image

帧结束由7位隐性位1组成。

2.1.2 遥控帧结构

什么时候开始去发收据帧呢?肯定要有人去控制,去请求啊,接收单元向发送单元请求数据的时候就用遥控帧。

遥控帧只有6个字段,和数据帧相比少了数据段。

image

遥控帧的 RTR 位为隐性的,数据帧的 RTR 位为显性,因此可以通过 RTR 位来区分遥控帧和没有数据的数据帧。遥控帧没有数据,因此 DLC 表示的是所请求的数据帧数据长度,遥控帧的其他段参考数据帧的描述即可。

2.1.3 错误帧结构

接收或发送消息出错的时候使用错误帧来通知。

image

错误帧=错误标志+错误界定符。

错误标志有主动错误标志和被动错误标志两种,主动错误标志是 6 个显性位,被动错误标志是 6 个隐性位,错误界定符由 8 个隐性位组成。

2.1.4 过载帧

接收单元尚未完成接收准备的话就会发送过载帧.

过载帧 = 过载标志 + 过载界定符

image

过载标志由 6 个显性位组成,与主动错误标志相同,过载界定符也是由 8 个隐性位组成,和错误界定符相同。

2.1.5 帧间隔

用于分隔数据帧和遥控帧。

image

3个隐性位+ n个隐性位(总线空闲)或者 3个隐性位+ 8个隐性位(延迟传送)+ n个隐性位(总线空闲)

注意:过载帧和错误帧前不能插入帧间隔。

2.2 CAN总线仲裁过程

image

当多个单元同时开始发送时,各发送单元从仲裁段的第一位开始进行仲裁。连续输出显性电平最多的单元可继续发送。

上图可以看到单元1的仲裁段显性电平没有单元2多,因此仲裁失利,立刻转入接收状态工作,不再与单元 2 竞争,而单元 2 则顺利获得总线使用权,继续发送自己的数据。

2.3 CAN位时序

CAN 总线,一个位分为 4 段:

同步段(SS) 传播时间段(PTS) 相位缓冲段 1(PBS1) 相位缓冲段 2(PBS2)

image

这些段由 Tq(Time Quantum)组成,Tq 是 CAN 总线的最小时间单位。1 位由多少个 Tq 构成。

总结:帧由位构成,一个位 由 4 个段构成,每个段又由若干个 Tq 组成。

2.3.1 1个位的四段含义

image

3 CAN主控-以imx6ull芯片为例

飞思卡尔恩智浦 I.MX6ULL 芯片带有 CAN 控制器,叫做FlexCAN,FlexCAN 符合 CAN2.0B 协议,速率高达1Mbps。

3.1 FlexCAN特性 支持 CAN2.0B 协议,数据帧和遥控帧支持标准和扩展两种格式,数据长度支持 0~8 字 节,可编程速度,最高 1Mbit/S。 灵活的消息邮箱,最高支持 8 个字节。 每个消息邮箱可以配置为接收或发送,都支持标准和扩展这两种格式的消息。 每个消息邮箱都有独立的接收掩码寄存器 强大的接收 FIFO ID 过滤。 未使用的空间可以用作通用 RAM。 可编程的回测模式,用于进行自测。 可编程的优先级组合。 3.2 FlexCAN工作模式

正常模式(Normal)、冻结模式(Freeze)、仅监听模式(Listen-Only)和 回环模式(Loop-Back),另外还有两种低功耗模式:禁止模式(Disable)和停止模式(Stop)。

3.2.1 正常模式(Normal)

正常模式下,FlexCAN 正常接收或发送消息帧,所有的 CAN 协议功能都使能。

3.2.2 冻结模式(Freeze)

当 MCR 寄存器的 FRZ 位置 1 的时候使能此模式,在此模式下无法进行帧的发送或接收, CAN 总线同步丢失。

3.2.3 仅监听模式(Listen-Onley)

当 CTRL 寄存器的 LOM 位置 1 的时候使能此模式,在此模式下帧发送被禁止,所有错误 计数器被冻结,CAN 控制器工作在被动错误模式,此时只会接收其他 CAN 单元发出的 ACK 消 息。

3.2.4 回环模式(Loop-Back)

当 CTRL 寄存器的 LPB 位置 1 的时候进入此模式,此模式下 FlexCAN 工作在内部回环模 式,一般用来进行自测。从模式下发送出来的数据流直接反馈给内部接收单元。

3.3 FlexCAN 控制寄存器 CTRL设置 3.3.1 位时序设置

CTRL 寄存器中的 PRESDIV、PROPSEG、PSEG1、 PSEG2 和 RJW 这 5 个位域用于设置 CAN 位时序。 PRESDIV 为 CAN 分频值,也即是设置 CAN 协议中的 Tq 值,公式如下:

image

fCANCLK: FlexCAN 模块时钟,因 此只需要修改 PRESDIV 即可修改 FlexCAN 的 Tq 频率值。

SS:同步段(Synchronization Segment),在 I.MX6ULL 参考手册中叫做 SYNC_SEG,此段固 定为 1 个 Tq 长度,因此不需要我们去设置。

PTS:传播时间段(Propagatin Segment),FlexCAN 的 CTRL 寄存器中的 PROPSEG 位域设 置此段,可以设置为 0~7,对应 1~8 个 Tq。

PBS1:相位缓冲段 1(Phase Buffer Segment 1),FlexCAN 的 CRTL 寄存器中的 PSEG1 位域 设置此段,可以设置为 0~7,对应 1~8 个 Tq。

PBS2:相位缓冲段 2(Phase Buffer Segment 2),FlexCAN 的 CRTL 寄存器中的 PSEG2 位域 设置此段,可以设置为 1~7,对应 2~8 个 Tq。

SJW:再同步补偿宽度(reSynchronization Jump Width),FlexCAN 的 CRTL 寄存器中的 RJW 位域设置此段,可以设置 0~3,对应 1~4 个 Tq。

最终FlexCAN的位时序如下:

image

3.3.2 计算波特率

那么SYNC+SEG+(PROP_SEG+PSEG1+2)+(PSEG2+1)就是总的 Tq。由此可以算出波特率就是:

𝐶𝐴𝑁波特率 = 𝑓𝑇𝑞 / 总 Tq

4 Linux CAN驱动实验-FlexCAN为例

NXP 原厂已经写好了can总线驱动程序。由于本人没有仔细研究过drivers/net/can/flexcan.c驱动源码,因此不做can驱动源码分析,这里只进行使用测试了解一下。

4.1 dts描述 4.1.1 原理图描述

image

4.1.2 flexcan1节点

打开imx6ull.dtsi,修改can1对应的引脚为自己使用的引脚,这里为uart3的cts和rts。

pinctrl_flexcan1: flexcan1grp{ fsl,pins = < MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX 0x1b020 MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX 0x1b020 >; }; flexcan1: can@02090000 { compatible = "fsl,imx6ul-flexcan", "fsl,imx6q-flexcan"; reg = ; interrupts = ; clocks = , ; clock-names = "ipg", "per"; stop-mode = ; status = "disabled"; };

flexcan1节点默认nxp官方帮我们写好了,可以看到寄存器地址范围,中断引脚,时钟,状态默认是禁用的。因此需要我们外部dts使用的时候去使能它。

打开imx6ull-alientek-emmc.dts,使能该节点

&flexcan1 { pinctrl-names = "default"; pinctrl-0 = ; xceiver-supply = ;//xceiver-supply 属性指定 CAN 收发器的电压为 3.3V status = "okay"; }; 4.2 使能Linux内核中的can驱动 4.2.1 使能 CAN 总线

make menuconfig进入网络子系统。开启如下选项:

-> Networking support -> CAN bus subsystem support

image

4.2.2 使能 Freescale 芯片的FlexCAN驱动 -> Networking support -> CAN bus subsystem support -> CAN Device Drivers -> Platform CAN drivers with Netlink support -> Support for Freescale FLEXCAN based chips //选中

image

image

可以看到选中后drivers/net/can/flexcan.c就会被编译进内核。

4.3 FlexCAN 测试

FlexCAN 驱动工作正常的话就会看到 CAN 对应的网卡接口:

image

4.3.1 移植 iproute2

busybox 自带的 ip 命令并不支持对 can 的操作,移植新的ip命令,也就是iproute2。iproute2 源码:https://mirrors.edge.kernel.org/pub/linux/utils/net/iproute2/

tar -xzf iproute2-4.4.0.tar.gz Makefile把 CC := gcc改为CC:=arm-linux-gnueabihf-gcc make

image

编译完后就会得到ip命令这个可执行程序。替换到板端的默认busybox自带的ip程序。输入:

./ip -V

image

4.3.2 移植 can-utils 工具

can-utils 工具源码: https://sources.buildroot.net/can-utils/

can-utils 这个工具来对 can0 网卡进行测试。我这里下载的can-utils-2020.02.04。

cd can-utils-2020.02.04 //进入 can-utils 源码目录 ./autogen.sh //先执行 autogen.sh,生成配置文件 configure ./configure --target=arm-linux-gnueabihf --host=arm-linux-gnueabihf -- prefix=/home/book/linux/IMX6ULL/tool/can-utils --disable-static --enable-shared //配置 make //编译 make install

编译完后工具如下:

image

4.3.3 CAN硬件准备和测试

准备2块开发板,都有自己的can0单元。将两个开发板的 CAN 接口连接起来,注意,CAN_H 接 CAN_H,CAN_L 接 CAN_L。

image

4.3.3.1 收发测试

ip link set can0 type can bitrate 500000

对2块板子都用该命令设置can参数,设置 can0 速度为 500Kbit/S,两个 CAN 设备的速度要设置为一样的!速度设置好 以后打开 can0 网卡:

ifconfig can0 up //打开 can0

使用 can-utils 里面的小工具进行数据收发测试:

A开发板用来接收数据:

candump can0 //接收数据

B开发板用来发送数据:

cansend can0 5A1#11.22.33.44.55.66.77.88

用 cansend 命令向接收单元发送 8 个字节的数据:0X11、0X22、0X33、 0X44、0X55、0X66、0X77、0X88。

“5A1”是帧 ID,“#”号后面的“11.22.33.44.55.66.77.88” 就是要发送的数据,十六进制。CAN2.0 一次最多发送 8 个字节的数据,8 个字节的数据之间用 “.”隔开。

这时接收的那块板子会打印数据如下:

image

4.3.3.2 回环测试

在一个板子上可以进行 CAN 回环测试,不需要2个can单元。

ifconfig can0 down //如果 can0 已经打开了,先关闭 ip link set can0 type can bitrate 500000 loopback on //开启回环测试 ifconfig can0 up //重新打开 can0 candump can0 & //candump 后台接收数据 cansend can0 5A1#11.22.33.44.55.66.77.88 //cansend 发送数据

如果回环测试成功的话那么开发板就会收到发送给自己的数据如下:

image



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3