STM32 CAN使用记录:FDCAN基础通讯

文章目录

  • 目的
  • 基础说明
  • 关键配置与代码
    • 轮询方式
    • 中断方式
    • 收发测试
  • 示例链接
  • 总结

目的

CAN是非常常用的一种数据总线,被广泛用在各种车辆系统中。这篇文章将对STM32中FDCAN的使用做个示例。

CAN的一些基础介绍与使用可以参考下面文章:
《CAN基础概念》https://blog.csdn.net/Naisu_kun/article/details/132814079
《STM32 CAN使用记录:bxCAN基础通讯》https://blog.csdn.net/Naisu_kun/article/details/132830073

本文使用STM32H750作为主控芯片,PD0设置为FDCAN1_RXPD1设置为FDCAN1_TX 。本文使用使用STM32CubeIDE进行开发。

基础说明

STM32中FDCAN和传统的bxCAN的区别除了两者协议本身的区别,在STM32中这两个外设也有较大不同。不同点主要是FIFIO和Filter分布。bxCAN中FIFIO和Filter都是设定好一定组数的,我们是现成的拿来用;而FDCAN中提供了一定的内存,用户可以手动分配各个FIFIO和Filter的大小。
在这里插入图片描述

关于FDCAN的特征说明可以参考ST官方文档 《AN5348: Introduction to FDCAN peripherals for STM32 product classes》

关键配置与代码

轮询方式

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

除了默认生成的代码只需在 main.c 中手动添加一些代码即可:

#include "main.h"FDCAN_HandleTypeDef hfdcan1;void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_FDCAN1_Init(void);int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_FDCAN1_Init();/**************** 以下为过滤器设置 ****************/FDCAN_FilterTypeDef sFilterConfig;// 下面这组设置只接受标准帧ID为0x666的消息sFilterConfig.IdType = FDCAN_STANDARD_ID;sFilterConfig.FilterIndex = 0;sFilterConfig.FilterType = FDCAN_FILTER_MASK;sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;sFilterConfig.FilterID1 = 0x666;sFilterConfig.FilterID2 = 0x7FF;sFilterConfig.RxBufferIndex = 0;HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig);// 下面这组设置只接受扩展ID为0x233和0x2233的消息sFilterConfig.IdType = FDCAN_EXTENDED_ID;sFilterConfig.FilterIndex = 0;sFilterConfig.FilterType = FDCAN_FILTER_MASK;sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;sFilterConfig.FilterID1 = 0x00002233;sFilterConfig.FilterID2 = 0x1FFFDFFF;sFilterConfig.RxBufferIndex = 0;HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig);// 默认情况下,如果未配置全局过滤器,则会接收所有不匹配的帧并将其重定向到RxFIFO0// 后面四个参数分别 拒绝未匹配的标准数据帧 拒绝未匹配的扩展数据帧 拒绝标准远程帧 拒绝扩展远程帧HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE);/**************** 以下为启动CAN外设 ****************/HAL_FDCAN_Start(&hfdcan1);while (1){/**************** 以下为接收消息并回发处理 ****************/if(HAL_FDCAN_GetRxFifoFillLevel(&hfdcan1, FDCAN_RX_FIFO0) != 0) // 接收队列不为0,有数据可读{FDCAN_RxHeaderTypeDef   RxHeader; // 用来保存接收到的数据帧头部信息uint8_t                 RxData[64]; // 用来保存接收数据端数据if(HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK) // 从接收队列中读取数据帧{FDCAN_TxHeaderTypeDef   TxHeader = {0}; // 用来保存发送数据帧头部信息uint8_t                 TxData[64]; // 用来保存发送数据帧数据TxHeader.Identifier = RxHeader.Identifier;TxHeader.IdType = RxHeader.IdType; // 标准-FDCAN_STANDARD_ID; 扩展-FDCAN_EXTENDED_IDTxHeader.TxFrameType = RxHeader.RxFrameType; // 数据帧-FDCAN_DATA_FRAME; 远程帧-FDCAN_REMOTE_FRAMETxHeader.DataLength = RxHeader.DataLength; // FDCAN_DLC_BYTES_xx// xx = 0 1 2 3 4 5 6 7 8 12 16 20 24 32 48 64TxHeader.ErrorStateIndicator = RxHeader.ErrorStateIndicator; // FDCAN_ESI_ACTIVE FDCAN_ESI_PASSIVETxHeader.BitRateSwitch = RxHeader.BitRateSwitch; // 波特率不可变-FDCAN_BRS_OFF; 波特率可变-FDCAN_BRS_ONTxHeader.FDFormat = RxHeader.FDFormat; // 经典CAN-FDCAN_CLASSIC_CAN; CANFD-FDCAN_FD_CAN// TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;// TxHeader.MessageMarker = 0;for(int i=0; i<64; i++){TxData[i] = RxData[i];}while(HAL_FDCAN_GetTxFifoFreeLevel(&hfdcan1) == 0); // 等待有发送邮箱可用HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData); // 发送数据帧}}}
}

中断方式

在这里插入图片描述

除了默认生成的代码只需在 main.c 中手动添加一些代码即可:

#include "main.h"FDCAN_HandleTypeDef hfdcan1;void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_FDCAN1_Init(void);/**************** 以下为重写中断回调函数 ****************/
// Fifo0收到消息回调
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{if (hfdcan == &hfdcan1) // 判断是hfdcan1的中断{if ((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET) // 判断是FIFO0_NEW_MESSAGE回调{FDCAN_RxHeaderTypeDef   RxHeader; // 用来保存接收到的数据帧头部信息uint8_t                 RxData[64]; // 用来保存接收数据端数据if(HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK) // 从接收队列中读取数据帧{FDCAN_TxHeaderTypeDef   TxHeader = {0}; // 用来保存发送数据帧头部信息uint8_t                 TxData[64]; // 用来保存发送数据帧数据TxHeader.Identifier = RxHeader.Identifier;TxHeader.IdType = RxHeader.IdType; // 标准-FDCAN_STANDARD_ID; 扩展-FDCAN_EXTENDED_IDTxHeader.TxFrameType = RxHeader.RxFrameType; // 数据帧-FDCAN_DATA_FRAME; 远程帧-FDCAN_REMOTE_FRAMETxHeader.DataLength = RxHeader.DataLength; // FDCAN_DLC_BYTES_xx// xx = 0 1 2 3 4 5 6 7 8 12 16 20 24 32 48 64TxHeader.ErrorStateIndicator = RxHeader.ErrorStateIndicator; // FDCAN_ESI_ACTIVE FDCAN_ESI_PASSIVETxHeader.BitRateSwitch = RxHeader.BitRateSwitch; // 波特率不可变-FDCAN_BRS_OFF; 波特率可变-FDCAN_BRS_ONTxHeader.FDFormat = RxHeader.FDFormat; // 经典CAN-FDCAN_CLASSIC_CAN; CANFD-FDCAN_FD_CAN// TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;// TxHeader.MessageMarker = 0;for(int i=0; i<64; i++){TxData[i] = RxData[i];}while(HAL_FDCAN_GetTxFifoFreeLevel(&hfdcan1) == 0); // 等待有发送邮箱可用HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData); // 发送数据帧}}}
}int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_FDCAN1_Init();/**************** 以下为过滤器设置 ****************/FDCAN_FilterTypeDef sFilterConfig;// 下面这组设置只接受标准帧ID为0x666的消息sFilterConfig.IdType = FDCAN_STANDARD_ID;sFilterConfig.FilterIndex = 0;sFilterConfig.FilterType = FDCAN_FILTER_MASK;sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;sFilterConfig.FilterID1 = 0x666;sFilterConfig.FilterID2 = 0x7FF;sFilterConfig.RxBufferIndex = 0;HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig);// 下面这组设置只接受扩展ID为0x233和0x2233的消息sFilterConfig.IdType = FDCAN_EXTENDED_ID;sFilterConfig.FilterIndex = 0;sFilterConfig.FilterType = FDCAN_FILTER_MASK;sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;sFilterConfig.FilterID1 = 0x00002233;sFilterConfig.FilterID2 = 0x1FFFDFFF;sFilterConfig.RxBufferIndex = 0;HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig);// 默认情况下,如果未配置全局过滤器,则会接收所有不匹配的帧并将其重定向到RxFIFO0// 后面四个参数分别 拒绝未匹配的标准数据帧 拒绝未匹配的扩展数据帧 拒绝标准远程帧 拒绝扩展远程帧HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE);/**************** 以下为启动中断 ****************/HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); // 使能FIFO0数据接收中断/**************** 以下为启动CAN外设 ****************/HAL_FDCAN_Start(&hfdcan1);while (1){}
}

收发测试

本示例演示结果可以通过各种CAN工具配合上位机软件进行测试:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

示例链接

仓库地址: https://github.com/NaisuXu/STM32_MCU_Examples

本文中的示例位于仓库中 FDCAN_RxTxPoll_H750FDCAN_RxTxIT_H750

总结

STM32中使用FDCAN并不复杂,进行配置生成代码后只需要设置过滤器,然后就可以收发数据了。

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

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

相关文章

基于Xml方式Bean的配置-Bean的延时加载

SpringBean的配置详解 Bean的延时加载 当lazy-init设置为true时为延时加载&#xff0c;也就是当Spring容器创建的时候&#xff0c;不会立即创建Bean实例&#xff0c;等待用到时再创建Bean实例并储存到单例池中&#xff0c;后续使用该Bean时直接从单例池中获取即可&#xff0c;…

手把手教你搭建农产品商城小程序:详细步骤解析

随着移动互联网的普及&#xff0c;越来越多的人开始关注如何在手机上进行购物&#xff0c;尤其是对于农产品这类日常生活所需品。本文将手把手教你搭建一个农产品商城小程序&#xff0c;让你轻松实现在手机上购买农产品的愿望。 一、登录乔拓云网后台 首先&#xff0c;我们需要…

83 # 静态服务中间件 koa-static 的使用以及实现

静态服务中间件&#xff1a;koa-static 中间件可以决定是否向下执行&#xff0c;如果自己可以处理&#xff0c;那么直接处理完毕结束&#xff0c;如果自己处理不了&#xff0c;next 方法会继续向下执行 新建 public 文件夹&#xff0c;里面添加 index.html、style.css 文件 …

使用IDEA开发Servlet

一、新建工程 二、填写新工程的基本信息 javaee8的项目可以运行在tomcat9 三、配置tomcat 1、编辑server信息 “On frame deactivation”的意思是idea窗口发生切换时。 2、编辑部署信息 war exploded方式&#xff0c;这种方式是以文件夹方式部署的&#xff0c;支持热加载。 …

400电话客服中心电话:为您提供全方位的客户服务

在现代商业环境中&#xff0c;提供优质的客户服务是企业成功的关键之一。为了满足客户的需求和解决问题&#xff0c;许多企业选择设立400电话客服中心。400电话是一种特殊的电话号码&#xff0c;可以通过固定电话和移动电话拨打&#xff0c;客户可以通过这个号码与企业进行沟通…

2023年最热门的编程语言:前进的趋势和机会

2023年最热门的编程语言&#xff1a;前进的趋势和机会 2023年最热门的编程语言&#xff1a;前进的趋势和机会摘要引言1. 编程语言的热门趋势1.1 新兴编程语言的崛起1.2 编程语言的可持续性发展1.3 跨平台编程语言的兴起1.4 人工智能和机器学习编程语言的需求 2. 编程语言职业机…

HDMI协议Ver2.0a(学习笔记)

1 简介 本规范由HDMI论坛制定 2.目的和范围 本文件构成了高清多媒体接口2.0版规范&#xff08;HDMI规范2.0版&#xff09;。本规范通过引用纳入了HDMI规范1.4b版&#xff0c;并定义了附加和改进的功能。对Source、Sink、中继器和电缆的合规性所需的机械、电气、行为和协议要…

QT:使用普通按钮、网格布局管理器、标签、行编辑器、水平布局管理器、垂直布局管理器做一个小项目

widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton> //普通按钮 #include <QGridLayout> //网格布局管理器 #include <QLabel> //标签 #include <QLineEdit> //行编辑器 #include <QHBoxLayo…

Android 系统中适配OAID获取

一、OAID概念 OAID&#xff08;Open Anonymous Identification&#xff09;是一种匿名身份识别标识符&#xff0c; 用于在移动设备上进行广告追踪和个性化广告投放。它是由中国移动通信集 团、中国电信集团和中国联通集团共同推出的一项行业标准 OAID值为一个64位的数字 二、…

Linux中安装MySQL_图解_2023新

1.卸载 为了避免不必要的错误发生,先将原有的文件包进行查询并卸载 // 查询 rpm -qa | grep mysql rpm -qa | grep mari// 卸载 rpm -e 文件名 --nodeps2.将安装包上传到指定文件夹中 这里采用的是Xftp 3.将安装包进行解压 tar -zxvf 文件名 -C 解压路径4.获取解压的全路…

生成代理:人类行为的交互模拟(Generative Agents: Interactive Simulacra of Human Behavior)

Generative Agents: Interactive Simulacra of Human Behavior 简介 论文是斯坦福大学和deepmind团队联合发表&#xff0c;主要介绍了一种利用LLM模型指导生成Agents代理的方法&#xff0c;让代理具有记忆、反思和规划的能力。 结合LLM模型创造了一个系统架构&#xff0c;架构…

Qt扩展-KDDockWidgets 简介及配置

Qt扩展-KDDockWidgets 简介及配置] 一、概述二、编译 KDDockWidgets 库1. Cmake Gui 中选择源文件和编译后的路径2. 点击Config&#xff0c;配置好编译器3. 点击Generate4. 在存放编译的文件夹输入如下命令开始编译 三、qmake 配置 一、概述 kdockwidgets是一个由KDAB组织编写…

GPIO子系统编写LED灯的驱动、linux内核定时器

一、GPIO子系统 1.概念&#xff1a; 一个芯片厂商生产出芯片后会给linux提供一个当前芯片中gpio外设的驱动&#xff0c;我们当前只需要调用对应的厂商驱动即可完成硬件的控制。而linux内核源码中的gpio厂商驱动有很多&#xff0c;这里linux内核对厂商驱动做了一些封装&#x…

无涯教程-JavaScript - MUNIT函数

描述 MUNIT函数返回指定尺寸的单位矩阵。 语法 MUNIT (dimension)争论 Argument描述Required/OptionalDimension Dimension是一个整数,指定要返回的单位矩阵的尺寸。 尺寸必须大于零。 Required Notes MUNIT返回一个数组。因此,应将其作为数组公式输入 MUNIT (N)$\begin{m…

在docker中安装MQTT教程

网上的好多关于在docker中安装MQTT教程都是错误的不完整的。这篇博客是完整的&#xff0c;实践过的&#xff0c;踩过了很多的坑得来的&#xff0c;欢迎大家享用&#xff01; 1、首先在docker中拉取镜像 docker pull eclipse-mosquitto2、创建配置文件目录 mkdir -p /docker/…

Typora远程代码执行漏洞CVE-2023-2317

0x00 前言 漏洞详情 版本16.7以前的Typora中的updater/update.html存在基于DOM的XSS&#xff0c;可以通过加载定制的markdown文件实现任意javascript代码执行。 原理分析 漏洞触发点位于Typora的updater.html文件&#xff0c;通过特定协议typora://即可访问&#xff0c;同时…

公司固定资产管理定制方案怎么写

有效的固定资产管理对企业的成功至关重要。然而&#xff0c;如何制定一套既符合公司需求又具有前瞻性的固定资产管理定制方案&#xff0c;是每个企业都需要面对的挑战。本文将从创新、流畅和清晰的角度出发&#xff0c;探讨如何撰写一份成功的固定资产管理定制方案。 创新  …

Spring实例化源码解析(一)

invokeBeanFactoryPostProcessors 前言 AbstractApplicationContext类的refresh方法是spring实例化流程的开始。本章主要是介绍invokeBeanFactoryPostProcessors(beanFactory)方法&#xff0c;对其内部源码进行详细分析。接下来就来看看这句简单的代码后面具体做了什么。Spri…

R语言绘图-3-Circular-barplot图

0. 参考&#xff1a; https://r-graph-gallery.com/web-circular-barplot-with-R-and-ggplot2.html 1. 说明&#xff1a; 利用 ggplot 绘制 环状的条形图 (circular barplot)&#xff0c;并且每个条带按照数值大小进行排列。 2 绘图代码: 注意&#xff1a;绘图代码中的字体…

构建本地Web小游戏网站:Ubuntu下的快速部署与公网用户远程访问

文章目录 前言1. 本地环境服务搭建2. 局域网测试访问3. 内网穿透3.1 ubuntu本地安装cpolar内网穿透3.2 创建隧道3.3 测试公网访问 4. 配置固定二级子域名4.1 保留一个二级子域名4.2 配置二级子域名4.3 测试访问公网固定二级子域名 前言 网&#xff1a;我们通常说的是互联网&am…