草庐IT

CAN协议的学习与理解

感滴觉 2025-07-26 原文

最近在学习CAN,记录一下,也供大家参考交流。

推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记

首先是瑞萨的CAN入门,真的通透;

秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4 CAN!
原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252

CAN详解(小白教程)
原文链接:https://blog.csdn.net/xwwwj/article/details/105372234

一篇易懂的CAN通讯协议指南1

一篇易懂的CAN通讯协议指南1 - 知乎 (zhihu.com)

视频推荐

CAN总线个人知识总结_哔哩哔哩_bilibili

【单片机】野火STM32F103教学视频 (配套霸道/指南者/MINI)【全】(刘火良老师出品) (无字幕)_哔哩哔哩_bilibili

一、CAN协议是什么?(概念)

CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO国际标准化的串行通信协议。 在当前的汽车产业中,出于对安全性、舒适性、方便性、低公害、低成本的要求,各种各样的电子控制系统 被开发了出来。由于这些系统之间通信所用的数据类型及对可靠性的要求不尽相同,由多条总线构成的情况很 多,线束的数量也随之增加。为适应“减少线束的数量”、“通过多个 LAN,进行大量数据的高速通信”的需 要,1986 年德国电气商博世公司开发出面向汽车的 CAN 通信协议。此后,CAN 通过 ISO11898 及 ISO11519 进 行了标准化,现在在欧洲已是汽车网络的标准协议。

CAN通讯是异步通讯,没有时钟信号线来保持信号接收同步,无法同时发送与接收,在同一时刻,只能有一个节点发送数据,也就是半双工,其余节点都只能接收数据。

二、can的物理层 

CAN 通讯并不是以时钟信号来进行同步的,它是一种异步通讯,只具有 CAN_High 和 CAN_Low 两条信号线,共同构成一组差分信号线,以差分信号的形式进行通讯。

 1.通讯节点

CAN通讯节点由一个CAN控制器和一个CAN收发器组成,控制器与收发器由CAN_TX和CAN_RX连接,CAN收发器通过CAN_HIGH和CAN_LOW与总线连接。节点之间的信号经过总线传输,实现节点之间的通讯,CAN总线可以挂载多个通讯节点,因为CAN不对节点进行地址编码,而是对数据内容进行编码,只要总线的负载足够,理论上可以不受限制。

2.1闭环总线网络

遵循ISO11898标准,高速,通讯速率最大可达1Mbps,短距离,最长40m,总线俩端需要120欧的匹配电阻。

 

2.2开环总线网络

遵循ISO11519-2标准,低速,最高通讯速率125Kbps,远距离,最远1km,俩总线不闭环,要串联2.2千欧电阻。

 3.差分信号

为什么CAN要使用差分信号?

差分信号又称差模信号,与传统使用单根信号线电压表示逻辑的方式有区别,使用差分信号传输时,需要两根信号线,这两个信号线的振幅相等,相位相反,通过两根信号线的电压差值来表示逻辑 0 和逻辑 1。差分信号抗干扰能力强,可以有效抑制外部电磁干扰,时序定位精确。

单端信号和差分信号的区别

这个差分信号在CAN上怎么用,与逻辑之间是什么关系?

ISO-11898 (高速CAN)和ISO-11519(低速CAN)的CAN信号定义 

当CAN_H和CAN_L的电压均为2.5v,两者电压差为0,就规定CAN信号为隐性电平;当CAN_H的电压为3.5v,CAN_L的电压为1.5v,两者电压差为2V,就规定CAN信号为显性电平。这里实际的规定是:电压差满足定义的一定范围,就可以认为是显性电平或者隐性电平,比如电压差在1.5-2.5v范围,都认为是显性电平。

而CAN的差分信号可以参考下面这张图,在 CAN 总线中,必须使它处于隐性电平 (逻辑 1) 或显性电平 (逻辑 0) 中的其中一个状态。假如有两个 CAN 通讯节点,在同一时间,一个输出隐性电平,另一个输出显性电平,类似 I2C 总线的“线与”特性将使它处于显性电平状态,显性电平的名字就是这样来的,即可以认为显性具有优先的意味。

 二、CAN的协议层

前面提到CAN是异步通讯,那他没有时钟线怎么进行通讯的呢?

CAN的各个节点之间就要约定好特定的波特率进行通讯,怎么约定好波特率,没有时钟线,而且难免会出现误差,这时候我们还需要使用位同步的方式来抗干扰,吸收误差。这时候就要了解位时序和位同步。

1.位时序分解

位时序,就是一个数据位的时序,CAN把一个数据位的时序分解为SS、PTS、PBS1、PBS2,他们的最小单位是1Tq,一个完整的位由 8~25 个 Tq,这四段加上为一个CAN的数据位长度。下面分别介绍:

SS段    同步段   固定为1Tq

同步段,顾名思义与同步有关,若通讯节点检测到总线上面信号的跳变沿被包含在SS段的范围之内,则表示节点与总线的时序是同步的,此时采集到的电平也是确定的。

PTS段   传播时间段      1~8Tq

用于补偿网络的物理延长时间,是总线上输入比较器延时和输出驱动器延时的两倍。

PBS1段   相位缓冲段     1~8Tq

补偿边沿阶段的误差,他的时间可以在重新同步时加长(再同步)

PBS2段  相位缓冲段     2~8Tq

补偿边沿阶段的误差,他的时间可以在重新同步时缩短(再同步)

2.位同步

2.1硬同步

接收单元在总线空闲状态检测出帧起始时进行的同步调整。 在检测出边沿的地方不考虑 SJW 的值而认为是 SS 段。 硬件同步的过程如下图所示。

 2.2再同步

再同步就是在接收过程中检测出总线上的电平变化时进行的同步调整。 每当检测出边沿时,根据 SJW 值通过加长 PBS1 段,或缩短 PBS2 段,以调整同步。但如果发生了超出 SJW 值的误差时,最大调整量不能超过 SJW 值。这里定义了这个补偿时间叫做SJW,它的含义就是最大补偿值。一般保持在不大不小的状态,小了容易造成误差,大了影响传输速率。

3.确定波特率

总线上的各个通讯节点只要约定好1个Tq的时间长度以及一个数据位占多少个Tq,就可以确定波特率。例如:假设1Tq = 1us,19个Tq组成一个数据位,1bit = 19tq

                  1x10的6次方/19 = 52631.6 (bps)

4.CAN的报文种类及结构

了解了CAN协议的时钟现在了解一下CAN的数据咋实现。

CAN协议对数据、操作命令 (如读/写) 以及同步信号进行打包,打包后的这些内容称为报文,而当整个数据包被传输到其它设备时,只要这些设备按格式去解读,就能还原出原始数据,这样的报文就被称为 CAN 的“数据帧”。

通信是通过以下 5 种类型的帧进行的

 5.数据帧的结构

 数据帧以一个显性位开始,7个连续的隐形位结束,他们之间有仲裁段、数据段、CRC段和ACK段

1)SOF段,帧起始,用于通知各个节点将有信号传输,其他节点通过帧起始信号的电平跳变沿来进行硬同步。

2)仲裁段,CAN不对节点地址分配优先级,对信息的重要程度分配优先级,仲裁段的主要内容就是ID信息。RTR 区分数据帧和遥控帧  显性就是数据帧。

3)控制段 r0、r1保留位,默认显性,DCL段位数据长度。

4)CRC段,表示一个15位的校验码,算出来的校验码和接受相同表示正确,如果错误则错误帧返回,请求重新发送。CRC界定符,分界线,默认隐形。

5)ACK段,ACK 槽(ACK Slot)和 ACK 界定符 2 个位构成,发送单元的 ACK 段:发送单元在 ACK 段发送 2 个位的隐性位。 接收单元的 ACK 段 :接收到正确消息的单元在 ACK 槽(ACK Slot)发送显性位,通知发送单元正常接收结束。这称作“发 送 ACK”或者“返回 ACK”。

6)EOF 帧结束,帧结束是表示该该帧的结束的段。由 7 个位的隐性位构成。

........未写完

有关CAN协议的学习与理解的更多相关文章

  1. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  2. ruby CSV : How can I read a tab-delimited file? - 2

    CSV.open(name,"r").eachdo|row|putsrowend我得到以下错误:CSV::MalformedCSVErrorUnquotedfieldsdonotallow\ror\n文件名是一个.txt制表符分隔文件。我是专门做的。我有一个.csv文件,我转到excel,并将文件保存为.txt制表符分隔的文件。所以它是制表符分隔的。CSV.open不应该能够读取制表符分隔的文件吗? 最佳答案 尝试像这样指定字段分隔符:CSV.open("name","r",{:col_sep=>"\t"}).eachdo|row|

  3. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  4. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  5. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  6. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

  7. ruby - 易于初学者理解的 Ruby 库 - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。关闭3年前。Improvethisquestion我正处于学习Ruby的阶段,我想查看一些小型库的源代码以了解它们是如何构建的。我不知道什么是小型图书馆,但希望SO能推荐一些易于理解的图书馆来学习。因此,如果有人知道一两个非常小的库,这是新手Rubyists学习的好例子,请推荐!我想使用Manveru'sInnatelib,因为它试图保持在2000LOC以下,但我还不熟悉其中经常使用的Ruby速记。也许大约100-5

  8. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  9. ruby - 无法理解 `puts{}.class` 和 `puts({}.class)` 之间的区别 - 2

    由于匿名block和散列block看起来大致相同。我正在玩它。我做了一些严肃的观察,如下所示:{}.class#=>Hash好的,这很酷。空block被视为Hash。print{}.class#=>NilClassputs{}.class#=>NilClass为什么上面的代码和NilClass一样,下面的代码又显示了Hash?puts({}.class)#Hash#=>nilprint({}.class)#Hash=>nil谁能帮我理解上面发生了什么?我完全不同意@Lindydancer的观点你如何解释下面几行:print{}.class#NilClassprint[].class#A

  10. ruby - 混帐 & ruby : How can I unset the GIT_DIR variable from inside a ruby script? - 2

    我编写了一个非常简单的“部署”脚本,作为我的裸git存储库中的post-updateHook运行。变量如下livedomain=~/mydomain.comstagingdomain=~/stage.mydomain.comgitrepolocation=~/git.mydomain.com/thisrepo.git(bare)core=~/git.mydomain.com/thisrepo.gitcore==addedremoteintoeachlive&stagegitslive和stage都初始化了gitrepos(非裸),我已经将我的裸仓库作为远程添加到它们中的每一个(名为co

随机推荐