【STM32 CAN】STM32G47x 单片机FDCAN作为普通CAN外设使用教程

news2024/12/31 6:05:18

STM32G47x 单片机FDCAN作为普通CAN外设使用教程

控制器局域网总线(CAN,Controller Area Network)是一种用于实时应用的串行通讯协议总线,它可以使用双绞线来传输信号,是世界上应用最广泛的现场总线之一。CAN协议用于汽车中各种不同元件之间的通信,以此取代昂贵而笨重的配电线束。该协议的健壮性使其用途延伸到其他自动化和工业应用。CAN协议的特性包括完整性的串行数据通讯、提供实时支持、传输速率高达1Mb/s、同时具有11位的寻址以及检错能力。

硬件说明

这里使用的是STM32G473VET6主控芯片,具有三个CANFD外设,这些CAN外设同时支持传统CAN通信协议。

时钟配置情况

这里STM32主控的SYSCLK(系统时钟)为170MHz。使用外部晶振作为时钟源头。

在这里插入图片描述

CANFD外设作为普通CAN外设使用

CANFD外设

FDCAN外设子系统由一个CAN模块、一块共享的消息RAM和一个配置模块组成。可以参阅内存映射,以获取这些部分的基址。
这些模块(FDCAN)符合ISO 11898-1:2015(CAN协议规范版本2.0部分A、B)和CAN FD协议规范版本1.0。
每个FDCAN实例有0.8千字节的消息RAM,用于实现过滤器、接收FIFOs、传输事件FIFOs和传输FIFOs。

  • 符合CAN协议版本2.0部分A、B和ISO 11898-1:2015、-4
  • 支持最大64数据字节的CAN FD
  • 具有CAN错误日志
  • 支持AUTOSAR和J1939
  • 具有改进的接收过滤器
  • 具有两个接收FIFO,每个有三个有效载荷(每个有效载荷最多64字节)
  • 具有高优先级消息接收时的单独信号提示
  • 具有可配置的传输FIFO/队列,三个有效载荷(每个有效载荷最多64字节)
  • 具有传输事件FIFO
  • 具有可编程的环回测试模式
  • 具有可屏蔽的模块中断
  • 具有两个时钟域:APB总线接口和CAN核心内核时钟
  • 具有支持断电

CANFD 通信速率计算

前置知识
要计算CAN的通信速率首先都了解CAN通信过程中每个bit的构成。
一个电平位时间主要有以下4个段:

SS段(SYNC SEG;同步段):若通讯节点检测到总线上信号的跳变沿被包含在SS段的范围内,则表示节点与总线的时序是同步的;(固定1个Tq)
PTS段(PROP SEG;传播段):这个时间段是用于补偿网络的物理延时时间,是总线上输入比较器延时和输出驱动器延时综合的两倍;(长度可编程:1~8个Tq)
PBS1段(PHASE SEG1;相位缓冲段1):用于补偿节点间的晶振误差,允许通过重同步对该段加长,在这个时间段末端进行总线状态的采样;(长度可编程:1~8Tq)

协议层-位时序
意义:为了实现正确的总线电平采样,确保通讯正常。最小单位是Tq(Time Quantum),一个完整位由8~25个Tq组成,其中一个电平位时间主要有以下4个段:
在这里插入图片描述

 段名   意义   作用   SS(1Tq)   Sync Seg;同步段  若通讯节点检测到总线上信号的跳变沿被包含在SS段的范围内,则表示节点与总线的时序是同步的;(固定1个Tq)   PTS(1-8Tq)   Prob Seg;传播段   这个时间段是用于补偿网络的物理延时时间,,是传播时间、收发器延时之和的两倍   PBS1(1-8Tq)   Phase Seg1;相位缓冲段1  补偿变压阶段误差   PBS2(2-8Tq)   Phase Seg2;相位缓冲段2  补偿边沿阶段误差   SJW(1-4Tq)   再同步补偿宽度   补偿时钟频率偏差、传输延迟等  \begin{array}{|c|c|c|} \hline \text { 段名 } & \text { 意义 } & \text { 作用 } \\ \hline \text { SS(1Tq) } & \text { Sync Seg;同步段} & \text { 若通讯节点检测到总线上信号的跳变沿被包含在SS段的范围内,则表示节点与总线的时序是同步的;(固定1个Tq) } \\ \hline \text { PTS(1-8Tq) } & \text { Prob Seg;传播段 } & \text { 这个时间段是用于补偿网络的物理延时时间,,是传播时间、收发器延时之和的两倍 } \\ \hline \text { PBS1(1-8Tq) } & \text { Phase Seg1;相位缓冲段1} & \text { 补偿变压阶段误差 } \\ \hline \text { PBS2(2-8Tq) } & \text { Phase Seg2;相位缓冲段2} & \text { 补偿边沿阶段误差 } \\ \hline \text { SJW(1-4Tq) } & \text { 再同步补偿宽度 } & \text { 补偿时钟频率偏差、传输延迟等 } \\ \hline \end{array}  段名  SS(1Tq)  PTS(1-8Tq)  PBS1(1-8Tq)  PBS2(2-8Tq)  SJW(1-4Tq)  意义  Sync Seg;同步段 Prob Seg;传播段  Phase Seg1;相位缓冲段1 Phase Seg2;相位缓冲段2 再同步补偿宽度  作用  若通讯节点检测到总线上信号的跳变沿被包含在SS段的范围内,则表示节点与总线的时序是同步的;(固定1Tq  这个时间段是用于补偿网络的物理延时时间,,是传播时间、收发器延时之和的两倍  补偿变压阶段误差  补偿边沿阶段误差  补偿时钟频率偏差、传输延迟等 

在这里插入图片描述

如下图所示:
在这里插入图片描述
C A N 波特率 = 1 1 b i t 所占用时间 = 1 T q ∗ 1 b i t 的 T q 个数 CAN波特率 = \frac{1}{1bit所占用时间} = \frac{1}{Tq*1bit的Tq个数} CAN波特率=1bit所占用时间1=Tq1bitTq个数1

在这里插入图片描述
在这里插入图片描述

上面已经说明了一个数据位(1bit,准确来说是1baud)占**(SS+PTS+PBS1+PBS2+SJW)**个Tq。

STM32CubeMX界面参数

在这里插入图片描述
分别为(Nominal 我不知道为什么是Nominal 这个词,但是如果是CAN FD模式的话,这里NominalPrescaler、NominalSyncJumpWidth 、NominalTimeSeg1 、NominalTimeSeg2 是用于配置仲裁阶段波特率的,DataPrescaler 、DataSyncJumpWidth 、DataTimeSeg1 、DataTimeSeg2 是用于配置数据阶段波特率的。)

  • Basic Parameters:

    • Clock Divider: CAN内核时钟分频系数。
    • Frame Format: 指定CAN帧格式,这里是经典CAN(CAN2.0 B)、FD模式没有比特率切换、FD模式有比特率切换。
    • Mode: 指定CAN控制器的工作模式,如正常模式、环回模式或静默模式。
    • Auto Retransmission: 是否使能自动重发。
    • Transmit Pause: 是否配置禁止传输暂停特性。
    • Protocol Exception: 协议异常处理使能。
    • Nominal Sync Jump Width: 规定名义重同步跳跃宽度,用于时间同步,,即位时序提到的SJW。用于动态调节 Phase_Seg1和 Phase_Seg1,所以不可以比Phase_Seg1和 Phase_Seg1大.
    • Data Prescaler: 数据速率预分频值。CAN时钟分配设置,一般设置为1即可,全部由PLL配置好,tq = NominalPrescaler x (1/ fdcan_ker_ck),范围1-32。
    • Data Sync Jump Width: 数据阶段的同步跳跃宽度。用于动态调节 Phase_Seg1和 Phase_Seg1,所以不可以比Phase_Seg1和 Phase_Seg1大,范围1-16
    • Data Time Seg1: 数据位时间段1的长度。特别注意这里的Seg1,这里是两个参数之和,对应位时间特性图的 Pro_Seg + Phase_Seg1。
    • Data Time Seg2: 数据位时间段2的长度。对应位时间特性图的 Phase_Seg2。(Pro_Seg + Phase_Seg1 = DataTimeSeg1, Phase_Seg2 = DataTimeSeg2)
    • Std Filters Nbr: 设置标准ID过滤器个数,范围0-128。是配置CAN接受时候使用的滤波器数量,用了多少个就写多少个。
    • Ext Filters Nbr: 设置扩展ID过滤器个数,范围0-64。
    • Tx Fifo Queue Mode: 发送FIFO队列模式。
  • Bit Timings Parameters 位定时参数:

    • Nominal Prescaler: 名义速率预分频器值。CAN时钟分配设置,一般设置为1即可,全部由PLL配置好,tq = NominalPrescaler x (1/ fdcan_ker_ck)。
    • Nominal Time Quantum: 名义时间量子的长度。
    • Nominal Time Seg1: 名义位时间段1的长度。用于动态调节 Phase_Seg1和 Phase_Seg1,所以不可以比Phase_Seg1和 Phase_Seg1大。
    • Nominal Time Seg2: 名义位时间段2的长度。特别注意这里的Seg1,这里是两个参数之和,对应位时间特性图的 Pro_Seg + Phase_Seg1.(Pro_Seg + Phase_Seg1 = NominalTimeSeg1, Phase_Seg2 = NominalTimeSeg2)
    • Nominal Time for one Bit: 名义单比特时间。
    • Nominal Baud Rate: 名义波特率。

一般没有配置SJW,且STM32的CAN外设的Sync_Seg是固定值1,并且有:
CAN 波特率 = CAN Freq / (Sync_Seg + Pro_Seg + Phase_Seg1 + Phase_Seg2)

关于滤波器数量:

在CAN协议里,报文的标识符不代表节点的地址,而是跟报文的内容相关的。因此,发送者以广播的形式把报文发送给所有的接收者。节点在接收报文时,根据标识符(CAN ID)的值决定软件是否需要该报文;如果需要,就拷贝到SRAM里;如果不需要,报文就被丢弃且无需软件的干预。
为满足这一需求,bxCAN为应用程序提供了14个位宽可变的、可配置的过滤器组(13~0),以便只接收那些软件需要的报文。硬件过滤的做法节省了CPU开销,否则就必须由软件过滤从而占用一定的CPU开销。每个过滤器组x由2个32位寄存器,CAN_FxR0和CAN_FxR1组成。

在这个案例中CAN模块的时钟源为PCLK1,为170MHz。
在这里插入图片描述
如下图是在CAN使用上图的时钟源的情况下配置125Kbps的波特率,配置为传统CAN模式的情况,作为传统CAN模式,参数DataPrescaler 、DataSyncJumpWidth 、DataTimeSeg1 、DataTimeSeg2没有作用。
在这里插入图片描述

测试代码


/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_FDCAN1_Init();
  /* USER CODE BEGIN 2 */

  HAL_FDCAN_Start(&hfdcan1);

  //CAN2.0B 拓展帧消息发送
  FDCAN_TxHeaderTypeDef TxHeader;
  uint8_t TxData[8];
  TxHeader.Identifier = 0x321;
  TxHeader.IdType = FDCAN_EXTENDED_ID;
  TxHeader.TxFrameType = FDCAN_DATA_FRAME;
  TxHeader.DataLength = FDCAN_DLC_BYTES_8;
  TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
  TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
  TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
  TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
  TxHeader.MessageMarker = 0;

  TxData[0] = 0x00;
  TxData[1] = 0x01;
  TxData[2] = 0x02;
  TxData[3] = 0x03;
  TxData[4] = 0x04;
  TxData[5] = 0x05;
  TxData[6] = 0x06;
  TxData[7] = 0x07;

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    HAL_Delay(200);
    
    if (HAL_FDCAN_GetTxFifoFreeLevel(&hfdcan1) > 0)
    {
      if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData) != HAL_OK)
      {
        Error_Handler();
      }
    }
  }
  /* USER CODE END 3 */
}

运行结果:
在这里插入图片描述
如图为CANH对CANL的波形,发送端接了120欧姆的终端电阻,接收测悬空,在接收测测量。(主要是我还没有看到为什么不接CAN隔离芯片或者没有给CAN隔离芯片上电的情况下测不到发送出来的波形。)
在这里插入图片描述

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

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

相关文章

基于SSM+Vue的网上购物商城

基于SSMVue的网上购物商城的设计与实现~ 开发语言:Java数据库:MySQL技术:SpringMyBatisSpringMVC工具:IDEA/Ecilpse、Navicat、Maven 系统展示 主页 商品详情 登录界面 管理员界面 用户界面 可视化图标 摘要 基于SSM&#xff0…

vcomp120.dll丢失怎么办?vcomp120.dll丢失的解决方法分享

vcomp120.dll丢失”。这个错误通常会导致某些应用程序无法正常运行,给用户带来困扰。那么,当我们遇到这个问题时,应该如何修复呢?下面我将为大家介绍四个修复vcomp120.dll丢失的方法。 一、使用dll修复程序修复 可以通过百度或许…

Knife4j在springboot3中如何集成呢(如果大家阅读能力好的话,建议直接看作者写的博客。当然,在下面也会附上作者的博客)

一.为什么会写这篇博客呢? 因为本作者在使用springboot2的时候还好好的,将springbooot2升到springboot3的时候,发现我天,knife4j好像出问题了,找了好久才发现时knife4j的版本问题。 二.说一下knife4j的版本问题吧&…

力扣刷题-二叉树-二叉树的层序遍历(相关题目总结)

思路 层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。 需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的…

力扣刷题-二叉树-翻转二叉树

226.翻转二叉树 翻转一棵二叉树。 思路 参考: https://www.programmercarl.com/0226.%E7%BF%BB%E8%BD%AC%E4%BA%8C%E5%8F%89%E6%A0%91.html#%E6%80%9D%E8%B7%AF 如果要从整个树来看,翻转还真的挺复杂,整个树以中间分割线进行翻转&#xf…

【CUDA编程--编程模型简介算子开发流程】

官方文档:https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html 什么是CUDA CUDA全称(Compute Unified Device Architecture)统一计算架构,是NVIDIA推出的并行计算平台深度学习加速:对于神经网络&…

超级干货:光纤知识总结最全的文章

你们好,我的网工朋友。 光纤已经是远距离有线信号传输的主要手段,而安装、维护光纤也是很多人网络布线的基本功。 在网络布线中,通常室外楼宇间幢与幢之间使用的是光缆,室内楼宇内部大都使用的是以太网双绞线,也有使用…

前端案例-css实现ul中对li进行换行

场景描述: 我想要实现,在展示的item个数少于4个的时候,则排成一行,并且均分(比如说有3个,则每个的宽度为33.3%),如果item 个数大于4,则进行换行。 效果如下&#xff1a…

冰点还原精灵_Deep Freeze Standard v8.60.020.5592中文版

eep Freeze(又被成为冰点还原精灵)是Faronics公司出品的一款简单易用的系统还原软件,使用能够帮助用户轻松将系统还原到安装该款软件之后状态,避免因为病毒的入侵以及人为的对系统无意或无意的破坏,让你的系统始终完美…

HTTP——

HTTP 请求报文的构成 如下图: 第一行:HTTP请求的方法,具体是POST方法还是GET方法,或是其它方法;URI就是你的HTTP请求的路径;后面是HTTP协议的版本; 第二行往下连续多行:这些是请求头部分,也就是请求的首部设置的一些信息,相当于对HTTP请求的一些设置; 空格行:在…

【PIE-Engine 数据资源】全球250米LAI产品

文章目录 一、 简介二、描述三、波段四、示例代码参考资料 一、 简介 数据名称全球250米LAI产品时间范围2015年空间范围全球数据来源北京师范大学肖志强教授团队代码片段var images pie.ImageCollection(“BNU/LAI/GLOBAL-250”) 二、描述 全球 250 米叶面指数产品由北京师范…

VS Code设置技巧

基础设置 中文界面 安装扩展:Chinese(Simplified) Language Pack 自动换行 文件 - 首选项 - 设置,搜索wrap,找到Editor: Word Wrap,将其更改为on。

分享一个个人博客神器 VanBlog

一、先看效果图 这是前台页面,我已经发布了一篇文章 这是后台页面 一句话,真的好用,各种功能一应俱全,废话不多说,开始吧。 二、 安装docker容器技术 如果你没有安装 docker 和 docker-compose,可以通…

错误边界(Error boundary)

错误边界(Error boundary): 用来捕获后代组件错误,渲染出备用页面 只能捕获后代组件生命周期产生的错误,不能捕获自己组件产生的错误和其他组件在合成事件、定时器中产生的错误 getDerivedStateFromError配合componentDidCatch 案…

C++--二叉树经典例题

本文,我们主要讲解一些适合用C的数据结构来求解的二叉树问题,其中涉及了二叉树的遍历,栈和队列等数据结构,递归与回溯等知识,希望可以帮助你进一步理解二叉树。 目录​​​​​​​ 1.二叉树的层序遍历 2.二叉树的公…

【Redis】Zset有序集合

上一篇: Hash哈希类型 https://blog.csdn.net/m0_67930426/article/details/134382507?spm1001.2014.3001.5502 目录 Zadd Zrange Zcard Zcount Zrem set是一个无序且元素不可重复的集合 而Zset是一个有序的集合,集合里的每个元素都有一个评分(…

Linux网络——自定义协议

目录 一.什么是协议 二.协议与报文 三.自定义协议 1.封装套接字 2.构建请求与响应 3.序列化和反序列化 4.报头添加和去除 5.报文读取 四.服务器端程序 五.客户端程序 一.什么是协议 协议在生活中泛指:双方或多方为了完成某项任务或达成某种目的而制定的共…

文件操作(上)

目录 为什么使用文件什么是文件?程序文件数据文件文件名 二进制文件和文本文件文件的打开和关闭流和标准流流标准流 文件指针文件的打开和关闭 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 🐒🐒🐒 个人主页 &…

DMDEM部署说明-详细步骤-(DM8达梦数据库)

DMDEM部署说明-详细步骤-DM8达梦数据库 环境介绍1 部署DM8 数据库1.1 创建一个数据库作为DEM后台数据库1.2 创建数据库用户 DEM1.3 使用DEM用户导入dem_init.sql 2 配置tomcat2.1 配置/tomcat/conf/server.xml2.2 修改jvm启动参数 3 配置JAVA 1.8及以上版本的运行时环境3.1 配置…