【CANopen进阶日记】①CAN协议栈详解

2023-12-11 13:05

本文主要是介绍【CANopen进阶日记】①CAN协议栈详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【CANopen进阶日记】专栏目录

第一章 CAN协议栈详解
第二章 CANopen协议栈详解
第三章 CANopen对象字典工具


文章目录

  • 【CANopen进阶日记】专栏目录
  • 前言
  • 一、CAN简介
  • 二、CAN的发展历史
  • 三、CAN的电气特性
  • 四、CAN协议栈
    • 4.1、CAN协议栈解析
    • 4.2、CAN收发过程
    • 4.3、CAN错误处理
    • 4.4、CAN波特率
    • 4.5、CAN过滤
  • 总结


前言

在这个专栏中,你可以找到大量与CANopen协议有关的知识和技能,包括CANopen协议的基础、如何配置和管理网络、如何使用CANopen对象字典和数据类型等,旨在帮助读者更好地掌握和应用CANopen。

本章介绍了CAN协议栈的发展历史、电气特性、基础理论、标准协议栈解析等干货知识点。


一、CAN简介

CAN包含两个部分,分别是CAN总线和CAN总线协议。

  1. CAN总线
    控制器局域网总线(CAN,Controller Area Network)是一种用于实时应用的串行通讯协议总线,它是使用两根信号总线(双绞线的形式)来传输信号,是世界上应用最广泛的现场总线之一。

    最初,CAN被设计作为汽车环境中的微控制器通讯,在车载各电子控制装置ECU之间交换信息,形成汽车电子控制网络。比如:发动机管理系统、变速箱控制器、仪表装备、电子主干系统中,均嵌入CAN控制装置。

    一个由CAN 总线构成的单一网络中,理论上可以挂接无数个节点。实际应用中,节点数目受网络硬件的电气特性所限制。CAN 可提供高达1Mbit/s的数据传输速率,这使实时控制变得非常容易。另外,硬件的错误检定特性也增强了CAN的抗电磁干扰能力。

  2. CAN总线协议
    CAN总线协议是 ISO国际标准化的串行通信协议:
    CAN协议用于汽车中各种不同元件之间的通信,以此取代昂贵而笨重的配电线束。该协议的健壮性使其用途延伸到其他自动化和工业应用。CAN协议的特性包括完整性的串行数据通讯、提供实时支持、传输速率高达1Mb/s、同时具有11位的寻址以及检错能力。

    CAN总线协议是一个载波侦听(CSMA)、基于报文优先级碰撞检测和仲裁(CD+AMP)的多路访问协议:
    CSMA:意思是总线上的每一个节点在企图发送报文前,必须要监听总线,当总线处于空闲时,才可发送。
    CD+AMP:意思是通过预定编程好的报文优先级逐位仲裁来解决碰撞,报文优先级位于每个报文的标识域。更高级别优先级标识的报文总是能获得总线访问权,即:标识符中最后保持逻辑高电平的会继续传输,因为它具有更高优先级。

二、CAN的发展历史

  1. 1980年代初期,由于没有可满足汽车工程师的总线协议,人们开始开发新的串行总线。
  2. 1986年2月,在底特律举行SAE会议上CAN总线诞生,称之为Automotive Serial Controller Area Network。
  3. 1991年,博世发布CAN2.0规范,分CAN 2.0A(具有11位标识符)和CAN 2.0B(具有29位标识符)。
  4. 1993年,ISO组织发布CAN标准IS0 11898: IS0 11898-1涵盖数据链路层,IS0 11898-2涵盖高速CAN的CAN物理层(经典CAN速度1Mbps,CAN FD 5Mbps) ,IS0 11898-3 涵盖低速,容错CAN的物理层 (速度125Kbps),后续还推出了ISO 11898 -4 -5和-6标准。
  5. 2012年,博世发布CAN FD 1.0,速度2Mbps,使用CAN FD-SiC (加强版CAN PHY)可以做到5-8Msps。以STM32H7为例,带的CANFD是支持经典CAN的CAN2.0A和CAN2.0B,以及CANFD V1.0规范,兼容ISO 11898-1 : 2015和ISO11898 -4。
  6. 2018年12月,开始推出第三代CAN数据链路层协议CAN XL,速度提升至10Mbsp。
  7. 2022年11月、博世推出下一代CAN IP核CAN XL,速度高达20Mbps。

三、CAN的电气特性

  1. CAN总线测试阶段,至少一端的终端120Q终端电阻不可以省略。
    在这里插入图片描述

  2. CAN是差分通信,总线电平分为显性电平和隐性电平两种。总线上执行逻辑上的线“与”:显性电平为0,隐性电平为1。显性电平具有主导性,只有所有节点都输出隐性电平时总线上才是隐性。
    在这里插入图片描述

  3. 测量发现CAN仅接一端的终端电阻,结束的时候波形会有个抬高。

  4. 通信速度和最大长度理论值,主要是经典CAN,所有节点操作必须在同一个CAN波特率下。

  5. 在测试阶段,测试软件应用层时,由于STM32芯片大部分都是双CAN,所以可以通过特别操作,不使用CAN PHY芯片也可以实现CAN通讯,不过这个不是差分电平。
    在这里插入图片描述

四、CAN协议栈

CAN协议栈的帧类型包括数据帧、远程帧、错误帧、过载帧和帧间隔。

4.1、CAN协议栈解析

  1. 数据帧:发送单元向接收单元传送数据的帧。
    在这里插入图片描述
    在这里插入图片描述

    起始段:表示数据帧开始的段。
    SOF:帧起始(1位),显性(0)表示报文的开始,并用于同步总线上的节点。

    仲裁段:表示该帧优先级的段。
    标识符: 标识符(11位),标准格式具有11位标识符,用来确定报文的优先级。此域的数值越小,优先级越高。
    RTR: 远程发送请求位(1位),当需要从另一个节点请求信息(遥控帧)时,此位为显性(0)。
    所有节点都能接收这个请求,但是帧标识符确定被指定的节点。响应数据帧同样被所有节点接收,可以被有兴趣的节点使用。

    控制段:表示数据的字节数及保留位的段。
    IDE: 标志符扩展位(1位),为显性(0)时使用标准格式,为隐性(1)时表示这是扩展格式。
    r0:保留位(1位),必须全部以显性电平发送,但接收方可以接收任意电平。
    DLC:数据长度代码(4位),表示传输数据的字节数目,一帧最多传输8字节用户数据。

    数据段:数据的内容,经典CAN支持0-8字节,CANFD支持0-64字节。

    校验段:检查帧的传输错误的段。
    CRC:经典CAN是15bit+1个bit的CRC界定符 (用于位分隔),CANFD是17或者21bit+1个界定符。
    CRC Delimiter:置“1”。
    CRC的计算范围包括起始段,仲裁段,控制段,数据段,接收方以同样的算法计算CRC值并进行比较,不一致会通报错误。

    应答段:表示确认正常接收的段。
    ACK:包含应答位和应答界定符(2位)。
    发送节点的报文帧中,ACK两位是隐性位,当接收器正确地接收到有效的报文,接收器会在应答位期间向发送节点发送一个显性位,表示应答。
    如果接收器发现这帧数据有错误,则不向发送节点发送ACK应答,发送节点会稍后重传这帧数据。

    结束段:表示数据帧结束的段。
    EOF:帧结束标志位(7位),全部为隐性位。如果这7位出现显性位,则会引起填充错误。
    IFS:帧间隔标志位(7位),CAN控制器将接收到的帧正确的放入消息缓冲区是需要一定时间的,帧间隔可以提供这个时间。

  2. 远程帧:接收单元向具有相同ID的发送单元请求数据的帧。
    遥控用于接收单元向具有相同 ID 的发送单元请求数据的帧,CANFD没有遥控帧,只有经典CAN有远程帧。远程帧相比数据帧没有数据段。需要注意的是,目前CAN官方建议不再使用远程帧。

    扩展格式相对于标准格式改动的内容如下:
    ① SRR:代替远程请求位,为隐性。所以当标准帧与扩展帧发送相互冲突并且扩展帧的基本标识符与标准帧的标识符相同时,标准帧优先级高于扩展帧。
    ②IDE :为隐性位表示标志位扩展帧,18位扩展标识符紧跟着IDE位。
    ③ 18位标识符:增加18位标识符。
    ④ r1:保留位。

  3. 错误帧:当检测出错误时向其他单元通知错误的帧。
    接收节点或者发送节点检测出错误时,通知错误的帧。
    主动错误标志:6个bit的显性位;
    被动错误标志:6个bit的隐性位;
    错误界定符:8个bit隐性位。

  4. 过载帧:接收单元表明其自身尚未做好准备的帧。

  5. 帧间隔:将数据帧及遥控帧与前面的帧分离开来的帧。

4.2、CAN收发过程

  1. 发送过程
    ① 设置发送节点的ID,DLC,数据等。
    ② 设置CAN控制器,启动发送帧。
    ③ 任何节点,在总线空闲时,都可以启动发送帧。
    ④ 除了启动数据发送的节点,其余所有节点都在等待接收数据。
    ⑤ 如果多个节点同时启动数据发送,将进行仲裁,ID值小的优先处理,ID值大的停止发送,进入接收状态。
    ⑥ 此时,仅有一个节点发送数据,否则还有其它节点发送数据将造成异常。
    ⑦ 当发送节点完成消息发送,将等待应答bit被拉低为0,表示接收节点正常收到数据了。
    ⑧ 发送节点的数据已经送达接收节点,继续发送顿数据中的结束段,之后发送节点将进入接收状态或者继续发送下一帧数据。接收节点将处理收到的数据。
    ⑨ 此时,任何数据都可以发送数据,如果没有节点发送数据,总线将进入空闲状态。
    ⑩ 如果没有收到应答,将按照CAN错误方式处理 。

  2. 接收过程
    ① 所有节点,除了发送数据的节点和处于总线关闭状态的节点,都处于监听状态。
    ② CAN数据将按照前面说的CAN发送过程进行数据发送。
    ③ 所有处于监听状态的节点都将收到数据,如果被认为是没有错误的有效 CAN 消息,监听节点将应答。
    ④ 如果接收节点设置了CAN过滤器,将根据过滤设置滤掉不需要的消息。

4.3、CAN错误处理

检测到帧错误处理:

  1. 接收错误的节点将拉低 (显性电平0) 总线至少6个bit。
  2. 超过5个bit相同极性,将触发位填充,这个是硬件完成的,不需要用户操作。
  3. 错误帧以通知发送给所有节点,这个是硬件完成的。
  4. 发送总线放弃当前帧,8 bit的 TEC 发送错误计数器寄存器的值加X。
  5. 如果此TEC 等于0xFF,则发送节点将 BUSOFF (总线关闭) 并使自己脱离总线。
  6. 如果不是,则尝试重传消息,该消息必须与其他消息一起再次经过优先级处理。
  7. 所有其他节点放弃读取当前帧,REC接收错误计数器寄存器的值加X。
  8. 任何有消息排队的节点现在都将启动发送,其它的节点进去监听。
  9. 如果每次传输一个帧或接收一帧成功,相应的 TEC 和 REC 寄存器递减 (通常只递减 1)。
    在这里插入图片描述

4.4、CAN波特率

CANFD波特率计算,含仲裁阶段可变波特率和数据阶段可变波特率,而经典CAN只有一种波特率。

4.5、CAN过滤

标识符过滤器是用于接收的,发送的时候无需设置过滤器,根据发送端发送来的帧数据,通过标识符过滤器就可以设置仅接收需要接收的帧数据有效降低CPU多余的处理时间。

  1. 经典CAN支持标识符列表模式和屏蔽位模式。
  2. CANFD支持范围过滤器 (Range filter) 、专用ID的过滤器 (Filter for dedicated IDs)和经典位屏蔽过滤器 (Classic bit mask filter)。

总结

本章介绍了CAN协议栈的发展历史、电气特性、基础理论、标准协议栈解析等干货知识点。

关注公众号回复“加群”按规则加入技术交流群,回复“1024”查看更多内容。

这篇关于【CANopen进阶日记】①CAN协议栈详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/480791

相关文章

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

MySQL中between and的基本用法、范围查询示例详解

《MySQL中betweenand的基本用法、范围查询示例详解》BETWEENAND操作符在MySQL中用于选择在两个值之间的数据,包括边界值,它支持数值和日期类型,示例展示了如何使用BETWEEN... 目录一、between and语法二、使用示例2.1、betwphpeen and数值查询2.2、be

python中的flask_sqlalchemy的使用及示例详解

《python中的flask_sqlalchemy的使用及示例详解》文章主要介绍了在使用SQLAlchemy创建模型实例时,通过元类动态创建实例的方式,并说明了如何在实例化时执行__init__方法,... 目录@orm.reconstructorSQLAlchemy的回滚关联其他模型数据库基本操作将数据添

Java中ArrayList与顺序表示例详解

《Java中ArrayList与顺序表示例详解》顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构,:本文主要介绍Java中ArrayList与... 目录前言一、Java集合框架核心接口与分类ArrayList二、顺序表数据结构中的顺序表三、常用代码手动

JAVA线程的周期及调度机制详解

《JAVA线程的周期及调度机制详解》Java线程的生命周期包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED,线程调度依赖操作系统,采用抢占... 目录Java线程的生命周期线程状态转换示例代码JAVA线程调度机制优先级设置示例注意事项JAVA线程

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

C++构造函数中explicit详解

《C++构造函数中explicit详解》explicit关键字用于修饰单参数构造函数或可以看作单参数的构造函数,阻止编译器进行隐式类型转换或拷贝初始化,本文就来介绍explicit的使用,感兴趣的可以... 目录1. 什么是explicit2. 隐式转换的问题3.explicit的使用示例基本用法多参数构造

Android使用java实现网络连通性检查详解

《Android使用java实现网络连通性检查详解》这篇文章主要为大家详细介绍了Android使用java实现网络连通性检查的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录NetCheck.Java(可直接拷贝)使用示例(Activity/Fragment 内)权限要求

MyBatis中的两种参数传递类型详解(示例代码)

《MyBatis中的两种参数传递类型详解(示例代码)》文章介绍了MyBatis中传递多个参数的两种方式,使用Map和使用@Param注解或封装POJO,Map方式适用于动态、不固定的参数,但可读性和安... 目录✅ android方式一:使用Map<String, Object>✅ 方式二:使用@Param

JAVA transient 关键字作用详解

《JAVAtransient关键字作用详解》Java的transient关键字用于修饰成员变量,使其不参与序列化过程,通过自定义序列化方法,可以手动控制transient变量的序列化行为,本文给大... 目录一、transient关键字作用二、原理详解三、典型使用场景四、代码示例五、注意事项六、与 stat