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 控制器也可能接收到响应数据。一般流程如下:

  1. 中断处理
    • 当 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){// 对接收到的数据进行处理}
      }
      
  2. 数据处理
    • 在回调函数中,读取报文内容,根据 ID 和数据内容进行相应的业务处理。

五、总结整个流程

  1. 初始化阶段

    • HAL 初始化、系统时钟、GPIO 配置、CAN MSP 初始化(使能时钟、GPIO、NVIC 等)。
  2. CAN 模块初始化

    • 配置 CAN 参数(波特率、模式等),调用 HAL_CAN_Init()
    • 配置滤波器(决定哪些报文被接收),调用 HAL_CAN_ConfigFilter()
    • 启动 CAN 模块,调用 HAL_CAN_Start()
  3. 发送阶段

    • 构造发送报文(填写 CAN_TxHeaderTypeDef、数据数组)。
    • 将报文写入发送邮箱,调用 HAL_CAN_AddTxMessage()
    • 监控发送过程,处理发送成功或错误。

这种详细流程确保在发送报文前,所有硬件和软件配置都已完成,并且在发送过程中对可能出现的错误提供了检查和处理机制。通过这种模块化设计,整个 CAN 通信过程清晰而可靠,便于后续的调试和维护。

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

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

相关文章

15 数据结构及算法应用

15 数据结构及算法应用 15.1 算法策略区分 15.1.1、分治法 特征:把一个问题拆分成多个小规模的相同子问题,一般可用递归解决。 经典问题:斐波那契数列、归并排序、快速排序、矩阵乘法、二分搜索、大整数乘法、汉诺塔。 15.1.2、贪心法 (一般用于求满意解) …

基于大模型的唇裂手术全流程预测与应用研究报告

目录 一、引言 1.1 研究背景与意义 1.2 研究目标与内容 二、唇裂相关医学知识概述 2.1 唇裂的定义、分类与发病原因 2.2 唇裂对患者生理与心理的影响 2.3 传统唇裂治疗方法与局限性 三、大模型技术原理与应用基础 3.1 大模型概述 3.2 适用于唇裂预测的大模型类型及特…

环境变量设置异常导致UOS文件管理器无法正常运行

编译QT5.15.2,与UOS20.9的QT依赖冲突 现象原因解决方法 现象 重启系统后UOS桌面变成黑色,没有任何图标,任务栏的应用本来是有预览的,但也变得不可用。 原因 找了很久,查到原来是dde-file-manager未能正常启动。直接…

《认知觉醒》改变的核心方法论

《认知觉醒》改变的核心方法论 一、认知觉醒的核心目标 改变 → 提升能力 → 获得更好生活 二、大脑运作机制 脑区运算速度作用特点本能脑1.1亿次/秒自动化反应,能量消耗低情绪脑1.1亿次/秒情感驱动型决策​理智脑​40次/秒战略指挥官角色 关键差异&#xff1a…

Python中的字典:深度解析与应用实践

一、字典的本质与特性 Python字典(Dictionary)是以**键值对(Key-Value Pair)**形式存储数据的无序集合,使用大括号{}定义。其核心特性包括: 快速查找:基于哈希表实现,通过键&#…

【蓝桥杯python研究生组备赛】005 数学与简单DP

题目1 01背包 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi,价值是 wi。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。 输入格式 第一行两个整数&a…

2024年国赛高教杯数学建模E题交通流量管控解题全过程文档及程序

2024年国赛高教杯数学建模 E题 交通流量管控解题 原题再现 随着城市化进程的加快、机动车的快速普及,以及人们活动范围的不断扩大,城市道路交通拥堵问题日渐严重,即使在一些非中心城市,道路交通拥堵问题也成为影响地方经济发展和…

穿越是时空之门(java)

emm,之前做过一道类似的题目,但是这次又忘了 一开始的错误代码 package Lanqiao;import javax.swing.plaf.synth.SynthTextAreaUI; import java.math.BigInteger;/*** author zb* date2025/3/19 21:33*/ public class L19701 {public static void main…

npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本的处理方法

1、安装了node.js后,windows powershell中直接输入npm,然后就报错 2、出现原因:权限不够 系统禁用了脚本的执行,所以我们在windows powershell输入npm -v的时候,就会报上面的错误。 3、解决 Set-ExecutionPolicy Un…

蓝桥杯单片机之AT24C02(基于自己对AT24C02的学习和理解)

一、先用抽象法说明原理,让原理变得简单易懂: 1、向AT24C02写入数据: 有个关系户,他想安排自己的儿子进某个大厦里某个楼层的公司,那么他就要先找到这个公司的地址,然后再找到该公司是第几楼,最…

Java面试易忽略知识点

1. CompletableFuture中thenApply()与thenCompose()的区别 考察点:组合式异步编程 解析: ​**thenApply()**:接收前序任务结果,返回普通对象(同步转换),适用简单数据处理。​**thenCompose()*…

VLLM专题(十九)—兼容 OpenAI 的服务器

vLLM 提供了一个 HTTP 服务器,能够实现 OpenAI 的 Completions API、Chat API 等功能! 您可以通过 vllm serve 命令启动服务器,或者通过 Docker 启动: vllm serve NousResearch/Meta-Llama-3-8B-Instruct --dtype auto --api-key token-abc123要调用服务器,您可以使用官…

【云原生之kubernetes实战】在k8s环境中高效部署minio对象存储(详细教程)

【云原生之kubernetes实战】在k8s环境中高效部署minio对象存储(详细教程) 前言一、minio介绍1.1 MinIO简介1.2 主要特点1.3 主要使用场景二、相关知识介绍2.1 本次实践存储介绍2.2 k8s存储介绍三、本次实践介绍3.1 本次实践简介3.2 本次环境规划3.3 部署前需准备工作四、检查…

【高项】信息系统项目管理师(八)项目质量管理【3分】

项目质最管理包括把组织的质量政策应用于规划、管理、控制项目和产品质量要求。以满足干系人目标的各个过程。项目质量管理以执行组织的名义支持过程的持续改进活动,项目质量管理需要兼顾项目管理与项目可交付成果两个方面,它适用于所有项目无论项目的可付成果具有何种特性。质…

python-leetcode 48.括号生成

题目: 数字n代表生成括号的对数,设计一个函数,用于生成所有可能并且有效的括号组合。 方法一:回溯 可以生成所有 2**2n 个 ‘(’ 和 ‘)’ 字符构成的序列,然后检查每一个是否有效即可 为了生成所有序列&#xff0c…

TDE透明加密技术:免改造实现华为云ECS中数据库和文件加密存储

在数字经济与云计算深度融合的今天,华为云ECS(弹性云服务器)已成为企业数字化转型的核心载体,承载着数据库、文件存储、AI训练等关键业务。然而,云上数据安全形势日益严峻:2024年全球云环境勒索攻击同比激增…

3D点云数据处理中的聚类算法总结

1.欧式聚类: 基于点的空间距离(欧几里得距离)来分割点云,将距离较近的点归为同一簇。 欧式聚类需要的参数:邻域半径R,簇的最小点阈值minPts,最大点数阈值maxPts。 实现效率: O(n * log n) 实现…

PCL--点云可视化

用于单个显示、多个显示的头文件<visual_.h> visual_.h #pragma once #include <iostream> #include <thread> #include <pcl/visualization/pcl_visualizer.h>using namespace std::chrono_literals;/********************************************…

火星探测发展概述2025.3.20

一.火星探测历程 1.1 探索启蒙 火星探测的启蒙阶段可追溯至20世纪60年代,标志着人类对这颗神秘行星的科学探索正式拉开帷幕。这一时期的标志性事件包括: 1960年10月至1964年11月间,苏联和美国进行了6次火星探测尝试,但均以失败告终。 1964年11月28日,美国成功发射“水手…

DAPO:一个开源的大规模大型语言模型LLM强化学习系统

推断扩展赋予了大型语言模型前所未有的推理能力,强化学习作为激发复杂推理的核心技术,清华大学联合字节提出了解耦片段与动态采样策略优化(DAPO)算法,并全面开源了一个最先进的大规模强化学习系统,该系统使用Qwen2.5-32B基础模型在AIME 2024上取得了50分的高分。还开源了…