CAN总线协议和应用示例 |
您所在的位置:网站首页 › can总线数据报文格式 › CAN总线协议和应用示例 |
1 CAN总线介绍
1.1 什么是CAN
CAN ( Controller Area Network),也就是控制局域网络,简称为 CAN。CAN 最早是 由德国 BOSCH(博世)开发的,目前已经是国际标准(ISO 11898),是当前应用最广泛的现场总线 之一。BOSCH 主要是做汽车电子的,因此 CAN 一开始主要是为汽车电子准备的,事实也是如此,CAN 协议目前已经是汽车网络的标准协议。 下图以汽车电子为例,汽车上有空调、车门、发动机、大量传感器等,这些部件都是通过 CAN 总线连在一起形成一个局域网络。 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总线逻辑电平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_H 接总线的CAN_H、CAN_L接总线的CAN_L,CAN 总线两端要各接一个 120Ω的端接电阻,用于匹配总线阻抗, 吸收信号反射及回拨,提高数据通信的抗干扰能力以及可靠性。 1.5 CAN硬件原理图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 数据帧结构可以看到无论是标准格式还是扩展格式,一共7个字段: 帧起始,表示数据帧开始的段。 仲裁段,表示该帧优先级的段。 控制段,表示数据的字节数及保留位的段。 数据段,数据的内容,一帧可发送 0~8 个字节的数据。 CRC 段,检查帧的传输错误的段。 ACK 段,表示确认正常接收的段。 帧结束,表示数据帧结束的段。 2.1.1.1 帧起始无论是标准格式还是扩展格式,都是由一个位的显性电平 0 来表示帧起始。 2.1.1.2 仲裁段表示帧的优先级,如下: 标准格式的ID为11位,ID10 到 ID0,最高 7 位 ID10~ID4 不能全为隐性(1),也就是禁止 0X1111111XXXX。 扩展格式的ID为29位,基本 ID [ID28~ID18],扩展 ID[ID17~ID0]。 基本 ID 与标准格式一样,禁止最高 7 位都为隐性。 2.1.1.3 控制段表示数据的字节数及保留位。 前面r1 和 r0 为保留位,保留位必须以显性电平发送。DLC 为数据长度,高位在前,DLC 段有效值范围为 0~8。 2.1.1.4 数据段传输的数据包含 0~8 个字节。MSB高位先传。上面数据段的 0~64 为 bit,对应到字节就是 0~8 字节。 2.1.1.5 CRC段用来数据校验,CRC 校准。检查帧传输错误。 CRC 段由 15 位的 CRC 值与 1 位的 CRC 界定符组成。计算帧的CRC值 与此CRC段进行比较,不一样就校验不成功。 2.1.1.6 ACK段用来确认接收是否正常. ACK 段包含 ACK 槽(ACK Slot)和 ACK 界定符。 发送ACK: 发送单元的 ACK,发送 2 个隐性位:11. 接收ACK: 接收单元在 ACK 槽(ACK Slot)发送显性位:0 2.1.1.7 帧结束帧结束由7位隐性位1组成。 2.1.2 遥控帧结构什么时候开始去发收据帧呢?肯定要有人去控制,去请求啊,接收单元向发送单元请求数据的时候就用遥控帧。 遥控帧只有6个字段,和数据帧相比少了数据段。 遥控帧的 RTR 位为隐性的,数据帧的 RTR 位为显性,因此可以通过 RTR 位来区分遥控帧和没有数据的数据帧。遥控帧没有数据,因此 DLC 表示的是所请求的数据帧数据长度,遥控帧的其他段参考数据帧的描述即可。 2.1.3 错误帧结构接收或发送消息出错的时候使用错误帧来通知。 错误帧=错误标志+错误界定符。 错误标志有主动错误标志和被动错误标志两种,主动错误标志是 6 个显性位,被动错误标志是 6 个隐性位,错误界定符由 8 个隐性位组成。 2.1.4 过载帧接收单元尚未完成接收准备的话就会发送过载帧. 过载帧 = 过载标志 + 过载界定符 过载标志由 6 个显性位组成,与主动错误标志相同,过载界定符也是由 8 个隐性位组成,和错误界定符相同。 2.1.5 帧间隔用于分隔数据帧和遥控帧。 3个隐性位+ n个隐性位(总线空闲)或者 3个隐性位+ 8个隐性位(延迟传送)+ n个隐性位(总线空闲) 注意:过载帧和错误帧前不能插入帧间隔。 2.2 CAN总线仲裁过程当多个单元同时开始发送时,各发送单元从仲裁段的第一位开始进行仲裁。连续输出显性电平最多的单元可继续发送。 上图可以看到单元1的仲裁段显性电平没有单元2多,因此仲裁失利,立刻转入接收状态工作,不再与单元 2 竞争,而单元 2 则顺利获得总线使用权,继续发送自己的数据。 2.3 CAN位时序CAN 总线,一个位分为 4 段: 同步段(SS) 传播时间段(PTS) 相位缓冲段 1(PBS1) 相位缓冲段 2(PBS2)这些段由 Tq(Time Quantum)组成,Tq 是 CAN 总线的最小时间单位。1 位由多少个 Tq 构成。 总结:帧由位构成,一个位 由 4 个段构成,每个段又由若干个 Tq 组成。 2.3.1 1个位的四段含义飞思卡尔恩智浦 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 值,公式如下: 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的位时序如下: 那么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 原理图描述打开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可以看到选中后drivers/net/can/flexcan.c就会被编译进内核。 4.3 FlexCAN 测试FlexCAN 驱动工作正常的话就会看到 CAN 对应的网卡接口: 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编译完后就会得到ip命令这个可执行程序。替换到板端的默认busybox自带的ip程序。输入: ./ip -V 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编译完后工具如下: 准备2块开发板,都有自己的can0单元。将两个开发板的 CAN 接口连接起来,注意,CAN_H 接 CAN_H,CAN_L 接 CAN_L。 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 个字节的数据之间用 “.”隔开。 这时接收的那块板子会打印数据如下: 在一个板子上可以进行 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 发送数据如果回环测试成功的话那么开发板就会收到发送给自己的数据如下: |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |