《STM32 HAL库》CAN通信系列函数详尽解析——HAL_CAN_Init()

食用指南:本文主要内容为梳理CAN初始化函数主要运行逻辑及重点功能实现代码的详尽解析。函数源码在文末,建议在阅读源码之后观看。
CAN相关寄存器图:

主要逻辑分析:

下面分点梳理函数的主要逻辑(注意逻辑序号,后文依次为点进行分析):

  1. 首先,函数会检查传入的参数hcan是否为NULL,如果是NULL,则返回错误代码HAL_ERROR

  2. 接下来,函数会使用assert_param宏对传入的hcan结构体的各个参数进行检查,确保它们的取值范围符合要求。

  3. 如果宏USE_HAL_CAN_REGISTER_CALLBACKS的值为1并且hcan的状态为HAL_CAN_STATE_RESET,则表示使用了回调函数,并且需要将回调函数重置为默认的“legacy”函数。如果hcan->MspInitCallback为空,则将其设置为默认的初始化函数HAL_CAN_MspInit。然后调用hcanMspInitCallback函数,用于初始化底层硬件。

  4. 如果USE_HAL_CAN_REGISTER_CALLBACKS的值不为1或者hcan的状态不为HAL_CAN_STATE_RESET,则直接调用HAL_CAN_MspInit函数初始化底层硬件。

  5. 在初始化之前,首先需要将CAN控制器从睡眠模式唤醒。通过清除CAN_MCR_SLEEP位实现。

  1. 接着,获取当前的系统滴答计数器值tickstart,用于超时判断。

  2. 检查CAN控制器是否成功离开了睡眠模式。通过检查CAN_MSR_SLAK位,如果该位为0,则表示成功离开了睡眠模式。如果超时时间超过了预设的超时值CAN_TIMEOUT_VALUE,则更新错误代码并返回错误。

  3. 发送初始化请求,通过设置CAN_MCR_INRQ位实现。

  4. 获取当前的系统滴答计数器值tickstart,用于超时判断。

  5. 等待CAN控制器接受初始化请求。通过检查CAN_MSR_INAK位,如果该位为1,则表示CAN控制器已经接受了初始化请求。如果超时时间超过了预设的超时值CAN_TIMEOUT_VALUE,则更新错误代码并返回错误。

  6. 根据初始化参数设置CAN控制器的各种工作模式和配置,包括时间触发通信模式、自动总线断开管理、自动唤醒模式、自动重传、接收FIFO锁定模式和传输FIFO优先级等。

  1. 设置位时序寄存器BTR,将各个参数值写入寄存器中。

  2. 初始化错误代码和CAN状态。

  3. 返回函数执行状态HAL_OK

重点部分分析

逻辑 3

#if USE_HAL_CAN_REGISTER_CALLBACKS == 1
  if (hcan->State == HAL_CAN_STATE_RESET)
  {
    /* Reset callbacks to legacy functions */
    hcan->RxFifo0MsgPendingCallback  =  HAL_CAN_RxFifo0MsgPendingCallback;  /* Legacy weak RxFifo0MsgPendingCallback */
    hcan->RxFifo0FullCallback        =  HAL_CAN_RxFifo0FullCallback;        /* Legacy weak RxFifo0FullCallback */
    hcan->RxFifo1MsgPendingCallback  =  HAL_CAN_RxFifo1MsgPendingCallback;  /* Legacy weak RxFifo1MsgPendingCallback */
    hcan->RxFifo1FullCallback        =  HAL_CAN_RxFifo1FullCallback;        /* Legacy weak RxFifo1FullCallback */
    hcan->TxMailbox0CompleteCallback =  HAL_CAN_TxMailbox0CompleteCallback; /* Legacy weak TxMailbox0CompleteCallback */
    hcan->TxMailbox1CompleteCallback =  HAL_CAN_TxMailbox1CompleteCallback; /* Legacy weak TxMailbox1CompleteCallback */
    hcan->TxMailbox2CompleteCallback =  HAL_CAN_TxMailbox2CompleteCallback; /* Legacy weak TxMailbox2CompleteCallback */
    hcan->TxMailbox0AbortCallback    =  HAL_CAN_TxMailbox0AbortCallback;    /* Legacy weak TxMailbox0AbortCallback */
    hcan->TxMailbox1AbortCallback    =  HAL_CAN_TxMailbox1AbortCallback;    /* Legacy weak TxMailbox1AbortCallback */
    hcan->TxMailbox2AbortCallback    =  HAL_CAN_TxMailbox2AbortCallback;    /* Legacy weak TxMailbox2AbortCallback */
    hcan->SleepCallback              =  HAL_CAN_SleepCallback;              /* Legacy weak SleepCallback */
    hcan->WakeUpFromRxMsgCallback    =  HAL_CAN_WakeUpFromRxMsgCallback;    /* Legacy weak WakeUpFromRxMsgCallback */
    hcan->ErrorCallback              =  HAL_CAN_ErrorCallback;              /* Legacy weak ErrorCallback */

    if (hcan->MspInitCallback == NULL)
    {
      hcan->MspInitCallback = HAL_CAN_MspInit; /* Legacy weak MspInit */
    }

    /* Init the low level hardware: CLOCK, NVIC */
    hcan->MspInitCallback(hcan);
  }

让我们一句一句地详细分析这段代码:

#if USE_HAL_CAN_REGISTER_CALLBACKS == 1

这是一个条件编译的预处理指令,它检查宏定义USE_HAL_CAN_REGISTER_CALLBACKS是否等于1。如果等于1,则表示要使用回调函数注册功能。

if (hcan->State == HAL_CAN_STATE_RESET)
{

这是一个条件语句,它检查CAN的状态hcan->State是否等于HAL_CAN_STATE_RESET。只有当CAN处于复位状态时,才会执行接下来的代码块。

/* Reset callbacks to legacy functions */
hcan->RxFifo0MsgPendingCallback  =  HAL_CAN_RxFifo0MsgPendingCallback;  /* Legacy weak RxFifo0MsgPendingCallback */
……

这一系列的语句将CAN处理器结构体hcan中的回调函数成员设置为默认的回调函数。这些默认的回调函数被称为”Legacy weak”,表示它们是在历史版本中使用的弱定义回调函数。以第一句为例,作用是将HAL_CAN_RxFifo0MsgPendingCallback的回调函数的地址赋值给hcan->RxFifo0MsgPendingCallback,即将CAN模块的RxFIFO0消息待处理回调函数指针指向一个特定的函数。在CAN模块中,当RxFIFO0内有消息待处理时,可以通过注册一个回调函数来通知应用程序进行相应的处理。

点击《STM32 HAL库》CAN通信系列函数详尽解析——HAL_CAN_Init()——古月居可查看全文

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python提取PDF文本和图片,以及提前PDF页面中指定矩形区域的文本

前言 从PDF中提取内容能帮助我们获取文件中的信息,以便进行进一步的分析和处理。此外,在遇到类似项目时,提取出来的文本或图片也能再次利用。要在Python中通过代码提取PDF文件中的文本和图片,可以使用 Spire.PDF for Python 这个…

为什么五笔没人用了?

五笔输入法现在较少人使用的原因主要有以下几点: 学习门槛高:五笔输入法的学习难度相对较大,需要掌握所有的字根,全面了解编码的规律,并学习每个字的拆字原则,这要求用户有相当高的耐心和时间去学习和练习…

openh264 帧级码率控制原理:RcCalculatePictureQp 函数

RcCalculatePictureQp 函数 函数功能 在码控中,当eSliceType为P_SLICE时 计算 P 帧的帧级量化参数QP 值。 函数原理过程 初始化各类变量;计算帧复杂度iFrameComplexity,如果iUsageType是SCREEN_CONTENT_REAL_TIME,重复赋值帧复…

MySQL【触发器、存储过程、函数、范式】

day53 MySQL 触发器 创建触发器:(before : 前置触发器、after :后置触发器) 语法: delimiter xx 指定分隔符xxcreate trigger 触发器名 [before | after] 触发事件 on 表名 for each row 执行语句begin…

maven:中央仓库验证方式改变:401 Content access is protected by token

前几天向maven中央仓库发布版本,执行上传命令mvn release:perform时报错了: [ERROR] Failed to execute goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.13:deploy (injected-nexus-deploy) on project xxxxx: Failed to deploy artifacts: …

智慧互联,Vatee万腾平台引领新潮流

在数字化、智能化的新时代,智慧互联正成为推动社会进步的重要力量。在这一潮流中,Vatee万腾平台凭借其卓越的技术实力和创新理念,正引领着新潮流,将智慧互联的理念融入生活的方方面面。 Vatee万腾平台是一个以大数据、云计算、人工…

C#利用SignalR实现通信事例Demo

1.服务端安装SignalR的Nuget包 dotnet add package Microsoft.AspNet.SignalR --version 2.4.3 2.接下来,创建一个ChatHub类,它是SignalR通信的核心: using Microsoft.AspNetCore.SignalR;public class ChatHub : Hub {public static Dict…

聊聊 C# dynamic 类型,并分享一个将 dynamic 类型变量转为其它类型的技巧和实例

前言 dynamic 是一种有别于传统变量类型的动态类型声明,刚开始接触可能在理解上会有些困难,可以简单地把它理解为一个盲盒,你可以任意猜测盒子有什么东西,并认为这些东西真正存在而进行处理,等到真正打开时&#xff0…

文章自动生成器,在线AI写作工具

随着人工智能AI技术的发展,AI技术被应用到越来越多的场景。对于需要创作内容的同学来说,AI写作-文章内容自动生成器是一个非常好的辅助工具。AI写作工具可以提升我们的创作效率,快速的生成文章,然后在根据需求进行调整修改即可。下…

语法制导的翻译和属性文法

属性的分类 1.综合属性 重写规则(产生式)左部符号的属性是综合属性。一个结点相应文法符号的属性值通过语法分析树中它的子节点的属性之值计算(自底向上) 2.继承属性 出现在重写规则右部的符号的属性。一个结点相应文法符号的属性…

概念描述——TCP/IP模型中的两个重要分界线

TCP/IP模型中的两个重要分界线 协议的层次概念包含了两个也许不太明显的分界线,一个是协议地址分界线,区分出高层与低层寻址操作;另一个是操作系统分界线,它把系统与应用程序区分开来。 高层协议地址界限 当我们看到TCP/P软件的…

没等来百度惊艳的All in AI,却等来了国产之光的盘古大模型 5.0

6月21日,华为开发者大会(HDC 2024)在广东东莞正式开幕。盘古大模型5.0的更新,也是此次HDC2024的另一项重头戏。在过去的一年中,盘古大模型正在疯狂向各行各业渗透。 此次,华为方面展示了他们在具身智能、医…

【面向对象】复习(二)

内存对齐 class A{ static int a; } int main(){ A obj; cout<<sizeof(obj); } 在你的代码中&#xff0c;class A 包含一个静态成员变量 a。静态成员变量不属于类的任何特定实例&#xff0c;而是属于整个类。因此&#xff0c;在计算类的实例大小时&#xff0c;静态…

C语言入门系列:指针入门(超详细)

文章目录 一&#xff0c;什么是指针1&#xff0c;内存2&#xff0c;指针是什么&#xff1f; 二&#xff0c;指针的声明1&#xff0c;声明指针类型变量2&#xff0c;二级指针 三&#xff0c;指针的计算1&#xff0c;两个指针运算符1.1 *运算符1.2 & 运算符1.3 &运算符与…

状态压缩DP——AcWing 291. 蒙德里安的梦想

状态压缩DP 定义 状态压缩DP是一种利用二进制数来表示状态的动态规划算法。它通过将状态压缩成一个整数&#xff0c;从而减少状态数量&#xff0c;提高算法效率。 运用情况 状态压缩DP通常用于解决具有状态转移和最优解性质的问题&#xff0c;例如组合优化、图论、游戏等问…

python-邮票组合问题

[题目描述] 某人有四张3分的邮票和三张5分的邮票&#xff0c;用这些邮票中的一张或若干张可以得到多少种不同的邮资&#xff1f;输入格式&#xff1a; 此题无输入。输出格式&#xff1a; 输出可以得到不同邮资的数量。 样例输入 无样例输出 19数据范围&#xff1a; 对于100%的…

华为---RIP路由协议的汇总

8.3 RIP路由协议的汇总 8.3.1 原理概述 当网络中路由器的路由条目非常多时&#xff0c;可以通过路由汇总(又称路由汇聚或路由聚合)来减少路由条目数&#xff0c;加快路由收敛时间和增强网络稳定性。路由汇总的原理是&#xff0c;同一个自然网段内的不同子网的路由在向外(其他…

与Vatee万腾平台同行,共创智能未来

在科技日新月异的今天&#xff0c;智能化已成为推动社会进步的重要力量。Vatee万腾平台&#xff0c;作为这一浪潮中的佼佼者&#xff0c;正以其独特的创新力和前瞻的视野&#xff0c;引领我们迈向智能未来。与Vatee万腾平台同行&#xff0c;我们不仅能享受到科技带来的便捷与舒…

[最新教程]Claude Sonnet 3.5注册方法详细步骤分享,新手小白收藏,文末免费送已注册的Claude账号

一.Claude sonnet 3.5大模型面世 6月21日&#xff0c;被称为“OpenAI 最强竞对”的大模型公司 Anthropic 发布了 Claude 3.5 系列模型中的第一个版本——Claude 3.5 Sonnet。 Anthropic 在官方博客中表示&#xff0c;Claude 3.5 Sonnet 提高了智能化的行业标准&#xff0c;在…

传统图像特征描述及提取方法

目录 一、图像特征描述 二、图像特征的分类 2.1 图像的点、线、面特征 2.2 图像的纹理形状特征 2.3 图像颜色特征 2.4图像的统计特征 三、图像特征提取的评价 一、图像特征描述 图像特征是一幅图像区别于另一幅图像最基本的特征,是其可以作为标志性的属性。 图像特征分为…