Can通信流程
下面给出一个更详细的 CAN 发送报文的程序流程说明,结合 HAL 库的使用及代码示例,帮助你了解每一步的具体操作和内部原理。
一、系统与外设初始化
1.1 HAL 库初始化
在 main() 函数开头,首先调用 HAL 库初始化函数:
HAL_Init();
- 作用:重置外设、初始化系统定时器,并设置 NVIC 分组等。
- 细节:这一步保证后续调用 HAL 库函数时,各个全局变量和中断配置已就绪。
1.2 系统时钟配置
调用时钟配置函数(通常由 CubeMX生成):
SystemClock_Config();
- 作用:设置系统时钟源、PLL 频率、各总线的分频系数。
- 细节:CAN 模块依赖于时钟,必须保证 CAN 所在总线的时钟已使能。
1.3 GPIO 初始化
调用初始化 GPIO 的函数(通常在 gpio.c 中定义,如 MX_GPIO_Init()):
MX_GPIO_Init();
- 作用:初始化所有用到的 GPIO,包括 CAN_TX 和 CAN_RX 所对应的引脚。
- 细节:这些引脚需要配置为“复用功能”(Alternate Function),并设置对应的 AF 映射(如
GPIO_AF9_CAN1),以便与 CAN 外设关联。
1.4 CAN 外设低级硬件初始化
通过 HAL 库的 MSP 回调函数进行:
- 在
HAL_CAN_MspInit()中,使能 CAN 所在外设的时钟、配置相关 GPIO、设置 NVIC 中断优先级等。 - 例如:
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan) {if(hcan->Instance==CAN1){__HAL_RCC_CAN1_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitStruct = {0};// 配置 CAN_TX、CAN_RX 所对应的引脚(假设为 PA11、PA12)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);// 配置 NVIC 中断(可选,根据需要启用接收/错误中断)HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);} } - 作用:为后续 CAN 模块初始化提供硬件资源支持。
二、CAN 外设初始化及滤波器配置
2.1 配置 CAN_HandleTypeDef 并调用 HAL_CAN_Init()
在 main() 或专用初始化函数中:
CAN_HandleTypeDef hcan1;hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 16; // 根据时钟计算波特率
hcan1.Init.Mode = CAN_MODE_NORMAL; // 工作模式(正常/回环等)
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_1TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_1TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = ENABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;if (HAL_CAN_Init(&hcan1) != HAL_OK)
{// 初始化失败处理Error_Handler();
}
- 作用:通过调用
HAL_CAN_Init(),配置 CAN 控制器的各种参数。 - 细节:调用过程中会自动调用
HAL_CAN_MspInit()完成低级资源初始化。
2.2 配置 CAN 滤波器
CAN 的滤波器决定了哪些报文会被 CAN 模块接收。调用 HAL 提供的函数或用户封装的函数来配置滤波器。
CAN_FilterTypeDef canFilterConfig;
canFilterConfig.FilterActivation = ENABLE;
canFilterConfig.FilterBank = 0; // 滤波器编号(根据硬件数量选择)
canFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
canFilterConfig.FilterIdHigh = 0x0000; // 根据需求设置过滤的 ID(高位)
canFilterConfig.FilterIdLow = 0x0000; // (低位)
canFilterConfig.FilterMaskIdHigh = 0x0000; // 掩码,高位(0表示不过滤,即接收所有)
canFilterConfig.FilterMaskIdLow = 0x0000; // 掩码,低位
canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;if (HAL_CAN_ConfigFilter(&hcan1, &canFilterConfig) != HAL_OK)
{// 滤波器配置失败处理Error_Handler();
}
- 作用:指定 CAN 模块只接收符合条件的报文。
- 细节:滤波器必须在 CAN 启动之前配置完成。通常在
HAL_CAN_Init()之后,HAL_CAN_Start()之前完成滤波器配置。
2.3 启动 CAN 模块
调用启动函数:
if (HAL_CAN_Start(&hcan1) != HAL_OK)
{// 启动失败处理Error_Handler();
}
- 作用:使 CAN 模块从初始化状态进入正常工作状态,此时发送和接收功能均可使用。
- 细节:启动后,可以使能中断,开始接收和发送数据。
三、构造和发送 CAN 报文
3.1 构造发送数据结构
通常使用 HAL 库提供的 CAN_TxHeaderTypeDef 结构体,同时准备数据数组。例如:
CAN_TxHeaderTypeDef TxHeader;
uint8_t TxData[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};TxHeader.StdId = 0x123; // 标准标识符
TxHeader.ExtId = 0x01; // 如果使用扩展 ID,此项有效
TxHeader.RTR = CAN_RTR_DATA; // 数据帧(非远程帧)
TxHeader.IDE = CAN_ID_STD; // 标准帧
TxHeader.DLC = 8; // 数据长度:8 字节
TxHeader.TransmitGlobalTime = DISABLE;
- 作用:设置报文的 ID、数据长度、数据帧类型等。
- 细节:字段设置应根据应用协议要求,确保接收端能正确解析数据。
3.2 将报文写入发送邮箱并启动发送
调用 HAL 库的发送函数:
uint32_t TxMailbox;
if (HAL_CAN_AddTxMessage(&hcan1, &TxHeader, TxData, &TxMailbox) != HAL_OK)
{// 发送失败处理,例如邮箱未空或总线错误Error_Handler();
}
- 作用:将构造好的报文放入 CAN 控制器的发送邮箱,由硬件完成后续发送过程。
- 细节:
TxMailbox用于返回所使用的发送邮箱编号(CAN 发送邮箱通常有 3 个)。- 如果返回错误,则需要根据错误码进行重发或错误处理。
3.3 发送过程监控与确认
- 轮询检查:可以通过轮询
HAL_CAN_GetTxMailboxesFreeLevel(&hcan1)来判断是否还有空邮箱。 - 中断回调:也可以使用 HAL 提供的回调函数,例如
HAL_CAN_TxMailbox0CompleteCallback()(如果启用了对应中断),来确认某个邮箱完成发送。 - 错误处理:在发送过程中,如果检测到错误(例如仲裁失败、总线错误等),需要调用错误回调
HAL_CAN_ErrorCallback()进行处理。
四、CAN 接收(补充说明)
虽然主要讨论发送流程,但在实际应用中,发送报文后 CAN 控制器也可能接收到响应数据。一般流程如下:
- 中断处理
- 当 CAN 模块检测到有报文到达 FIFO0 时,HAL 库会调用回调函数:
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {CAN_RxHeaderTypeDef RxHeader;uint8_t RxData[8];if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK){// 对接收到的数据进行处理} }
- 当 CAN 模块检测到有报文到达 FIFO0 时,HAL 库会调用回调函数:
- 数据处理
- 在回调函数中,读取报文内容,根据 ID 和数据内容进行相应的业务处理。
五、总结整个流程
-
初始化阶段
- HAL 初始化、系统时钟、GPIO 配置、CAN MSP 初始化(使能时钟、GPIO、NVIC 等)。
-
CAN 模块初始化
- 配置 CAN 参数(波特率、模式等),调用
HAL_CAN_Init()。 - 配置滤波器(决定哪些报文被接收),调用
HAL_CAN_ConfigFilter()。 - 启动 CAN 模块,调用
HAL_CAN_Start()。
- 配置 CAN 参数(波特率、模式等),调用
-
发送阶段
- 构造发送报文(填写 CAN_TxHeaderTypeDef、数据数组)。
- 将报文写入发送邮箱,调用
HAL_CAN_AddTxMessage()。 - 监控发送过程,处理发送成功或错误。
这种详细流程确保在发送报文前,所有硬件和软件配置都已完成,并且在发送过程中对可能出现的错误提供了检查和处理机制。通过这种模块化设计,整个 CAN 通信过程清晰而可靠,便于后续的调试和维护。
相关文章:
Can通信流程
下面给出一个更详细的 CAN 发送报文的程序流程说明,结合 HAL 库的使用及代码示例,帮助你了解每一步的具体操作和内部原理。 一、系统与外设初始化 1.1 HAL 库初始化 在 main() 函数开头,首先调用 HAL 库初始化函数: HAL_Init()…...
小白闯AI:Llama模型Lora中文微调实战
文章目录 0、缘起一、如何对大模型进行微调二、模型微调实战0、准备环境1、准备数据2、模型微调第一步、获取基础的预训练模型第二步:预处理数据集第三步:进行模型微调第四步:将微调后的模型保存到本地4、模型验证5、Ollama集成部署6、结果测试三、使用总结AI是什么?他应该…...
rip 协议详细介绍
以下是关于 RIP(Routing Information Protocol,路由信息协议) 的详细介绍,涵盖其工作原理、版本演进、配置方法、优缺点及实际应用场景。 1. RIP 协议概述 类型:动态路由协议,基于距离矢量算法(…...
同旺科技USB to SPI 适配器 ---- 指令之间延时功能
所需设备: 内附链接 1、同旺科技USB to SPI 适配器 1、指令之间需要延时发送怎么办?循环过程需要延时怎么办?如何定时发送?现在这些都可以轻松解决; 2、只要在 “发送数据” 栏的Delay单元格里面输入相应的延迟时间就…...
2024年MathorCup数学建模D题量子计算在矿山设备配置及运营中的建模应用解题文档与程序
2024年第十四届MathorCup高校数学建模挑战赛 D题 量子计算在矿山设备配置及运营中的建模应用 原题再现: 随着智能技术的发展,智慧矿山的概念越来越受到重视。越来越多的设备供应商正在向智慧矿山整体解决方案供应商转型,是否具备提供整体解…...
自动化机器学习(TPOT优化临床试验数据)
目录 自动化机器学习(TPOT优化临床试验数据)1. 引言2. 项目背景与意义2.1 临床试验数据分析的重要性2.2 自动化机器学习的优势2.3 工业级数据处理与GPU加速需求3. 数据集生成与介绍3.1 数据集构成3.2 数据生成方法4. 自动化机器学习与TPOT4.1 自动化机器学习简介4.2 TPOT在临…...
回归——数学公式推导全过程
文章目录 一、案例引入 二、如何求出正确参数 1. 最速下降法 1)多项式回归 2)多重回归 2. 随机梯度下降法 一、案例引入 以Web广告和点击量的关系为例来学习回归,假设投入的广告费和点击量呈现下图对应关系。 思考:如果花了…...
Redisson分布式锁(超时释放及锁续期)
🍓 简介:java系列技术分享(👉持续更新中…🔥) 🍓 初衷:一起学习、一起进步、坚持不懈 🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏 🍓 希望这篇文章对你有所帮助,欢…...
音视频学习(三十):fmp4
FMP4(Fragmented MP4)是 MP4(MPEG-4 Part 14)的扩展版本,它支持流式传输,并被广泛应用于DASH(Dynamic Adaptive Streaming over HTTP)和HLS(HTTP Live Streaming…...
【语料数据爬虫】Python爬虫|批量采集讲话稿数据【范文网】(2)
前言 本文是该专栏的第7篇,后面会持续分享Python爬虫采集各种语料数据的的干货知识,值得关注。 本文,笔者将主要介绍基于Python,来实现批量采集范文网“讲话稿”数据。同时,本文也是采集“讲话稿”数据系列的第2篇。 采集相关数据的具体细节部分以及详细思路逻辑,笔者将…...
Java安全-类的动态加载
类的加载过程 先在方法区找class信息,有的话直接调用,没有的话则使用类加载器加载到方法区(静态成员放在静态区,非静态成功放在非静态区),静态代码块在类加载时自动执行代码,非静态的不执行;先父类后子类,…...
内存取证之windows-Volatility 3
一,Volatility 3下载 1.安装Volatility 3。 要求:python3.7以上的版本,我的是3,11,这里不说python的安装方法 使用 pip 安装 Volatility 3: pip install volatility3 安装完成后,验证安装: v…...
WIFI p2p连接总结
p2p 设备角色 go 为 group owner,类似 ap 的功能,控制 p2p 组,每个 group 只有一个 go gc 是 client,为连接 go 的设备,是组成员 P2P 扫描 p2p discovery 利用 probe request 和 probe response 帧来搜索周围的 p2…...
React Native进阶(六十):webview实现屏蔽所嵌套web页面异常弹窗
文章目录 一、前言二、解决方案三、注意事项四、拓展阅读 一、前言 在React Native项目集成web页面时,webview嵌套方式是常用方式。如果所嵌套的web页面由于某种不可控因素导致出现错误弹窗信息,webview作为web嵌套方式应该对其行为可控。 React Nativ…...
fastapi+playwright爬取google搜索1-3页的关键词返回json
1,playwright无头 2,代理池随机获取代理ip 3,随机浏览行为,随机页面滚动 4,启用stealth模式 5,随机延时搜索 from fastapi import FastAPI, HTTPException from fastapi.responses import JSONResponse import asyncio from concurrent.futures import ThreadPool…...
施磊老师高级c++(五)
文章目录 一、设计模式二、单例模式(创建型模式)- 重点(共三种代码)1.1 饿汉式单例模式 -- 不受欢迎1.2 懒汉式单例模式 -- 受欢迎1.3 线程安全的懒汉式单例模式--锁volatile 三、工厂模式(创建型模式)3.1 简单工厂模式3.2 工厂方…...
鸿蒙相机开发实战:从设备适配到性能调优 —— 我的 ArkTS 录像功能落地手记(API 15)
引言:为什么我要写这份开发指南? 作为一名老技术,最近特别喜欢研究鸿蒙相机功能,而且目前已经更新到API15了,那么咱们更要好好研究一下。而且从手持云台到车载记录仪,每个项目都面临独特挑战:车…...
MySQL中怎么分析性能?
MySQL中主要有4种方式可以分析数据库性能,分别是慢查询日志,profile,Com_xxx和explain。 慢查询日志 先用下面命令查询慢查询日志是否开启, show variables like slow_query_log;# 一般默认都是以下结果 ---------------------…...
阿里云对象存储教程
搜“对象存储->免费试用” 选择你的心仪产品,我使用的是第一个 创建后获得三个实例: 点击右上角自己的账号可以进入到AccessKey管理界面 回到对象存储控制台创建Bucket实例 在以下文件中替换自己Bucket的信息即可美美使用~ package com.kitty.blog…...
【Node.js入门笔记10---http 模块】
Node.js入门笔记10 Node.js---http 模块一、核心功能0.学习http的前提1. 创建 HTTP 服务器2. 处理请求和响应 二、进阶用法1. 路由管理2. 处理 POST 请求3. 中间件模式 三、常见场景四、错误处理与安全五、对比 http 与 Express六、工具库推荐: Node.js—http 模块 …...
深拷贝在 JavaScript 中的几种实现方式对比
深拷贝在 JavaScript 中的几种实现方式对比 1. JSON 序列化法2. 结构化克隆(structuredClone)原理与使用 3. 自定义深拷贝函数原理与使用 性能对比与选择建议性能比较 综合建议:示例代码整合总结 在开发过程中,我们经常需要对对象…...
实验11 机器学习-贝叶斯分类器
实验11 机器学习-贝叶斯分类器 一、实验目的 (1)理解并熟悉贝叶斯分类器的思想和原理; (2)熟悉贝叶斯分类器的数学推导过程; (3)能运用贝叶斯分类器解决实际问题并体会算法的效果&a…...
Delta Lake 解析:架构、数据处理流程与最佳实践
Delta Lake 是一个基于 Apache Spark 的开源存储层,主要解决传统数据湖(Data Lake)缺乏 ACID 事务、数据一致性和性能优化的问题,使大数据处理更加可靠、高效。从本质上讲,它让数据湖具备了数据仓库的结构化管理能力&a…...
OpenHarmony子系统开发 - 电池管理(二)
OpenHarmony子系统开发 - 电池管理(二) 五、充电限流限压定制开发指导 概述 简介 OpenHarmony默认提供了充电限流限压的特性。在对终端设备进行充电时,由于环境影响,可能会导致电池温度过高,因此需要对充电电流或电…...
hive 数据简介
Hive介绍 1)Hive简介 Hive是基于Hadoop的一个数据仓库工具,用于结构化数据的查询、分析和汇总。Hive提供类SQL查询功能,它将SQL转换为MapReduce程序。 Hive不支持OLTP,Hive无法提供实时查询。 2)Hive在大数据生态环境…...
Win32桌面编程:ACLUI.DLL,EditSecurity(IntPtr hwndOwner, ISecurityInformation psi)
在Windows编程中,我们通常需要借助通用对话框的力量,今天我们就聊一下“安全属性表”通用对话框的使用心得。 当我们调用EditSecurity函数时: 1.EditSecurity将调用ISecurityInformation中的GetObjectInformation函数 在编写 ISecurityInf…...
数据分析异步进阶:aiohttp与Asyncio性能提升
一、时间轴呈现方案进程 2023-04-01:需求确认 确定目标:使用aiohttp与Asyncio提升采集性能,目标采集今日头条网站的新闻数据(标题、内容、时间等)。同时要求在程序中加入代理IP、Cookie和UserAgent的设置,…...
《AI大模型趣味实战 》第8集:多端适配 个人新闻头条 基于大模型和RSS聚合打造个人新闻电台(Flask WEB版) 2
《AI大模型趣味实战 》第8集:多端适配 个人新闻头条 基于大模型和RSS聚合打造个人新闻电台(Flask WEB版) 2 摘要 本文末尾介绍了如何实现新闻智能体的方法。在信息爆炸的时代,如何高效获取和筛选感兴趣的新闻内容成为一个现实问题。本文将带领读者通过P…...
低配电脑畅玩《怪物猎人:荒野》,ToDesk云电脑优化从30帧到144帧?
《怪物猎人:荒野(Monster Hunter Wilds)》自2025年正式发售以来已取得相当亮眼的成绩,仅用三天时间便轻松突破800万销量,目前顺利蝉联周榜冠军;凭借着开放世界的宏大场景和丰富的狩猎玩法,该游戏…...
Leetcode刷题笔记1 图论part03
卡码网 101 孤岛总面积 from collections import deque directions [[0, 1], [1, 0], [0, -1], [-1, 0]] count 0def main():global countn, m map(int, input().split())grid []for _ in range(n):grid.append(list(map(int, input().split())))for i in range(n):if gri…...
