STM32 HAL库详解

2023-05-16

STM32 HAL库整体总结

STM32 之二 HAL库详解 及 手动移植

本篇博客是对以上参考资源的一个二次总结与整理。

1. HAL库文件结构

对于开发人员而言,首先要清楚 HAL 库的文件结构。

根据文件类型可认为以下两大类:

库文件:
	stm32f2xx_hal_ppp.c/.h			// 主要的外设或者模块的驱动源文件,包含了该外设的通用API
	stm32f2xx_hal_ppp_ex.c/.h		// 外围设备或模块驱动程序的扩展文件。这组文件中包含特定型号或者系列的芯片的特殊API。以及如果该特定的芯片内部有不同的实现方式,则该文件中的特殊API将覆盖_ppp中的通用API。
	stm32f2xx_hal.c/.h				// 此文件用于HAL初始化,并且包含DBGMCU、重映射和基于systick的时间延迟等相关的API
	其他库文件
用户级别文件:
	stm32f2xx_hal_msp_template.c	// 只有.c没有.h。它包含用户应用程序中使用的外设的MSP初始化和反初始化(主程序和回调函数)。使用者复制到自己目录下使用模板。
	stm32f2xx_hal_conf_template.h	// 用户级别的库配置文件模板。使用者复制到自己目录下使用
	system_stm32f2xx.c				// 此文件主要包含SystemInit()函数,该函数在刚复位及跳到main之前的启动过程中被调用。 **它不在启动时配置系统时钟(与标准库相反)**。 时钟的配置在用户文件中使用HAL API来完成。
	startup_stm32f2xx.s				// 芯片启动文件,主要包含堆栈定义,终端向量表等
	stm32f2xx_it.c/.h				// 中断服务函数的相关实现
	main.c/.h						//

与我们密切相关的有

  • 主函数: main.c/.h
  • MSP初始化: stm32f2xx_hal_msp_template.c
  • 中断服务函数: stm32f2xx_it.c/.h

2. HAL库用户代码

HAL 库对底层进行了抽象,在此结构下,用户代码处理可分为三大部分:

  • 句柄
  • MSP
  • 回调函数

关于这三点,也可参考这里进行理解,

1、关于句柄

HAL库在结构上,对每个外设抽象成了一个称为ppp_HandleTypeDef的结构体,其中ppp就是每个外设的名字。

与标准库中的结构体相比,HAL 库中的结构体包含了其可能出现的所有定义,比如用户想要使用ADC,只要定义一个ADC_HandleTypeDef的全局变量,针对不同的应用场景配置不同结构体成员就可以满足使用要求。

2、MSP
MSP(MCU Specific Package,单片机的具体方案),是指和MCU相关的初始化

初始化函数包含的内容可分为两部分:

  • 一部分是与MCU无关的,通信协议;
  • 一部分是与MCU相关的,引脚功能。

这里可以结合博主关于串口的说明USART and UART进行理解。

以串口为例,在 MX_USART1_UART_Init(void) 函数中初始化串口的波特率、停止位、奇偶校验等,这部分代码是与串口协议相关的,并未涉及到具体的引脚,因此与 MCU 是无关的,是抽象的。

static void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;  
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
    __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);

}

stm32f0xx_hal_msp.c 文件中的 HAL_UART_MspInit(UART_HandleTypeDef* huart) 函数中将串口所时用的 MCU 引脚模式进行配置,这部分是与 MCU 具体相关的。

void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
  // 关于 GPIO 引脚初始化的流程与上面介绍的“四步”相同
  GPIO_InitTypeDef GPIO_InitStruct;
  if(huart->Instance==USART2)   // USART 2
  {
  /* USER CODE BEGIN USART2_MspInit 0 */

  /* USER CODE END USART2_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_USART2_CLK_ENABLE(); // 使能串口时钟
  
    /**USART2 GPIO Configuration    
    PA2     ------> USART2_TX
    PA3     ------> USART2_RX 
    */
    GPIO_InitStruct.Pin = USART2_TX_Pin|USART2_RX_Pin;  // 收发引脚
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;  // 复用推挽输出
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF1_USART2;  // 复用功能配置
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);  // 结构体初始化

    /* USART2 DMA Init */    // DMA 方式收发初始化
    /* USART2_RX Init */
    hdma_usart2_rx.Instance = DMA1_Channel3;
    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart2_rx.Init.Mode = DMA_NORMAL;
    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }

    __HAL_DMA1_REMAP(HAL_DMA1_CH3_USART2_RX);

    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);

    /* USART2_TX Init */
    hdma_usart2_tx.Instance = DMA1_Channel4;
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart2_tx.Init.Mode = DMA_NORMAL;
    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }

    __HAL_DMA1_REMAP(HAL_DMA1_CH4_USART2_TX);

    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);

    /* USART2 interrupt Init */
    HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);
  /* USER CODE BEGIN USART2_MspInit 1 */

  /* USER CODE END USART2_MspInit 1 */
  }
}

3、回调函数
在标准库中,串口中断了以后,我们要先在中断中判断是否是接收中断,然后读出数据,顺便清除中断标志位,然后再是对数据的处理。这样如果我们在一个中断函数中写这么多代码,就会显得很混乱。

而在HAL库中,以GPIO为例,进入中断后,直接由HAL库中断函数HAL_GPIO_EXTI_IRQHandler() 进行托管。
而该函数主要完成两项任务:

  • 清除中断标志位
  • 调用回调函数处理中断
// EXIT 外部中断服务函数
void EXTI0_1_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
}


// HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10)函数如下
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET) 
  { 
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
}

在回调函数内对中断进行处理,这种方式增强了代码的逻辑性,但也增加了文件的嵌套程度。

3. HAL库编程方式

在 HAL 库中对外设模型进行了统一,支持三种编程方式:

  • 轮询模式/阻塞模式
  • 中断方式
  • DMA模式

以IIC为例,三种编程模式对应的函数如下:

1、轮询模式/阻塞模式

HAL_I2C_Master_Transmit()HAL_I2C_Master_Receive()HAL_I2C_Slave_Transmit()HAL_I2C_Slave_Receive()
HAL_I2C_Mem_Write()HAL_I2C_Mem_Read()HAL_I2C_IsDeviceReady()

2、中断模式

HAL_I2C_Master_Transmit_IT()HAL_I2C_Master_Receive_IT()HAL_I2C_Slave_Transmit_IT()
HAL_I2C_Slave_Receive_IT()HAL_I2C_Mem_Write_IT()HAL_I2C_Mem_Read_IT()

3、DMA模式

HAL_I2C_Master_Transmit_DMA()HAL_I2C_Master_Receive_DMA()HAL_I2C_Slave_Transmit_DMA()HAL_I2C_Slave_Receive_DMA()HAL_I2C_Mem_Write_DMA()HAL_I2C_Mem_Read_DMA()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 HAL库详解 的相关文章

  • SQL Server访问远程数据库--使用openrowset/opendatasource的方法

    一 使用openrowset opendatasource前首先要启用Ad Hoc Distributed Queries xff0c 因为这个服务不安全SqlServer默认是关闭的 SQL Server 阻止了对组件 39 Ad Hoc
  • 我的2014碎碎念—学习篇、实习篇、工作篇、生活篇

    继去年作了一次年度总结过后 xff0c 我就发誓说以后每年年末都要做一次总结 xff0c 这对自己是非常有帮助的 xff0c 无奈由于天性懒散 xff0c 2015年都过去好几天了 xff0c 才花了点心思整理下自己在过去一年里的所得所失
  • 百度2014研发类校园招聘笔试题解答

    先总体说下题型 xff0c 共有3道简答题 xff0c 3道算法编程题和1道系统设计题 xff0c 题目有难有易 xff0c 限时两小时完成 一 简答题 动态链接库和静态链接库的优缺点轮询任务调度和可抢占式调度有什么区别 xff1f 列出数
  • CSDN-markdown语法之如何插入图片

    目录 图片上传方式 插入在线图片插入本地图片图片链接方式 行内式图片链接参考式图片链接几个问题探讨 问题1 xff1a 图片上传和图片链接两种方式的区别 问题2 xff1a Markdown中如何指定图片的高和宽 xff1f 问题3 xff
  • 京东2013校园招聘软件研发笔试题

    时间 xff1a 2012 9 11 地点 xff1a 川大 我只能说第一家公司 xff0c 不是一般的火爆 不得不吐槽一下 xff1a 京东宣讲完全没有计划 xff0c 只看到个下午两点半宣讲 xff0c 结果跑过去 xff0c 下午两点
  • C运行时库函数和API函数区别

    C运行时库函数 是指 C语言本身支持的一些基本函数 xff0c 通常是汇编直接实现的 API函数是操作系统提供给用户方便设计应用程序的函数 xff0c 实现一些特定的功能 xff0c API函数也是C语言的函数实现的 他们之间区别是 xff
  • Docker常用命令详解

    docker命令大全 命令说明docker attach将本地标准输入 输出和错误流附加到正在运行的容器docker build从 Dockerfile 构建镜像docker builder管理构建docker checkpoint管理检查
  • PIX飞控中POS数据读取方法(实用工具)

    前些日子用到PIX飞控 xff0c 后来急用生成的日志需要导出里面的POS数据 xff0c 结果发现比较麻烦 xff0c 网上教程倒是很多 xff0c 对于不同版本的地面站情况又不一样 xff0c 当时就那样导出来简单用了用 xff0c 今
  • 在不丢失堆栈跟踪的情况下重新抛出Java中的异常

    在C xff03 中 xff0c 我可以使用throw 保留堆栈跟踪时重新抛出异常的语句 xff1a try catch a href http www javaxxz com thread 368216 1 1 html Exceptio
  • JPG图像exif和XPM信息中GPS数据姿态数据航向角数据的提取

    JPG图像的编码相关内容太多不在多说了大家随手能查很多资料 今天重点说说图像数据中的GPS信息以及飞机 相机姿态角度数据提取 JPG作为复杂的图像数据很多人都知道存在一个叫做EXIF的数据规范 xff0c 在这个数据规范中 xff0c 包含
  • 在STM32上对EV1527等无线编码格式的C程序编码实现

    测调 西安 老雷子 2020年6月1日 软件平台 WINDOWS Keil uVision STM32 ST LINK 硬件平台 STM32S108C8B6 通用32开发板调试 发射端 xff1a 蜂鸟远T1 输入需要用MCU进行编码 xf
  • 机器人手眼标定快速精度验证方法

    一 原理及流程 机器人的手眼标定原理在本文中不再过多描述 xff0c 基本流程都是先标定相机的内外参数 xff0c 然后标定两台相机之间的位置关系 xff0c 如果相机是可以转动的话 xff0c 还要标定转台与机械臂之间的关系 在手眼标定完
  • 【转载】写给电子信息工程专业的毕业生(一)

    一 继续深造 VS 找工作 在就业竞争异常激烈的今天 xff0c 也许大家大三起就开始忧心自己毕业后该何去何从了 摆在大家面前最为清晰的 xff0c 是两条路 xff1a 继续深造 xff08 考研 留学 xff09 和找工作 现在研究生扩
  • 通过python的百度云客户端可以把linux数据备份到百度云

    引言 网站备份真的很重要 xff0c 前段时间已经被坑过一次了 xff0c 幸好数据没有完全丢 xff0c 勉强恢复了 xff0c 虽然丢失了几篇文章 之前一直是每隔几天手动备份一下重要的数据 xff0c 然后下载到本地 但是有时候会忘记备
  • XCOM2.0接收数据为0

    新装系统后 xff0c 串口助手Xcom2 0版本 xff0c 使用FT232接受到的数据全是0 xff0c FT232已经有驱动 xff0c 经过多出测试 xff0c 需要更新FTDI的官网驱动 xff0c 并重启 xff0c 问题解决
  • PyQt(Python+Qt)学习随笔:Action功能详解及Designer中的操作方法

    老猿Python博文目录老猿Python博客地址 一 引言 Qt Designer中的部件栏并没Action相关的部件 xff0c Action可以在右侧的Action Editor中编辑 xff0c 如图 xff1a 如果没有出现Acti
  • 鸿蒙最新功能及承载设备详解:HarmonyOS 2及华为全场景新品发布会全纪录

    6月2日 xff0c 华为联手CSDN直播了 HarmonyOS 2及华为全场景新品发布会 xff0c 老猿全程观看直播 xff0c 并进行了回看 xff0c 力争将发布会的核心内容在本文中概要性地呈现 一 一生万物 万物归一 首先是华为消
  • 构建VisualStudio2019+OpenCV4.3的C++ windows编译环境

    一 引言 最近在读源代码研究CLAHE的算法 xff0c 但好久没学习C 43 43 了 xff0c 发现部分代码难以理解 xff0c 因此最后下决心装一个C 43 43 编译器 下载OpenCV源码 xff0c 这样碰到疑难问题就可以实际
  • 关于C++集合操作赋值和集合间操作的结果集合的疑问

    一 关于集合的疑问 最近对C 43 43 语言的集合操作比较感兴趣 xff0c 看了好友博主CP猫介绍的 C 43 43 中集合set的常用操作 xff0c 在使用时有3个疑问 xff1a 集合的变量赋值能否直接将一个集合实例赋值个另一个集
  • 如何使用Docker暴露多个端口?

    本文翻译自 xff1a How can I expose more than 1 port with Docker So I have 3 ports that should be exposed to the machine 39 s i

随机推荐

  • 人工智能基础概念1:模型、拟合、最大似然估计、似然函数、线性回归、sigmoid函数、逻辑回归

    一 模型 拟合 xff08 fitting xff09 和过拟合 xff08 overfitting xff09 人工智能中的模型 xff08 Artificial Intelligence Model xff09 指的是一些算法和数学模型
  • 中国移动提出的ABCDNETS和DSSN数联网技术介绍

    一 引言 在2023年4月14日 xff0c 中国移动召开 数据要素流通与治理产业高峰论坛上 xff0c 中国移动发布了 数联网 xff08 DSSN xff09 白皮书 xff0c 同时发布了全球首创的数联网 DSSN 服务平台等产品 x
  • Python循环语句(while循环、for循环)

    Python循环语句 一 while循环二 for语句三 range 函数四 break 和 continue 语句五 pass语句 Python循环语句主要有while循环和for循环 xff0c Python 循环语句的控制结构图如下所
  • 深度学习笔记一:深度学习环境的搭建

    首先需要下载anaconda xff08 官方网站下载 xff09 一路选择next即可 这里我没有选择添加环境变量 xff0c 如果有需要 xff0c 后期可以手动添加 xff0c 这里可以根据自己情况选择 安装完成后 xff0c 从wi
  • HAN论文模型代码复现与重构

    论文简介 本文主要介绍CMU在2016年发表在ACL的一篇论文 xff1a Hierarchical Attention Networks for Document Classification及其代码复现 该论文是用于文档级情感分类 xf
  • Http Digest认证协议

    http blog csdn net htjoy1202 article details 7067287 其认证的基本框架为挑战认证的结构 xff0c 如下图所示 xff1a xfeff xfeff 1 客户端希望取到服务器上的某个资源 x
  • 【系统分析师之路】嵌入式系统章节错题集锦

    系统分析师之路 嵌入式系统章节错题集锦 系分章节错题集第01题 xff1a 红色 01 雷达设计人员在设计数字信号处理单元时 xff0c 其处理器普遍采用DSP芯片 xff08 比如 xff1a TI公司的TMS320C63xx xff09
  • 【软工】程序编码

    目录 前言正文 程序设计语言 分类 选择原则 程序编码总原则 好程序的标准 结构化程序设计 主要内容 主要原则 程序设计风格 源程序文档化 数据说明 语句结构 输入输出方法 程序设计质量评价 正确性结构清晰性易修改性 易读性 简单性 程序复
  • TPM1.2到TPM 2.0的变化

    原文地址 xff1a http www vonwei com mod 61 pad amp act 61 view amp id 61 11 TPM 1 2规范主要面向PC平台 xff0c 其103版本在2009年被接受为ISO标准 xff
  • 关于Cmake与CmakeLists(一)--背景,须知,示例

    一 背景及须知 1 背景 xff1a VS2019与VS2010在编写程序时都是创建了一个工程 xff0c 然后直接打开 sln即可 但是vscode仅仅是一个编辑器 xff0c 打开之后只有 c或者 cpp文件 xff0c 故需要手动编译
  • webgl(three.js)实现室内定位,楼宇bim、实时定位三维可视化解决方案——第五课

    webgl three js 实现室内定位 楼宇bim 实时定位三维可视化解决方案 第五课 参考文章 xff1a xff08 1 xff09 webgl three js 实现室内定位 楼宇bim 实时定位三维可视化解决方案 第五课 xff
  • Linux虚拟机在线扩容lvm类型root分区

    目录 Linux虚拟机在线扩容lvm类型root分区写在前面正文写在后面 Linux虚拟机在线扩容lvm类型root分区 写在前面 这是我在CSDN上的第一篇文章 作为一个半江湖的IT人 xff0c 这些年来也在CSDN受益很多 今天是20
  • 无vCenter创建vSAN集群

    无vCenter创建vSAN集群 最近仍有朋友在问题 xff0c vCenter如果 挂了 xff0c vSAN还能正常运行吗 xff1f 这个小文通过手动创建vSAN集群的方式来解答下这个问题吧 xff08 生产环境慎用 xff01 xf
  • 记一次mdadm软raid1升级容量

    MDRaid 2块4TB做了软RAID1 xff0c 需要升级成2块8TB盘 查看磁盘信息 xff0c SerialNumber等会儿会用到 xff0c 防止换错盘 span class token function sudo span h
  • [简洁版]youtube-dl下载命令

    简介 YouTube dl是python上的pip模块 xff08 开源 xff09 xff0c 可以用来下载YouTube Bilibili等多个平台的视频 音频文件 xff0c 可谓是居家旅行必备小工具 本文主要介绍一些常用的youtu
  • [简版]VMware强大的管理工具-PowerCLI

    一 PowerCLI介绍 什么是 PowerCLI PowerCLI 是一个命令行工具 xff0c 可以用于自动化vSphere管理 xff0c 包括网络 存储 虚拟机以及其他很多功能 PowerCLI包含超过700个命令 要安装Power
  • [简版]使用PowerCLI自定义vSphere ISO安装镜像

    一 什么情况下要自定义ISO镜像 一般来说 xff0c 对于DELL Lenovo HPE这类主流的服务器厂商 xff0c VMware官方vSphere ISO镜像或者官网的第三方客制镜像 xff08 由服务器厂商提供的封装镜像 xff0
  • [简版] 关于vSphere漏洞-OpenSLP

    一 前言 近期vSphere OpenSLP漏洞在野利用的新闻频频被爆出来 xff0c 大伙儿非常关注 由于vSphere虚拟化客户之广泛 xff0c 很多朋友都表达了自己的焦虑 xff0c 同时也会担心自己管理的vSphere虚拟化平台是
  • [简版] Linux搭建SAMBA文件共享服务

    SMB服务搭建 更多参数含义参考链接 常用配置 安装samba span class token comment Ubuntu span span class token function sudo span span class toke
  • STM32 HAL库详解

    STM32 HAL库整体总结 STM32 之二 HAL库详解 及 手动移植 本篇博客是对以上参考资源的一个二次总结与整理 1 HAL库文件结构 对于开发人员而言 xff0c 首先要清楚 HAL 库的文件结构 根据文件类型可认为以下两大类 x