嵌入式开发—CAN通信协议详解与应用(上)

news2024/9/21 23:17:49

文章目录

    • 1.CAN简介
      • CAN协议的诞生背景
      • CAN协议的发展历程
      • CAN协议的影响
      • CAN通信的主要特点
    • 2.CAN数据帧的帧格式
      • CAN标准数据帧的帧格式
      • CAN标准数据帧的帧格式结构图
      • CAN扩展帧的帧格式
      • CAN遥控帧的帧格式
      • CAN错误帧的帧格式
    • 3.CAN数据传输中的位填充
      • 位填充的概念
      • 位填充的作用
      • 位填充的工作机制
      • 位填充示例

1.CAN简介

CAN协议的诞生背景

在1980年代,汽车内部的电子控制单元(ECU)数量逐渐增加,传统的点对点电气通信方式已经难以满足需求。每一个电子控制单元与其他设备之间的点对点连接使得系统布线复杂、成本高、故障率高。汽车制造商希望有一种能够简化布线,同时满足车辆实时控制和高可靠性要求的通信方式。

CAN协议的发展历程

  1. 1983年:开发需求
    • 博世公司意识到,汽车内部的电子设备(如发动机管理、车身控制等)需要更可靠、更高效的通信网络。因此,博世公司开始着手开发一种专为车辆设计的通信系统。
  2. 1986年:CAN协议发布
    • 博世公司在1986年正式发布了CAN协议的初步规范,并在同年举行的**国际社会科学控制会议(SAE International Congress and Exposition)**上进行了展示。
  3. 1987年:第一款CAN控制器
    • 博世与英飞凌(当时为西门子半导体部)合作,推出了世界上第一个CAN控制器芯片,标志着CAN协议的实际应用开始进入汽车电子市场。
  4. 1991年:ISO标准化
    • CAN协议在1991年通过了国际标准化组织(ISO)的审核,成为ISO 11898标准。这一标准规范了CAN协议的物理层和数据链路层,进一步推动了CAN在工业界的应用。
  5. 1990年代:广泛应用
    • 随着汽车电子技术的发展,CAN协议迅速普及,成为大多数汽车制造商的标准通信协议。CAN网络在汽车中的应用从发动机控制单元(ECU)扩展到了防抱死刹车系统(ABS)、车身控制模块(BCM)、车载诊断系统(OBD)等。
  6. 后续发展
    • 在CAN的基础上,博世公司还开发了CAN FD(Flexible Data-rate CAN),旨在提高数据传输速度和帧容量,以满足汽车中更高带宽的需求。CAN FD协议于2012年正式发布,并在汽车和其他高需求的工业应用中得到推广。

CAN协议的影响

CAN协议的推出彻底改变了汽车电子系统的架构,极大地简化了车内电子设备之间的通信,使得汽车系统更加高效、可靠、可扩展。其低成本、高实时性、高可靠性的特点,使得CAN不仅在汽车工业中广泛应用,还逐渐推广到工业自动化、医疗设备、轨道交通等多个领域。

CAN通信的主要特点

  1. 多主结构
    • CAN采用多主架构,即多个节点可以同时发送消息,避免了单一主设备的瓶颈。
  2. 无中心控制器
    • 所有节点均可自主发送和接收消息,通信无主从之分,减少了中心节点的依赖。
  3. 消息优先级和仲裁机制
    • 每个CAN消息帧都有一个独特的标识符(ID),当多个节点同时发送数据时,标识符优先级较高的消息会获得总线访问权,而不会引起冲突。
  4. 快速错误检测与恢复
    • CAN具有CRC校验错误帧检测自动重发等机制,能够实时检测到错误并自动恢复通信,保证数据传输的高可靠性。
  5. 短数据帧结构
    • 单个CAN数据帧最多可包含8字节的数据,虽然帧结构较小,但可以确保高实时性和低延迟。
  6. 传输速率
    • CAN通信的传输速率从10 kbps1 Mbps不等,具体速率取决于应用场景和总线长度。

2.CAN数据帧的帧格式

CAN标准数据帧的帧格式

CAN标准数据帧(CAN 2.0A,11位标识符)的帧格式由以下几部分组成,每个部分的作用不同,具体字段如下:

  1. 起始位(SOF,Start of Frame)

    • 1位
    • 表示数据帧的开始,是一个显性位(逻辑低电平),它标志着总线空闲状态的结束和数据传输的开始。
  2. 标识符(Identifier)(有些资料中称为仲裁字段)

    • 11位
    • 用于表示数据帧的优先级和来源。标识符的优先级由数值大小决定,数值越小,优先级越高。在总线仲裁时,通过标识符的优先级确定哪个节点可以发送数据。
  3. 远程传输请求(RTR,Remote Transmission Request)

    • 1位
    • 标识帧类型:
      • 数据帧:此位为显性位(0)。
      • 远程帧:此位为隐性位(1),表示请求某个节点发送数据。
  4. 控制位(Control Field)

    • 6位
      • IDE(Identifier Extension Bit):1位,区分标准帧(11位ID)和扩展帧(29位ID)。对于标准帧,IDE为显性位(0)。
      • 保留位(Reserved Bit):2位,保留为未来使用,默认为显性位(0)。
      • 数据长度码(DLC,Data Length Code):4位,表示数据段的字节数,范围为0-8字节
  5. 数据字段(Data Field)

    • 0到8字节
    • 包含实际传输的数据,长度由DLC字段决定,最多8个字节。CAN标准帧的每个数据帧最多可以传输8字节的数据。
  6. 循环冗余校验(CRC,Cyclic Redundancy Check)

    • 15位CRC字段1位CRC定界符
    • 用于检测数据传输中的错误。发送端根据数据帧计算CRC校验码,接收端进行同样的计算并比较,确保数据的完整性。
  7. 应答字段(ACK,Acknowledgement Field)

    • 2位
      • 1位ACK槽位:发送端将此位设置为隐性位(1),接收端在成功接收并验证帧后,将其设置为显性位(0),表示接收成功。
      • 1位ACK定界符:固定为隐性位(1),用于标识ACK槽位结束。
  8. 结束帧(EOF,End of Frame)

    • 7位
    • 表示数据帧的结束,全部为隐性位(逻辑高电平)。

CAN标准数据帧的帧格式结构图

在这里插入图片描述

  • 仲裁机制:CAN总线上的每个节点通过发送标识符进行仲裁,标识符越小,优先级越高。
  • 高可靠性:通过CRC校验ACK应答机制确保数据的正确传输和接收。
  • 实时性:通过短帧设计(最多8字节数据)和仲裁机制,实现快速的数据传输,特别适合汽车和工业应用中要求低延迟的场景。

CAN扩展帧的帧格式

扩展数据帧(CAN 2.0B)和标准数据帧(CAN 2.0A)的主要区别在于标识符的长度以及相应的控制字段变化。扩展数据帧允许使用更长的标识符,用于更复杂的应用场景

标识符长度

  • 标准数据帧:
    • 标识符长度为11位
    • 11位标识符可以表示的范围是0x000到0x7FF(0到2047),共2048个不同的标识符。
  • 扩展数据帧:
    • 标识符长度为29位,由11位基标识符18位扩展标识符组成。
    • 29位标识符可以表示的范围是0x00000000到0x1FFFFFFF(0到536870911),共536870912个不同的标识符。

IDE位(Identifier Extension Bit)

  • 标准数据帧:
    • IDE位显性位(0),表示这是一个标准帧。
  • 扩展数据帧:
    • IDE位隐性位(1),表示这是一个扩展帧。

标识符的结构

  • 标准数据帧:
    • 只有一个11位标识符
  • 扩展数据帧:
    • 包含一个11位的基标识符,加上18位的扩展标识符,总计29位标识符。

在这里插入图片描述

在仲裁过程中,标准数据帧的优先级高于扩展数据帧,因为在IDE位的比较中,显性位(0)比隐性位(1)优先。

CAN遥控帧的帧格式

遥控帧(Remote Frame)是CAN通信协议中的一种帧类型,用于请求其他节点发送指定标识符的数据帧。与数据帧不同,遥控帧不携带数据,它只包含发送方希望接收的数据类型的标识符。当一个节点发送遥控帧后,拥有相同标识符的节点会响应并发送相应的数据帧。

遥控帧的作用:

  • 请求数据:某个节点通过发送遥控帧请求其他节点发送特定标识符的数据帧。
  • 通信控制:用于控制特定标识符的数据传输,而无需占用过多带宽。

遥控帧和数据帧的区别:

  • 数据帧:包含数据字段,并将实际数据传输给接收节点。
  • 遥控帧:没有数据字段,仅用来请求特定标识符的数据。

遥控帧的帧格式:

遥控帧的帧结构与标准数据帧和扩展数据帧的格式基本相同,唯一的区别是遥控帧的RTR(Remote Transmission Request)位设为隐性位(1),表示这是一个遥控帧,而不是数据帧。

在这里插入图片描述

CAN错误帧的帧格式

错误帧是CAN总线中的一种特殊帧,用于标识和通知总线上的节点发生了传输错误。与普通的数据帧遥控帧不同,错误帧不会携带数据,而是通过特定的信号让总线上的其他节点知道出现了错误。

错误帧与普通数据帧的区别

  1. 目的不同

    • 数据帧:用于在节点之间传递实际的数据。
    • 错误帧:用于通知总线中的所有节点出现了传输错误,要求丢弃当前传输,触发重新传输。
  2. 帧结构不同
    错误帧与数据帧的结构完全不同,它包含以下两个主要部分:

    • 主动错误标志被动错误标志
    • 错误定界符

错误帧由两个部分组成:

  1. 错误标志(Error Flag)

    • 分为主动错误标志被动错误标志
    • 主动错误标志:发送方发送6个连续的显性位(逻辑0)。任何主动错误的节点都可以发送这个标志,用于通知错误发生。
    • 被动错误标志:发送方发送6个连续的隐性位(逻辑1)。当节点进入被动错误状态时,会发送此标志,而不是显性位。
  2. 错误定界符(Error Delimiter)

    • 8个隐性位(逻辑1)。
    • 用于标识错误帧的结束,并确保错误帧与后续的数据帧之间有明确的分界。
  3. 主动错误帧(Active Error Frame)

    当节点检测到错误并处于主动状态时,发送主动错误帧:

    • 主动错误标志:由6个**显性位(0)**组成,用于通知总线有错误发生。
    • 错误定界符:8个隐性位(1),用于标志错误帧结束。

主动错误帧格式:

| Active Error Flag (6显性位) | Error Delimiter (8隐性位) |
  1. 被动错误帧(Passive Error Frame)

    当节点进入被动错误状态时,发送被动错误帧:

    • 被动错误标志:由6个**隐性位(1)**组成,表示节点进入被动错误状态。
    • 错误定界符:8个隐性位(1),与主动错误帧相同。

被动错误帧格式:

| Passive Error Flag (6隐性位) | Error Delimiter (8隐性位) |

错误帧的触发条件:

  • 位错误(Bit Error):节点检测到在发送显性位(或隐性位)时总线状态与预期不符。
  • 填充错误(Stuff Error):CAN总线规定,每连续5个相同的位后应插入一个相反的位作为填充位,如果填充位不正确,则触发错误。
  • CRC错误(CRC Error):接收方计算的CRC校验码与数据帧中的CRC校验码不匹配。
  • 帧格式错误(Form Error):帧的结构或定界符不符合CAN协议规定。
  • 应答错误(ACK Error):发送方未检测到接收方的应答信号(ACK位没有被接收方拉低)。

3.CAN数据传输中的位填充

**位填充(Bit Stuffing)**是CAN(Controller Area Network)协议中的一种技术,用于确保总线上的同步性和避免长时间出现连续的相同电平,帮助接收方正确恢复时钟和位计时。

位填充的概念

  • 在CAN通信中,每当发送方在数据流中检测到连续的5个相同的位(不论是显性位或隐性位),它会自动插入一个相反的位
  • 这个额外插入的位称为填充位(Stuff Bit)。
  • 位填充适用于CAN帧的控制字段、数据字段、CRC字段等所有包含在帧中的位流,但不适用于固定长度的字段(例如帧的ACK、SOF、EOF等字段)。

示例:

假设在数据传输时,发送方发送的连续位流为11111,在CAN总线上会自动插入一个填充位0,传输的数据会变成111110。如果发送的是00000,则会插入一个1,变成000001

位填充的作用

  1. 保持总线同步性

    • CAN总线使用的是非归零编码(NRZ,Non-Return to Zero),这种编码方式容易导致连续相同电平的位序列,进而使接收方无法检测位的边界,影响时钟同步。
    • 通过位填充,CAN总线上可以定期产生电平变化,帮助接收节点正确同步时钟。
  2. 防止长时间的恒定电平

    • 如果CAN总线上的电平长时间保持不变,接收节点的时钟可能会失步,导致数据无法正确解析。
    • 位填充强制在总线上插入反向电平,从而确保位流中的变化,增强信号可靠性。
  3. 错误检测

    • 接收方也按照同样的规则进行位填充判断,当接收到的数据中未按规则插入填充位,或者填充位错误时,接收方可以判定数据帧有错误,触发错误帧。
    • 位填充错误是一种常见的CAN错误类型之一,被称为填充错误(Stuff Error)

位填充的工作机制

  1. 发送过程

    • 发送方在发送帧时,自动检测每一段连续的5个相同的位。
    • 如果连续5位相同,则在后面插入一个相反的位。
  2. 接收过程

    • 接收方接收到数据时,按照相同的规则检查填充位。
    • 一旦检测到错误(如连续相同的位未插入反向位),则判定为填充错误。

位填充示例

假设发送方要发送一个二进制数据流01111110,我们可以通过以下步骤看到位填充的过程:

发送前的数据:

01111110

位填充过程:

  1. 从左到右扫描位流,发现有连续5个1
  2. 按照位填充规则,必须在11111后插入一个反向位0

发送后的数据:

0111110 0 10

这样,通过位填充,连续相同的位序列被打破,确保接收方能够保持同步。

位填充适用于CAN帧中的大多数部分,包括:

  • 数据字段(实际数据位)
  • CRC字段(校验位)
  • 控制字段(例如标识符)

位填充不适用的部分

  • SOF(Start of Frame):帧的开始标志位,不进行位填充。
  • ACK(Acknowledgment Field):用于确认接收到数据帧,也不进行填充。
  • EOF(End of Frame):帧结束标志位,同样不进行位填充。

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

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

相关文章

今天中秋,中秋快乐,分析一个中秋月饼的项目

特色功能 使用obj模型,搭配tga文件,附加上颜色 normalMap 是让字和线条看起来更清楚和真实 高光贴图 凹凸贴图 ...... 源码 https://github.com/Lonely1201/lonely1201.github.io/tree/main/Juejin/mooncake 在线预览 https://lonely1201.githu…

将YYYY-MM-DD HH:mm:ss格式化为YYYY-MM-DD (星期一) 下午 ?点

分为凌晨、早上、中午、晚上 function formatDate(inputDate) {const date new Date(inputDate);date.setHours(date.getHours() - 1);const year date.getFullYear();const month date.getMonth() 1; // 月份从0开始const day date.getDate();let hours date.getHours(…

详解:Tensorflow、Pytorch、Keras

这是一个专门对Tensorflow、Pytorch、Keras三个主流DL框架的一个详解和对比分析 一、何为深度学习框架? 你可以理解为一个工具帮你构建一个深度学习网络,调用里面的各种方法就能自行构建任意层,diy你想要的DNN,而且任意指定学习…

用Qt 对接‌百度语音识别接口

一 、前期准备工作 1,搭建好开发环境; 2,注册百度云平台,获取语音相关东西, 短语音识别标准版_短语音识别-百度AI开放平台 (baidu.com) 3,涉及到的Qt 类有 QAudioFormat,QAudioDeviceInfo&a…

JDBC实现对单表数据增、删、改、查

文章目录 API介绍获取 Statement 对象Statement的API介绍使用步骤案例代码 JDBC实现对单表数据查询ResultSet的原理ResultSet获取数据的API使用JDBC查询数据库中的数据的步骤案例代码 API介绍 获取 Statement 对象 在java.sql.Connection接口中有如下方法获取到Statement对象…

线程池是啥有啥用,怎么用,如何自己实现一个

目录 一、线程池是啥,有啥用 二、线程池怎么用 1.构造方法 2.如何使用Java的线程池 三、简单实现一个线程池 假设我是一个(好看有才华) 的妹子,那么我就会有很多追求者,这些也叫备胎们,我们若把他…

71、哪吒开发板试用结合oak深度相机进行评测

基本思想:收到intel的开发板-小挪吒,正好手中也有oak相机,反正都是openvino一套玩意,进行评测一下,竟然默认是个window系统,哈哈

STL-vector练习题

118. 杨辉三角 思路: 杨辉三角有以下性质使我们要用到的: ● 每行数字左右对称,由 1 开始逐渐变大再变小,并最终回到 1。 ● 第 n 行(从 0 开始编号)的数字有 n1 项,前 n 行共有 2n(n1)个数。…

linux重要文件

/etc/sysconfig/network-scripts/ifcfg-eth1 网卡重启 /etc/init.d/network restart ifup ethname & ifdown ethname /etc/resolv.conf 设置Linux本地的客户端DNS的配置文件 linux客户端DNS可以在网卡配置文件(/etc/sysconfig/network/ifcfg-eth0 DNS2)里配置 也可以在/et…

SSY20240916提高组T1题解__贪心+大模拟

题面 题面描述 fe和xt在玩一个游戏, 在 n m n\times m nm的网格图上进行. 定义 ( a , b ) , ( c , d ) (a,b)\;,\;(c,d) (a,b),(c,d)见距离为 ∣ a − c ∣ ∣ b − d ∣ |a-c||b-d| ∣a−c∣∣b−d∣ 现在游戏按照以下步骤进行: xt选择 k k k个格子fe选择一个格子(不能选…

QT + WebAssembly + Vue环境搭建

Qt6.7.2安装工具 emsdk安装 git clone https://github.com/emscripten-core/emsdk.git cd emsdk emsdk install 3.1.50 emsdk activate 3.1.50 Qt Creator配置emsdk 效果 参考 GitHub - BrockReece/vue-wasm: Vue web assembly loader Emscripten cmake多版本编译-CSDN博客 …

【数据结构】排序算法---希尔排序

文章目录 1. 定义2. 算法步骤3. 动图演示4. 性质5. 算法分析6. 代码实现C语言PythonJavaCGo 结语 1. 定义 希尔排序(英语:Shell sort),也称为缩小增量排序法,是[直接插入排序]的一种改进版本。希尔排序以它的发明者希…

优化最长上升子序列

前言&#xff1a;平时我们做的题目都是用动态规划做的&#xff0c;但是有没有能够优化一下呢&#xff1f; 有一个结论&#xff0c;长度为 i 的一个序列&#xff0c;最后一个元素一定是构成长度为 i 的序列中最小的 我们可以用二分来优化 题目地址 #include<bits/stdc.h>…

【设计模式】创建型模式(四):建造者模式

创建型模式&#xff08;四&#xff09;&#xff1a;建造者模式 1.概念2.案例3.优化 1.概念 建造者模式 是一种创建型设计模式&#xff0c;它允许你创建复杂对象的步骤与表示方式相分离。 建造者模式是一种创建型设计模式&#xff0c;它的主要目的是将一个复杂对象的 构建过程…

极速上云2.0范式:一键智连阿里云

在传统上云的现状与挑战&#xff1a; 专线上云太重&#xff0c;VPN上云不稳&#xff0c;云上VPC&#xff0c;云下物理网络&#xff0c;多段最后一公里...... 层层对接&#xff0c;跳跳延迟&#xff0c;好生复杂! 当你试图理解SD-WAN供应商和阿里云的文档&#xff0c;以协调路由…

7-ZIP工具的功能分享:合并分卷压缩文件

在日常工作中&#xff0c;有些大文件无法单独传输&#xff0c;我们通常会通过压缩拆分成多个分卷文件来完成传输。 当完成传输后&#xff0c;不想要这么多分卷文件的时候&#xff0c;就可以通过7-ZIP工具的合并功能来解决这个问题。下面一起来看看&#xff0c;具体如何操作。 …

【C++算法】位运算

位运算基础知识 1.基础运算符 << : 左移 >> : 右移 ~ : 取反 & : 按位与&#xff0c;有0就是0 I : 按位或&#xff0c;有1就是1 ^ : 按位异或&#xff0c;&#xff08;1&#xff09;相同为0&#xff0c;相异为1&#xff08;2&#xff09;无进位相加 2.…

【docker】阿里云使用docker,2024各种采坑

▒ 目录 ▒ &#x1f6eb; 导读需求开发环境 1️⃣ dial tcp: lookup on 8.8.8.8:53: no such host失败属于DNS问题 2️⃣ docker镜像配置配置最新镜像源 3️⃣ 【重点】阿里云专用获取自己的镜像加速器地址配置镜像地址 &#x1f6ec; 文章小结&#x1f4d6; 参考资料 &#x…

MySQL_SQLYog简介、下载及安装(超详细)

课 程 推 荐我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448;入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448;虚 拟 环 境 搭 建 &#xff1a;&#x1…

如何设置xshell关闭最后一个选项卡标签时不退出软件?

不知道你是否遇到这个问题&#xff0c;就是在使用xshell的时候&#xff0c;每次关闭最后一个选项卡标签的时候&#xff0c;xshell软件默认就退出了&#xff0c;好多次我都只是想要关闭&#xff0c;而非退出&#xff0c;所以该如何设置&#xff0c;才能到我们的预期的效果呢&…