CAN总线通信协议

news2024/11/16 18:06:48

Reference video:
趋近于完美的通讯 CAN总线!4分钟看懂!
CAN通信精华整理,汽车工程师必备技能,一个视频带你轻松掌握!

写在前面:CAN通信就三个要点

- 波特率的配置
- 过滤寄存器的配置与理解(难点)
- 填充发送数据结构体TxMessage,确定帧类型、ID、要发送的数据等

1. CAN简介

1.1 CAN协议的特点

========================了解即可 ==============================

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

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

  • 通信速度较快,通信距离远。最高1Mbps(距离小于40M),最远可达10KM(速率低于5Kbps)。

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

  • 故障封闭功能。CAN 可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。由此功能,当总线上发生持续数据错误时,可将引起此故障的单元从总线上隔离出去。

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

1.2 ISO11898标准

=======知道显性电平和隐性电平的概念,知道多个设备之间如何组网 =============

经常使用的是ISO11898标准,它是针对通信速率为125Kbps~
1Mbps的高速通信标准,标准的物理层特征如图所示:

ISO11898

CAN 控制器根据两根线上的电位差来判断总线电平。总线电平分为显性电平和隐性电平,二者必居其一。发送方通过使总线电平发生变化,将消息发送给接收方。

从该特性可以看出,显性电平对应逻辑0,CAN_H和CAN_L之差为2.5V左右。而隐性电平对应逻辑1,CAN_H和CAN_L之差为0V。在总线上显性电平具有优先权,只要有一个单元输出显性电平,总线上即为显性电平而隐形电平则具有包容的意味,只有所有的单元都输出隐性电平,总线上才为隐性电平(显性电平比隐性电平更强)。另外,在CAN总线的起止端都有一个120Ω的终端电阻,来做阻抗匹配,以减少回波反射。


总结:

  • 显性电平:CAN_H和CAN_L之差为2.5V左右;对应逻辑0

  • 隐性电平:CAN_H和CAN_L之差为0V;对应逻辑1

  • 当多个设备之间组成网络进行通信时,只需要两个120Ω的终端电阻,并不是每一个设备都需要带一个120Ω电阻。


2. CAN的帧类型

===================平常用的只是数据帧 ========================

CAN协议是通过以下5种类型的帧进行的:

  • 数据帧
  • 遥控帧
  • 错误帧
  • 过载帧
  • 帧间隔

另外,数据帧和遥控帧有标准格式和扩展格式两种格式。标准格式有11个位的标识符(ID),扩展格式有29个位的ID。各种帧的用途如表所示:
在这里插入图片描述

3. 数据帧

=================知道数据帧的结构,标准帧和扩展帧的区别 ==============

仅对数据帧进行详细介绍,数据帧一般由7个段构成,即:

  • 1)帧起始。表示数据帧开始的段。

  • 2)仲裁段。表示该帧优先级的段(ID)。

  • 3)控制段表示数据的字节数及保留位的段。

  • 4)数据段。数据的内容,一帧可发送0~8个字节的数据

  • 5)CRC段。检查帧的传输错误的段。

  • 6)ACK段。表示确认正常接收的段。

  • 7)帧结束。表示数据帧结束的段。

数据帧的构成如图所示:
数据帧

图中D表示显性电平,R表示隐形电平(下同)。

  • 帧起始,这个比较简单,标准帧和扩展帧都是由1个位的显性电平表示帧起始

  • 仲裁段,表示数据优先级的段,标准帧和扩展帧格式在本段有所区别,如图所示:

仲裁段

标准格式的 ID 有11个位。从 ID28 到 ID18 被依次发送。禁止高7 位都为隐性(禁止设定:ID=1111111XXXX)。扩展格式的 ID 有29 个位。基本ID 从 ID28 到 ID18 ,扩展ID 由 ID17 到 ID0 表示。基本ID和标准格式的ID 相同。禁止高7 位都为隐性(禁止设定:基本ID=1111111XXXX)。

其中RTR位用于标识是否是远程帧(0,数据帧;1,远程帧),IDE位为标识符选择位(0,使用标准标识符;1,使用扩展标识符),SRR位为代替远程请求位,为隐性位,它代替了标准帧中的RTR位。

  • 控制段,由6个位构成,表示数据段的字节数。标准帧和扩展帧的控制段稍有不同,如图所示:

控制段

上图中,r0和r1为保留位,必须全部以显性电平发送,但是接收端可以接收显性、隐性及任意组合的电平。DLC段为数据长度表示段,高位在前,DLC段有效值为0–8,但是接收方接收到9–15的时候并不认为是错误。

  • 数据段,该段可包含0~8个字节的数据。从最高位(MSB)开始输出,标准帧和扩展帧在这个段的定义都是一样的。如图所示:

数据段

  • CRC段,该段用于检查帧传输错误。由15个位的CRC顺序和1个位的CRC界定符(用于分隔的位)组成,标准帧和扩展帧在这个段的格式也是相同的。如图所示:

CRC段

此段CRC的值计算范围包括:帧起始、仲裁段、控制段、数据段。接收方以同样的算法计算 CRC 值并进行比较,不一致时会通报错误。

  • ACK段,此段用来确认是否正常接收。由ACK槽(ACK Slot)和ACK界定符2个位组成。标准帧和扩展帧在这个段的格式也是相同的。如图所示:

ACK段

发送单元的ACK,发送2个位的隐性位,而接收到正确消息的单元在ACK槽(ACK Slot)发送显性位,通知发送单元正常接收结束,这个过程叫发送ACK/返回ACK。发送 ACK 的是在既不处于总线关闭态也不处于休眠态的所有接收单元中,接收到正常消息的单元(发送单元不发送ACK)。所谓正常消息是指不含填充错误、格式错误、CRC 错误的消息。

  • 帧结束,这个段也比较简单,标准帧和扩展帧在这个段格式一样,由7个位的隐性位组成。

4. 位时序

============了解即可,一位是如何构成的 ===========

由发送单元在非同步的情况下发送的每秒钟的位数称为位速率。一个位可分为 4 段

  • 同步段(SS)

  • 传播时间段(PTS)

  • 相位缓冲段1(PBS1)

  • 相位缓冲段2(PBS2)

这些段又由可称为 Time Quantum(以下称为Tq)的最小时间单位构成。

1 位分为4 个段,每个段又由若干个Tq 构成,这称为位时序。

1 位由多少个Tq 构成、每个段又由多少个Tq 构成等,可以任意设定位时序。通过设定位时序,多个单元可同时采样,也可任意设定采样点。各段的作用和 Tq 数如表所示:

tq

1个位的构成如图所示:

位时序

上图的采样点,是指读取总线电平,并将读到的电平作为位值的点。位置在 PBS1 结束处。根据这个位时序,我们就可以计算CAN通信的波特率了

5. CAN的波特率计算

===================知道波特率如何计算 ==================

接下来,我们简单看看STM32的CAN位时间特性,STM32的CAN位时间特性和之前我们介绍的,稍有点区别。STM32把传播时间段和相位缓冲段1(STM32称之为时间段1)合并了,所以STM32的CAN一个位只有3段:同步段(SYNC_SEG)、时间段1(BS1)和时间段2(BS2)。STM32的BS1段可以设置为1–16个时间单元,刚好等于我们上面介绍的传播时间段和相位缓冲段1之和。BS2段可以设置为2–8个时间单元。STM32的CAN位时序如图所示:

位时间

CAN波特率计算公式:CANCLK/[(1+TS1+1+TS2+1)*(BRP+1)];

图中还给出了CAN波特率的计算公式,我们只需要知道BS1和BS2的设置,以及APB1的时钟频率(一般为36Mhz),就可以方便的计算出波特率。比如设置TS1=6、TS2=7和BRP=4,在APB1频率为36Mhz的条件下,即可得到CAN通信的波特率=36000/[(7+8+1)*5]=450Kbps。

程序上如何配置:(平时都是用这个!!)

程序中宏定义时BS1、BS2已经加上1了!!!

CAN波特率 = CAN时钟/( (1 + CAN_BS1 + CAN_BS2)  * CAN_Prescaler)

假设程序配置如下:
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_9tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_6tq;
CAN_InitStructure.CAN_Prescaler=5;
CAN_Init(&CAN_InitStructure);

则baudrate=36000,000/[(1+9+6)*5]=450kbps

附常用波特率配置表:
在这里插入图片描述

6. CAN总线的仲裁

================了解即可,CAN总线的仲裁机制 =====================

在总线空闲态,最先开始发送消息的单元获得发送权。

当多个单元同时开始发送时,各发送单元从仲裁段的第一位开始进行仲裁。连续输出显性电平最多的单元可继续发送。实现过程,如图所示:

仲裁

上图中,单元1和单元2同时开始向总线发送数据,开始部分他们的数据格式是一样的,故无法区分优先级,直到T时刻,单元1输出隐性电平,而单元2输出显性电平,此时单元1仲裁失利,立刻转入接收状态工作,不再与单元2竞争,而单元2则顺利获得总线使用权,继续发送自己的数据。这就实现了仲裁,让连续发送显性电平多的单元获得总线使用权。

7. CAN控制器

============= 不重要,了解即可==============

STM32自带的是bxCAN,即基本扩展CAN。它支持CAN协议2.0A和2.0B。它的设计目标是,以最小的CPU负荷来高效处理大量收到的报文。它也支持报文发送的优先级要求(优先级特性可软件配置)。对于安全紧要的应用,bxCAN提供所有支持时间触发通信模式所需的硬件功能。

STM32的bxCAN的主要特点有:

  • 支持CAN协议2.0A和2.0B主动模式

  • 波特率最高达1Mbps

  • 支持时间触发通信

  • 具有3个发送邮箱

  • 具有3级深度的2个接收FIFO

  • 可变的过滤器组(最多28个)

在STM32互联型产品中,带有2个CAN控制器,而我们使用的STM32F103ZET6属于增强型,不是互联型,只有1个CAN控制器。双CAN的框图如图所示:

can控制器

从图中可以看出两个CAN都分别拥有自己的发送邮箱和接收FIFO,但是他们共用28个滤波器。通过CAN_FMR寄存器的设置,可以设置滤波器的分配方式。

8. 过滤器

STM32的标识符过滤是一个比较复杂的东东,它的存在减少了CPU处理CAN通信的开销。STM32的过滤器组最多有28个(互联型),但是STM32F103ZET6只有14个(增强型),每个滤波器组x由2个32位寄存器,CAN_FxR1和CAN_FxR2组成。

STM32每个过滤器组的位宽都可以独立配置,以满足应用程序的不同需求。根据位宽的不同,每个过滤器组可提供:

  • 1个32位过滤器,包括:STDID[10:0]、EXTID[17:0]、IDE和RTR位

  • 2个16位过滤器,包括:STDID[10:0]、IDE、RTR和EXTID[17:15]位

此外过滤器可配置为,屏蔽位模式和标识符列表模式。

在屏蔽位模式下,标识符寄存器和屏蔽寄存器一起,指定报文标识符的任何一位,应该按照“必须匹配”或“不用关心”处理。

而在标识符列表模式下,屏蔽寄存器也被当作标识符寄存器用。因此,不是采用一个标识符加一个屏蔽位的方式,而是使用2个标识符寄存器。接收报文标识符的每一位都必须跟过滤器标识符相同。

通过CAN_FMR寄存器,可以配置过滤器组的位宽和工作模式,如图所示:

过滤器

为了过滤出一组标识符,应该设置过滤器组工作在屏蔽位模式。

为了过滤出一个标识符,应该设置过滤器组工作在标识符列表模式。

应用程序不用的过滤器组,应该保持在禁用状态。

过滤器组中的每个过滤器,都被编号为(叫做过滤器号,图30.1.11中的n)从0开始,到某个最大数值-取决于过滤器组的模式和位宽的设置。

举个简单的例子,我们设置过滤器组0工作在:1个32为位过滤器-标识符屏蔽模式,然后设置CAN_F0R1=0XFFFF0000,CAN_F0R2=0XFF00FF00。其中存放到CAN_F0R1的值就是期望收到的ID,即我们希望收到的映像(STID+EXTID+IDE+RTR)最好是:0XFFFF0000。而0XFF00FF00就是设置我们需要必须关心的ID,表示收到的映像,其位[31:24]和位[15:8]这16个位的必须和CAN_F0R1中对应的位一模一样,而另外的16个位则不关心,可以一样,也可以不一样,都认为是正确的ID,即收到的映像必须是0XFFxx00xx,才算是正确的(x表示不关心)。

9. CAN过滤器配置

============难点 ================
CAN ID值的结构分析:

TIPS:对于一个扩展CAN ID,不能单纯地将它看成一个数,而应该将它看成两部分,基本ID和扩展ID(当然标准CAN ID只包含基本ID部分),过滤器屏蔽码寄存器和标识符寄存器也应该看成多个部分,然后问题就变成了如何将CAN ID所表示的各部分如何针对过滤器寄存器各部分对号入座的问题了。

对号入座的方法多种多样,但万变不离其心,主要是掌握其核心思想即可:1:在各种过滤器模式下,CAN ID与寄存器相应位置一定要匹配;2:在屏蔽方式下,屏蔽码寄存器某位为1表示接收到的CAN ID对应的位必须对验证码寄存器对应的位相同。

弄懂一件事,当给定一个CAN ID,如0x1800f001,当然这个是扩展ID,这里要问的是,这个CAN ID的值本身包含两部分,即基本ID与扩展ID,即么你知道这个扩展ID0x1800f001的哪些位是基本ID,哪些位又是扩展ID?(在基本CANID格式下不存在这个问题)

在回答这个问题之前我们来看看ISO11898的定义,如下图:
在这里插入图片描述
如上图,基本格式不存在扩展ID,而扩展格式中ID0~ID17为Extension ID,而ID18~ID28为Base ID.

因此CAN ID值0x1800f001用二进制表示为:0b 0001 1000 0000 0000 1111 0000 0000 0001,用括号分别区别为:0b 000[1 1000 0000 00][00 1111 0000 0000 0001],红色部分为扩展ID,蓝色部分为基本ID。

位宽为32位的屏蔽模式(最常用):配置时的映射最重要!!

在这里插入图片描述

如上图,上面的ID为标识符寄存器,中间部分的MASK为屏蔽码寄存器。每个寄存器都是32位的。最下边显示的是与CAN ID各位定位的映射关系。于是可以知道,上图最下边的映射关系恰好等于扩展CAN值左移3位再补上IDE(扩展帧标识),RTR(远程帧标志)

下面给出代码例子,假设我们要接收多个ID:0x7e9,0x1800f001,前面为标准ID,后面为扩展ID,要同时能接收这两个ID,那么该如何设置这个过滤器呢?

example 1:
在这里插入图片描述
在这里插入图片描述

example 2:
在这里插入图片描述

在该配置中,结构体成员CAN_FilterIdHigh和CAN_FilterIdLow存储的是要筛选的ID,而CAN_FilterMaskIdHigh和CAN_FilterMaskIdLow存储的是相应的掩码。在赋值时,要注意寄存器位的映射,在32位的ID中,第0位是保留位,第1位是RTR标志,第2位是IDE标志,从第3位起才是报文的ID(扩展ID)。

因此在上述代码中我们先把扩展ID"0x1314"、IDE位标志"宏CAN_ID_EXT"以及RTR位标志"宏CAN_RTR_DATA"根据寄存器位映射组成一个32位的数据,然后再把它的高16位和低16位分别赋值给结构体成员CAN_FilterIdHigh和CAN_FilterIdLow。

而在掩码部分,为简单起见我们直接对所有位赋值为1,表示上述所有标志都完全一样的报文才能经过筛选,所以我们这个配置相当于单个ID列表的模式,只筛选了一个ID号,而不是筛选一组ID号。这里只是为了演示方便,实际使用中一般会对不要求相等的数据位赋值为0,从而过滤一组ID,如果有需要,还可以继续配置多个筛选器组,最多可以配置28个,代码中只是配置了筛选器组0。

可以参考:
CAN ID过滤器分析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1152230.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Django 社区志愿者管理系统

摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 社区志愿者服务管理系统,主要的模块包括查看首页、个人中心、通知公告管理、志愿者管理、普通管理员管理、志愿活动管理、活动宣…

计算机毕业设计选题推荐-超市售货微信小程序/安卓APP-项目实战

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

【C语言初学者周冲刺计划】1.1用筛选法求100之内的素数

目录 1解题思路: 2代码如下: 3运行代码如图所示: 4总结: (前言周冲刺计划:周一一个习题实操,依次类推加一,望各位读者可以独自实践敲代码) 1解题思路: 首先了解筛选法定义:先把…

免费的PPT模版--九五小庞

PPT模板: www.1ppt.com/moban/    行业PPT模板:www.1ppt.com/hangye/ 节日PPT模板:www.1ppt.com/jieri/    PPT素材: www.1ppt.com/sucai/PPT背景图片:www.1ppt.com/beijing/   PPT图表&#xff…

AssertionError: Torch not compiled with CUDA enabled

Pytorch和CUDA版本不兼容,运行python后(终端输入python回车)用以下代码测试 import torch print(torch.__version__) print(torch.cuda.is_available())返回False则说明目前的pytorch版本无法使用显卡,如下图所示 接着重装合适版…

新能源汽车电池包自动三维尺寸检测系统蓝光光学平面度测量仪-CASAIM

电池包是新能源汽车核心能量源,为整车提供驱动电能。作为新能源汽车的核心部件,其品质直接决定了整车性能。 由于电池包的生产工艺相对复杂,传统的测量工具不仅测量工序复杂、精度不足,还会或多或少接触到电池表面形成瑕疵&#…

[UDS] --- ECUReset 0x11

1 0x11功能描述 根据ISO14119-1标准中所述,诊断服务11主要用于Client向Server(ECU)请求重启行为。该重启行为将会导致Server复位回归到特定的初始状态,具体是什么初始状态取决于Client的请求行为。 2 0x11应用场景 一般而言,对于11诊断服务…

案例分析真题-系统建模

案例分析真题-系统建模 2009年真题 【问题1】 【问题2】 【问题3】 2012年真题 【问题1】 【问题2】 【问题3】 2014年真题 【问题1】 【问题2】 骚戴理解:这个题目以前经常考,不知道今年会不会考,判断的话就是看加工有没有缺少输入和输出&a…

Linux进程的概念

一:冯诺依曼体系结构 什么叫做体系结构??? 计算机组成 / 芯片架构 输入单元:键盘、话筒、摄像头、usb、鼠标、磁盘(ROM)/ssd、网卡、显卡 存储器:内存(RAM&#xff09…

apache seatunnel支持hive jdbc

上传hive jdbc包HiveJDBC42.jar到seatunel lib安装目录 原因是cloudera 实现了add batch方法 创建seatunnel任务文件mysql2hivejdbc.conf env {execution.parallelism = 2job.mode = "BATCH"checkpoint.interval = 10000 } source {Jdbc {url = "jdbc:mysql:/…

Kafka设计原理详解

Kafka核心总控制器Controller 在Kafka集群中会有一个或者多个broker,其中有一个broker会被选举为控制器(Kafka Controller),它负责管理整个集群中所有分区和副本的状态。 当某个分区的leader副本出现故障时,由控制器…

UEditor编辑器导入自定义html模板,jeesite框架报json.parse()错误

文章目录 前言一、错误描述1. 选择模板错误2. 填入模板数据错误二、解决方案1. 选择模板错误解决2.填入数据错误解决总结前言 实现效果如下图: 添加模板 选择模板 填入模板及对应数据 一、错误描述 1. 选择模板错误

Java修仙传之Flink篇

大道三千:最近我修Flink 目前个人理解: 处理有界,无界流的工具 FLINK: FLINK定义: Flink特点 Flink分层API 流的定义 有界数据流(批处理): 有界流:数据结束了,程序也…

【图像分割】【深度学习】Windows10下PFNet官方代码Pytorch实现与源码讲解

【图像分割】【深度学习】Windows10下PFNet官方代码Pytorch实现与源码讲解 提示:最近开始在【图像分割】方面进行研究,记录相关知识点,分享学习中遇到的问题已经解决的方法。 文章目录 【图像分割】【深度学习】Windows10下PFNet官方代码Pytorch实现与源码讲解前言PFNet模型运行…

算法笔记【4】-冒泡排序法改进

一、冒泡排序缺点 冒泡排序是一种简单但效率较低的排序算法。冒泡排序通过比较相邻元素并交换位置来实现排序。具体而言,它从数组的第一个元素开始,依次比较相邻的两个元素,如果顺序错误则交换它们的位置,直到整个数组排好序为止…

RK3399平台开发系列讲解(基础篇)应用程序代码优化技巧

🚀返回专栏总目录 文章目录 一、利用高速缓存二、代码内联三、restrict 关键字四、消除不必要的内存引用沉淀、分享、成长,让自己和他人都能有所收获!😄 📢我主要会为你介绍四个优化 应用代码的技巧,它们分别是 利用高速缓存利用代码内联利用 restrict 关键字消除不必…

Java架构师软件可靠性构建

目录 1 导学2 软件可靠性基本概念3 软件可靠性建模4 软件可靠性管理5 软件可靠性设计6 软件可靠性测试与评价想学习架构师构建流程请跳转:Java架构师系统架构设计 1 导学 2 软件可靠性基本概念 软件可靠性是软件产品在规定的条件下和规定的时间区间完成规定功能的能力。软件…

Java精品项目源码爱心捐赠平台网站(编号V65)

Java精品项目源码扶农助农平台建设系统(编号V64) 大家好,小辰今天给大家介绍一个爱心捐赠平台网站(编号V65),演示视频公众号(小辰哥的Java)对号查询观看即可 文章目录 Java精品项目源码扶农助农平台建设系统(编号V64)难度指数&a…

修仙路上的基石 ->继承与实现

继承与实现的区别 不同点: 继承:不强制 子类重写父类方法 实现:强制 实现类重写接口的全部方法共同点: 都可以使用多态 继承:父类 父类对象 new 子类() 实现:接口 接口对象 实现类.调用方法(); 这里…

[尚硅谷React笔记]——第7章 redux

目录: redux简介redux工作流程求和案例_纯react版求和案例_redux精简版redux完整版异步action版对react-redux的理解连接容器组件与UI组件,react-redux基本使用优化1_简写mapDispatch优化2_Provider组件的使用优化3_整合UI组件与容器组件数据共享_编写P…