当前位置: 首页 > news >正文

STM32 CAN快速配置(HAL库版本)

STM32 CAN快速配置(HAL库版本)

目录

  • STM32 CAN快速配置(HAL库版本)
    • 前言
    • 1 软件编程
      • 1.1 初始化
        • 1.1.1 引脚设置
        • 1.1.2 CAN参数设置
        • 1.1.3 CAN滤波器设置
      • 1.2 CAN发送
      • 1.3 CAN接收
    • 2 运行测试
    • 结束语

前言

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

特别说明:关于CAN总线协议和硬件电路等问题,这里不做介绍,网上的资料非常多,不懂的同学请自行查阅。

1 软件编程

1.1 初始化

初始化主要分成三部分:引脚设置,CAN参数设置和CAN滤波器设置。

1.1.1 引脚设置

把CAN_H和CAN_L两个引脚配置成复用功能即可。
注:如果CAN控制芯片的S引脚连接到STM32的话,还得初始化这个引脚,S引脚可以配置成高速模式或静音模式。

参考代码:
注:该代码可以通过STM32CubeMX生成

/**
* @brief CAN MSP Initialization
* This function configures the hardware resources used in this example
* @param hcan: CAN handle pointer
* @retval None
*/
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(hcan->Instance==CAN1){/* USER CODE END CAN1_MspInit 0 *//* Peripheral clock enable */HAL_RCC_CAN1_CLK_ENABLED++;if(HAL_RCC_CAN1_CLK_ENABLED==1){__HAL_RCC_CAN1_CLK_ENABLE();}__HAL_RCC_GPIOA_CLK_ENABLE();/**CAN1 GPIO ConfigurationPA11     ------> CAN1_RXPA12     ------> CAN1_TX*/GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/* CAN1 interrupt Init */HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);    // CAN接收中断HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);}
}

1.1.2 CAN参数设置

HAL库的CAN初始化有几个重要参数,都存放在几个结构体里面(如:CAN_HandleTypeDef,CAN_InitTypeDef),具体的结构体定义可以在HAL库查看。
说明:CAN参数需要根据自己实际的需求来配。

我这里着重讲解一下CAN波特率的配置。

CAN波特率 = CAN时钟频率 / 分频系数 / (TimeSeg1 + TimeSeg2 + 1)。

其中,CAN时钟频率不是固定不变的,它取决于CAN所挂载的总线时钟。
比如STM32F1,系统时钟最大72M,APB1的总线时钟最大36M,而CAN控制器的时钟是挂在APB1的,所以CAN的时钟频率也等于APB1的时钟。
如果换作其他型号的MCU,CAN外设不一定是挂载到APB1上面的,时钟也不一定是36M,比如F4系列,APB1的时钟是可以配成42M的,因此,这个要根据实际情况来配置。

参考代码:
注:该代码可以通过STM32CubeMX生成

/*** @brief CAN1 Initialization Function* @param None* @retval None*/
static void MX_CAN_Init(void)
{// CAN波特率 = CAN时钟频率 / Prescaler / (TimeSeg1 + TimeSeg2 + 1)// 例: 500kbps = 36MHz / 9 / (3 + 4 + 1)   36MHz为该例程APB1的总线时钟/* USER CODE END CAN1_Init 1 */hcan.Instance = CAN1;                     // 配置CAN1hcan.Init.Prescaler = 9;                  // 预分频系数hcan.Init.Mode = CAN_MODE_NORMAL;         // 正常CAN模式        hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;    // 重同步跳跃宽度,CAN_SJW_1TQ~CAN_SJW_4TQ             hcan.Init.TimeSeg1 = CAN_BS1_3TQ;         // TimeSeg1        hcan.Init.TimeSeg2 = CAN_BS2_4TQ;         // TimeSeg2        hcan.Init.TimeTriggeredMode = DISABLE;    // 非时间触发通信模式             hcan.Init.AutoBusOff = DISABLE;           // 软件自动离线管理      hcan.Init.AutoWakeUp = DISABLE;           // 睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)      hcan.Init.AutoRetransmission = DISABLE;   // 禁止报文自动重传               hcan.Init.ReceiveFifoLocked = DISABLE;    // FIFO报文不锁定,新的覆盖旧的              hcan.Init.TransmitFifoPriority = DISABLE; // 优先级由报文标识符决定                 if (HAL_CAN_Init(&hcan) != HAL_OK){Error_Handler();}
}

1.1.3 CAN滤波器设置

CAN滤波器的主要作用是筛选CAN接收的数据,只有满足设定规则的数据才会被接收,否则会被过滤掉。

参考代码:

void CAN_Config(void)
{CAN_FilterTypeDef  sFilterConfig;/* Configure the CAN Filter */sFilterConfig.FilterBank = 0;                      // 过滤器编号,使用一个CAN,则可选0-13;使用两个CAN可选0-27sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  // 过滤器模式,掩码模式或列表模式sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // 过滤器位宽sFilterConfig.FilterIdHigh = 0x0000;               // 过滤器验证码ID高16位,0-0xFFFFsFilterConfig.FilterIdLow = 0x0000;                // 过滤器验证码ID低16位,0-0xFFFFsFilterConfig.FilterMaskIdHigh = 0x0000;           // 过滤器掩码ID高16位,0-0xFFFFsFilterConfig.FilterMaskIdLow = 0x0000;            // 过滤器掩码ID低16位,0-0xFFFFsFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // FIFOx,0或1sFilterConfig.FilterActivation = ENABLE;           // 使能过滤器sFilterConfig.SlaveStartFilterBank = 14;           // 从过滤器编号,0-27,对于单CAN实例该参数没有意义if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK){/* Filter configuration Error */}/* Start the CAN peripheral */if (HAL_CAN_Start(&hcan) != HAL_OK){/* Start Error */}/* Activate CAN RX notification */if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK){/* Notification Error */}
}

1.2 CAN发送

CAN发送需要先配置发送参数,我这里为了方便测试,直接固定发送标准帧,ID也是固定的。
实际使用时可以再增加一个ID的入参,这样会更灵活一点。

参考代码:

/****************************************************************************
* 名    称: uint8_t CAN_Send_Msg(uint8_t* msg, uint8_t len)
* 功    能:can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)
* 入口参数:len:数据长度(最大为8)				     msg:数据指针,最大为8个字节.
* 返回参数:0,成功;其他,失败;
* 说    明:       
****************************************************************************/		
uint8_t CAN_Send_Msg(uint8_t* msg, uint8_t len)
{	uint8_t i=0;uint8_t message[8];uint32_t TxMailbox;CAN_TxHeaderTypeDef CAN_TxHeader;// 设置发送参数CAN_TxHeader.StdId = 0x12;                 // 标准标识符(12bit)CAN_TxHeader.ExtId = 0x12;                 // 扩展标识符(29bit)CAN_TxHeader.IDE = CAN_ID_STD;             // 使用标准帧CAN_TxHeader.RTR = CAN_RTR_DATA;           // 数据帧CAN_TxHeader.DLC = len;                    // 发送长度      CAN_TxHeader.TransmitGlobalTime = DISABLE;// 装载数据for(i = 0; i < len; i++){message[i] = msg[i];}// 发送CAN消息if(HAL_CAN_AddTxMessage(&hcan, &CAN_TxHeader, message, &TxMailbox) != HAL_OK) {return 1;}while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) != 3) {}return 0;	
}

1.3 CAN接收

接收部分只要开启了Rx中断,在CAN控制器收到消息时会调用RxFifo的回调函数,此时我们在这里读取数据并根据实际情况做相应的处理即可。

参考代码:

/*******************************************************************************
* Function Name  : HAL_CAN_RxFifo0MsgPendingCallback
* Description    : 消息接收回调函数
* Input          : hcan
* Output         : None
* Return         : None
****************************************************************************** */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{// 收到CAN数据会触发接收中断,进入该回调函数uint32_t i;uint8_t RxData[8];CAN_RxHeaderTypeDef CAN_RxHeader; if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &CAN_RxHeader, RxData) == HAL_OK){// 串口打印接收结果printf("GetRxMessage, CANID:0x%0X, Data:", CAN_RxHeader.StdId);for(i = 0;i < CAN_RxHeader.DLC; i++){printf("%02x ", RxData[i]);}// 把接收的数据用CAN再发回去CAN_Send_Msg(RxData, CAN_RxHeader.DLC);}
}

2 运行测试

使用USB-CAN工具测试发送:
在这里插入图片描述

消息窗口如下:
在这里插入图片描述
可以看到,上位机发送了一条CAN数据,CANID为0x01,接着就收到了STM32回的一条数据,CANID为0x12(因为我代码固定写死了ID为0x12)。

同样的,通过串口也能看到STM32收到的CAN数据,如下图所示:
在这里插入图片描述
还有一些其他测试,比如收发不同长度,切换扩展帧等等,这里就不展示了,感兴趣的同学可以自己改参数试试。

结论:CAN收发正常。

结束语

好了,关于如何通过STM32如何配置和使用CAN就讲到这里,如果你有什么问题或者有更好的方法,欢迎在评论区留言。

相关文章:

STM32 CAN快速配置(HAL库版本)

STM32 CAN快速配置&#xff08;HAL库版本&#xff09; 目录 STM32 CAN快速配置&#xff08;HAL库版本&#xff09;前言1 软件编程1.1 初始化1.1.1 引脚设置1.1.2 CAN参数设置1.1.3 CAN滤波器设置 1.2 CAN发送1.3 CAN接收 2 运行测试结束语 前言 控制器局域网总线&#xff08;CA…...

【文末送书】全栈开发流程——后端连接数据源(二)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…...

leetcode_27_最小栈

class MinStack { public:MinStack() {}void push(int val) {//只要是压栈&#xff0c;先将元素保存到_elem中_elem.push(val);//如果x小于_min中栈顶的元素&#xff0c;将x再压入_min中if(_min.empty() || val < _min.top()){_min.push(val);}}void pop() {//如果——min栈…...

01-ZooKeeper快速入门

1 Zookeeper概念 Zookeeper是Apache Hadoop项目下的一个子项目&#xff0c;是一个树形目录服务。 zookeeper翻译过来就是 动物园管理员&#xff0c;它是用来管理Hadoop&#xff08;大象&#xff09;、Hive&#xff08;蜜蜂&#xff09;、Pig&#xff08;小猪&#xff09;的管…...

[经典面试题]JS的typeof和instanceof区别

一、typeof typeof 是一个一元操作符不是函数&#xff0c;所以不需要传递参数&#xff0c;使用方法非常简单&#xff1a;typeof A 对于基本类型 let s "Nicholas"; let b true; let i 22; let u; let sb undefined; console.log(typeof s); // string console.…...

C++内存区堆和栈

在C中&#xff0c;内存分成5个区&#xff0c;堆、栈、自由存储区、全局/静态存储区和常量存储区。 栈&#xff0c;就是那些由编译器在需要的时候分配&#xff0c;在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。 堆&#xff0c;就是那些…...

QT中闹钟的设置

.h文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton> //按钮 #include <QTextEdit> //文本 #include <QLabel> //标签 #include <QLineEdit> //行编辑器#include <QTimerEvent> //定时器事件类头文件 #…...

【Redis】几款redis可视化工具(推荐Another Redis Desktop Manager)

Redis是一个超精简的基于内存的键值对数据库(key-value)&#xff0c;一般对并发有一定要求的应用都用其储存session&#xff0c;乃至整个数据库。不过它公自带一个最小化的命令行式的数据库管理工具&#xff0c;有时侯使用起来并不方便。不过Github上面已经有了很多图形化的管理…...

肖sir__设计测试用例方法之因果图07_(黑盒测试)

设计测试用例方法之因果图 一、定义&#xff1a;因果图提供了一个把规格转化为判定表的系统化方法&#xff0c;从该图中可以产生测试数据。其 中&#xff0c;原因是表示输入条件&#xff0c;结果是对输入执 行的一系列计算后得到的输出。 二、因果图方法最终生成的就是判定表。…...

李宏毅-21-hw3:对11种食物进行分类-CNN

一、代码慢慢阅读理解总结内化&#xff1a; 1.关于torch.nn.covd2d()的参数含义、具体用法、功能&#xff1a; &#xff08;1&#xff09;参数含义&#xff1a; 注意&#xff0c;里面的“padding”参数&#xff1a;《both》side所以是上下左右《四》边都会加一个padding数量…...

成集云 | 飞书审批同步金蝶云星空销售订单 | 解决方案

源系统成集云目标系统 方案介绍 飞书是字节跳动于2016年自研的新一代一站式协作平台&#xff0c;将即时沟通、日历、云文档、云盘和工作台深度整合&#xff0c;通过开放兼容的平台&#xff0c;让成员在一处即可实现高效的沟通和流畅的协作&#xff0c;全方位提升企业效率。 …...

06 科技英语|控制与优化学科词汇

maneuver n 策略&#xff1b;v 操控、调遣 manipulate vt 熟练控制 scalability n 可扩展性 leverage n 杠杆&#xff1b;v 促使...改变 flexibility n 弹性 dispatch n 急件&#xff1b;v 调度&#xff1b;派遣 leverage …...

【网络教程】GitHub搜索技巧大揭秘

文章目录 1. 使用关键词优化搜索2. 结合布尔运算符3. 利用星号扩展搜索4. 高级搜索语法5. 按照星标数量搜索6. 使用文件类型搜索7. 在特定分支上搜索8. 使用文件名搜索9. 搜索贡献者10. 使用标签筛选仓库在开发过程中,我们经常需要在GitHub上查找代码、库或相关文档。本文将介…...

AUTOSAR LIN: LDF(LIN Description File)文件解析

LDF文件示例 LIN_description_file "lin_example.ldf" { LIN_protocol_version "2.0";LIN_language_version "2.0";nodes {master: MasterNode;slaves: SlaveNode1, SlaveNode2;};signals {Signal1: MasterNode, SlaveNode1;Signal2: Maste…...

Vue.js 报错:Cannot read property ‘validate‘ of undefined“

错误解决 起因&#xff0c;是我将elemnt-ui登录&#xff0c;默认放在mounted()函数里面&#xff0c;导致vue初始化就调用这个函数。 找了网上&#xff0c;有以下错误原因&#xff1a; 1.一个是你ref写错了&#xff0c;导致获取不了这个表单dom&#xff0c;我这显然不是。 2.…...

vue使用wangEditor

vue版本2.0&#xff1b;editor5.1.23版本&#xff1b;editor-for-vue&#xff1a;1.0.2版本 api文档入口 效果图 安装步骤入口 npm install wangeditor/editor --savenpm install wangeditor/editor-for-vue --save代码 <template><div><div style"bor…...

网络编程、socket编程、多进程并发服务器

网络编程 一、TCP编程的API socket: int socket(int domain, int type, int protocol); 返回值&#xff1a;> 0 代表函数调用成功&#xff0c;这个值是一个文件描述符< 0 代表函数调用失败 int domain&#xff1a;地址簇 AF_INET&#xff1a;IPv4 AF_INET6: IPv6 ​ i…...

Elasticsearch:自动使用服务器时间设置日期字段并更新时区

在大多数情况下&#xff0c;你的数据包含一个以 create_date 命名的字段。 即使没有日期字段&#xff0c;处理各种格式和时区的日期对数据仓库来说也是一个重大挑战。 与此类似&#xff0c;如果要检测变化的数据&#xff0c;则必须准确设置日期字段。 在 Elasticsearch 中还有…...

网络技术三:局域网基本原理

局域网基本原理 使用的协议及线缆 物理层 双绞线 同轴电缆 光纤 无线电 数据链路层 以太网 唯一事实标准 令牌环 淘汰 FDDI 光纤分布式接口 网络层 IP 唯一的事实标准 IPX 淘汰 Apple talk 淘汰 局域网设备 集线器 内部为总线型拓扑 任意时间只能由一台主机占用总线&a…...

Fine-tuning Large Enterprise Language Models via Ontological Reasoning

本文是LLM系列文章&#xff0c;针对《Fine-tuning Large Enterprise Language Models via Ontological Reasoning》的翻译。 基于本体论推理的大型企业语言模型微调 摘要1 引言2 微调LLM的神经符号管道3 通过概念证明进行初步验证4 结论 摘要 大型语言模型&#xff08;LLM&am…...

新手入门:在快马平台生成代码,理解智能应用控制警告的模拟实现

今天想和大家分享一个特别适合编程新手的小项目——通过HTML和JavaScript模拟"智能应用控制"的安全警告弹窗。这个练习不仅能帮助我们理解现代操作系统中的安全机制&#xff0c;还能学到实用的前端开发技巧。 项目背景理解 智能应用控制是现代操作系统的一项重要安全…...

从零入门大模型应用开发:收藏这份学习清单,轻松转型高薪岗位!

文章指出当前AI应用开发社招要求已提升&#xff0c;不再满足于简单的API调用或Demo实现。文章警示三类人慎入AI开发社招&#xff0c;并强调能力复合化、工程深度和业务理解的重要性。作者分享了四年AI开发经验&#xff0c;建议深入原理、重构项目经验&#xff0c;并给出了量化解…...

Matlab GUI计时器:自动更新的数字时钟与恢复/暂停功能的定时器对象实现

Matlab图形用户界面计时器&#xff1a;使用定时器对象自动更新的MatlabGUI&#xff0c;一个数字时钟&#xff0c;作为显示基本组件的快速演示&#xff0c;带有一个按钮&#xff0c;用于恢复/暂停执行更新 实验室配了新酶标仪孵箱但总有人&#xff08;比如同组摸鱼的小师妹顺便…...

选AI面试软件,为何一定要看中防作弊、可解释、全场景?

想象一下&#xff1a;你花了半个月筛选简历&#xff0c;终于确定了100个面试候选人&#xff0c;却发现一半人在用AI生成器写答案、用提词器念稿&#xff0c;甚至找人替考&#xff1b;好不容易拿到AI评分&#xff0c;却看不懂分数怎么来的&#xff0c;候选人质疑时你根本没法解释…...

别再死记硬背了!用MATLAB 5分钟搞定控制系统的稳定裕度计算(附代码)

用MATLAB高效计算控制系统稳定裕度的工程实践指南 在自动控制系统的设计与分析中&#xff0c;稳定裕度是评估系统鲁棒性的关键指标。传统手工计算不仅耗时费力&#xff0c;还容易出错。本文将展示如何利用MATLAB这一强大工具&#xff0c;在5分钟内完成从传递函数定义到稳定裕度…...

MySQL 5.7.32 Online DDL避坑指南:如何避免主从延迟和锁等待?

MySQL 5.7.32 Online DDL实战避坑&#xff1a;高并发场景下的零停机表结构变更策略 在数据库运维的日常工作中&#xff0c;表结构变更&#xff08;DDL&#xff09;操作总是让人又爱又恨。特别是当面对千万级数据表时&#xff0c;一个简单的ALTER TABLE操作就可能引发连锁反应—…...

Z-Image-Turbo-辉夜巫女GPU利用率:监控xinference.log与nvidia-smi协同调参指南

Z-Image-Turbo-辉夜巫女GPU利用率&#xff1a;监控xinference.log与nvidia-smi协同调参指南 1. 引言&#xff1a;为什么需要关注GPU利用率&#xff1f; 当你部署好一个像Z-Image-Turbo-辉夜巫女这样的文生图模型&#xff0c;看着它生成精美的图片时&#xff0c;有没有想过一个…...

AI绘画杀死UI设计师?幸存者在开发岗位的复仇

在数字技术的狂潮中&#xff0c;AI绘画工具的崛起如海啸般席卷设计行业。短短几年间&#xff0c;Midjourney、Stable Diffusion等AI平台已能10秒生成上百张海报&#xff0c;基础美工岗招聘量骤降35%&#xff0c;薪资停滞在4-6K区间。无数UI设计师面临失业危机&#xff0c;仿佛一…...

告别复杂配置!Phi-3-Mini-128K一键部署实测:7GB显存跑通,小白也能玩转大模型

告别复杂配置&#xff01;Phi-3-Mini-128K一键部署实测&#xff1a;7GB显存跑通&#xff0c;小白也能玩转大模型 1. 为什么选择Phi-3-Mini-128K 如果你正在寻找一个既强大又轻量的大语言模型&#xff0c;Phi-3-Mini-128K绝对值得考虑。这个由微软开发的模型虽然只有3.8亿参数…...

ChatGPT_JCM深色模式实现:保护眼睛的界面显示方案

ChatGPT_JCM深色模式实现&#xff1a;保护眼睛的界面显示方案 【免费下载链接】ChatGPT_JCM 项目地址: https://gitcode.com/gh_mirrors/ch/ChatGPT_JCM ChatGPT_JCM是一款功能强大的AI交互工具&#xff0c;其深色模式实现为用户提供了舒适的夜间使用体验&#xff0c;有…...