初始HAL库

引言

 初HAL库简介识 STM32 HAL 库 STM32 开发中常说的 HAL 库开发,指的是利用 HAL 库固件包里面封装好的 C 语言编写 的驱动文件,来实现对 STM32 内部和外部电器元件的控制过程。但只有 HAL 库还不能直接驱 动一个 STM32 的芯片,其他的组件已经由 ARM 与众多芯片硬件、软件厂商指定的通用的软 件开发标准 CMSIS 实现了,本章只简单介绍这个标准.

CMSIS标准

根据一些调查研究表明,软件开发已经被嵌入式行业公认为最主要的开发成本,为了降低 这个成本,ARM 与 Atmel、IAR、KEIL、SEGGER 和 ST 等诸多芯片和软件工具厂商合作,制 定了一个将所有 Cortex 芯片厂商的商品的软件接口标准 CMSIS(Cortex Microcontroller Software Interface Standard)

从图中可以看出这个标准分级明显,从用户程序到内核底层实现做了分层处理。按照这个 分级,HAL 库属于 CMSIS-Pack 中的“Peripheral HAL”层。CMSIS 规定的最主要的 3 个部分 为:核内外设访问层(由 ARM 负责实现),片上外设访问层和外设访问函数(后面两个由芯 片厂商负责实现)。ARM 整合并提供了大量的模板,各厂商根据自己的芯片差异修改模板,这 其中包括汇编文件 startup_device.s、system_.h 和 system_.c 这些与初始化和系统相关的函数。

此处目前只作了解

初始HAL库

库函数的引入,大大降低了 ST 主控芯片开发的难度。ST 公司为了方便用户开发 STM32 芯片开发提供了三种库函数,从时间产生顺序是:标准库、HAL 库和 LL 库。目前 ST 已经逐 渐暂停对部分标准库的支持,ST 的库函数维护重点对角已经转移到 HAL 库和 LL 库上,下面 我们分别为这三种库作一下简单的介绍。

1. 标准外设库(Standard Peripheral Libraries)

标准外设库(Standard Peripherals Library)是对 STM32 芯片的一个完整的封装,包括所有标准器件外设的器件驱动器,是 ST 最早推出的针对 STM 系列主控的库函数。标准库的设计的初衷是减少用户的程序编写时间,进而降低开发成本。几乎全部使用 C 语言实现并严格 按照 Strict ANSI-C、 MISRA-C 2004 等多个 C 语言标准编写。但标准外设库仍然接近于寄存器操作,主要就是将一些基本的寄存器操作封装成了 C 函数。开发者仍需要关注所使用的外设 是在哪个总线之上,具体寄存器的配置等底层信息。下面看一下 ST 的标准库函数家族,如图所示:

ST 为各系列提供的标准外设库稍微有些区别。例如,STM32F1x 的库和 STM32F3x 的库 在文件结构上就有些不同,此外,在内部的实现上也稍微有些区别,这个在具体使用(移植) 时,需要注意一下!但是,不同系列之间的差别并不是很大,而且在设计上是相同的。 STM32 的标准外设库涵盖以下 3 个抽象级别:

•包含位,位域和寄存器在内的完整的寄存器地址映射

•涵盖所有外围功能(具有公共 API 的驱动器)的例程和数据结构的集合。

•一组包含所有可用外设的示例,其中包含最常用的开发工具的模板项目。 关于更详细的信息,可以参考 ST 的官方文档《STM32 固件库使用手册中文翻译版》,文 档中对于标准外设库函数命名、文件结构等都有详细的说明,这里我们就不多介绍了。 值得一提的是由于 STM32 的产品性能及标准库代码的规范和易读性以及例程的全覆盖性, 使 STM32 的开发难度大大下降。但 ST 从 L1 以后的芯片 L0、L4 和 F7 等系列就没有再推出相 应的标准库支持包了。此处仅作了解

2. HAL 库

HAL(Hardware Abstraction Layer)即硬件抽象层是 ST 为可以更好的确保跨 STM32 产品的最大可移植性而推出的 MCU 操作库。这种程序设计由于抽离应用程序和硬件底 层的操作,更加符合跨平台和多人协作开发的需要。

HAL 库是基于一个非限制性的 BSD 许可协议(Berkeley Software Distribution)而发布的 开源代码。 ST 制作的中间件堆栈(USB 主机和设备库,STemWin)带有允许轻松重用的许可 模式, 只要是在 ST 公司的 MCU 芯片上使用,库中的中间件(USB 主机/设备库,STemWin)协 议栈即被允许修改,并可以反复使用。至于基于其它著名的开源解决方案商的中间件 (FreeRTOS,FatFs,LwIP 和 PolarSSL)也都具有友好的用户许可条款。

HAL 库是从 ST 公司从自身芯片的整个生产生态出发,为了方便维护而作的一次整合,以 改变标准外设库带来各系列芯片操作函数结构差异大、分化大、不利于跨系列移植的情况。相 比标准外设库,STM32Cube HAL 库表现出更高的抽象整合水平,HAL 库的 API 集中关注各外 设的公共函数功能,这样便于定义一套通用的用户友好的 API 函数接口,从而可以轻松实现 从一个 STM32 产品移植到另一个不同的 STM32 系列产品。但由于封闭函数为了适应最大的兼 容性,HAL 库的一些代码实际上的执行效率要远低于寄存器操作。但即便如此,HAL 库仍是 ST 未来主推的库。

3. LL 库

LL 库(Low Layer)目前与 HAL 库捆绑发布,它设计为比 HAL 库更接近于硬件底层的操 作,代码更轻量级,代码执行效率更高的库函数组件,可以完全独立于 HAL 库来使用,但 LL 库不匹配复杂的外设,如 USB 等。所以 LL 库并不是每个外设都有对应的完整驱动配置程序。 使用 LL 库需要对芯片的功能有一定的认知和了解,它可以:

•独立使用,该库完全独立实现,可以完全抛开 HAL 库,只用 LL 库编程完成。

•混合使用,和 HAL 库结合使用。 对于 HAL 库和 LL 库的关系, 如图 CubeF1 的软件框架所示,可以看出它们设计为 彼此独立的分支,但又同属于 HAL 库体系。

通过以上简介我们对目前主流的 STM32 开发库有了一个初步的印象。标准库和 HAL 库、 LL 库完全相互独立,HAL 库更倾向于外设通用化,扩展组件中解决芯片差异操作部分;LL 倾向于最简单的寄存器操作,ST 在未来还将重点维护和建设 HAL 库,标准库已经部分停止更 新。HAL 库和 LL 库的应用将是未来的一个趋势。

HAL 库能做什么

用过标准库的朋友应该知道,使用标准库可以忽略很多芯片寄存器的细节,根据提供的接 口函数快速配置和使用一个 STM32 芯片,使用 HAL 库也是如此。不论何种库,本质都是配置 指定寄存器使芯片工作在我们需要的工作模式下。HAL 库在设计的时候会更注重软硬件分离。 HAL 库的 API 集中关注各个外设的公共函数功能,便于定义通用性更好、更友好的 API 函数 接口,从而具有更好的可移植性。HAL 库写的代码在不同的 STM32 产品上移植,非常方便。

我们需要学会调用 HAL 库的 API 函数,配置对应外设按照我们的要求工作,这就是 HAL 库能做的事。但是无论库封装得多高级,最终还是要通过配置寄存器来实现。所以我们学习 HAL 库的同时,也建议同时学习外设的工作原理和寄存器的配置。只有掌握了原理,才能更 好的使用 HAL 库,一旦发生问题也能更快速了定位和解决问题。

HAL 库还可以和 STM32CubeMX(图形化软件配置工具)配套一起使用,开发者可以使 用该工具进行可视化配置,并且自动生成配置好的初始化代码,大大的节省开发时间

stm32cube固件包浅析

解压后的 STM32CubeF1 固件包的目录结构,如图 所示。

Documentation

Documentation:里面是一个 STM32CubeF1 英文说明文档,是 ST 官方指导如何使用 HAL 库。

Drivers 文件夹

Drivers:Drivers 文件夹包含 BSP,CMSIS 和 STM32F1xx_HAL_Driver 三个子文件夹。三个子文件 夹具体说明请参考下表

Middlewares 文件夹

Middlewares :该文件夹下面有 ST 和 Third_Party 2 个子文件夹。ST 文件夹下面存放的是 STM32 相关的 一些文件,包括 STemWin 和 USB 库等。Third_Party 文件夹是第三方中间件,这些中间件都是 非常成熟的开源解决方案。具体说明请见下表所示:

Projects 文件夹

project:该文件夹存放的是一些可以直接编译的实例工程。每个文件夹对应一个 ST 官方的 Demo 板。根据型号的不同提供 MDK 和 IAR 等类型的例程。里面有很多实例,读者可以根据自己的 需要来作为参考。

Utilities 文件夹

该文件夹是一些公用组件,也是主要为 ST 官方 DEMO 板提供的,在我们的例程中使用得 不多。

其他几个文件

文件夹中还有几个单独的文件,用于声明软件版本或者版权信息,我们使用 ST 的芯片已 经默认得到这个软件的版权使用授权,可以简单了解一下各文件的内容,实际项目中我们一般 不添加。 License.md:用于声明软件版权信息的文件。 package.xml:描述固件包版本信息的文件。 Release_Notes.html:超文本文件,用浏览器打开可知它是对固件包的补充描述和固件版本 更新的记录说明。

CMSIS文件夹关键文件

CMSIS 版本 5.7.0 的规定软件包目录如表所示:

知道了 CMSIS 规定的组件及其文件目录的大概内容后,我们再来看看 ST 提供的 CMSIS 文件夹,如上节提到的,它的位置是“STM32Cube_FW_F1_V1.8.0\Drivers\CMSIS”。打开文件 夹内容如图所示,可以发现它的目录结构完全按照 CMSIS 标准执行,仅仅是作了部分删减。

CMSIS 文件夹中的 Device Include 这两个文件夹中的文件是我们工程中最常用到的。下 面对这两个文件夹作简单的介绍。

表中列出的文件都是正式工程中必须的文件。固件包的 CMSIS 文件包括了所有 STM32F1 芯片型号的文件,而我们只用到 STM32F103 系列,所以只是挑我们用到的文件来讲。

(2)Include 文件夹

Include 文件夹存放了符合 CMSIS 标准的 Cortex-M 内核头文件。 想要深入学习内核的朋 友可以配合内核相关的手册去学习。对于 STM32F1 的工程,我们只要把我们需要的添加到工 程 即 可 , 需 要 的 头 文 件 有 : cmsis_armcc.h 、 cmsis_armclang.h 、 cmsis_compiler.h 、 cmsis_version.h、core_cm3.h 和 mpu_armv7.h。这几个头文件,对比起来,我们会比较多接触 的是 core_cm3.h。 core_cm3.h 是内核底层的文件,由 ARM 公司提供,包含一些 AMR 内核指令,如软件复 位,开关中断等功能。今后在需要的例程再去讲解其程序,现在要提到的是它包含了一个重要 的头文件 stdint.h。

stdint.h 简介

stdint.h 是从 c99 中引进的一个标准 C 库的文件。在 2000 年 3 月,ANSI 采纳了 C99 标准。 ANSI C 被几乎所有广泛使用的编译器(如:MDK、IAR)支持。多数 C 代码是在 ANSI C 基 础上写的。任何仅仅使用标准 C 并且没有和任何硬件有依赖的代码实际上能保证在任何平台 84 STM32F103 开发指南 正点原子 MiniSTM32F103 开发板教程 上用遵循 C 标准的编译器编译成功。就是说这套标准不依赖硬件,独立于任何硬件,可以跨 平台。 stdint.h 可以在 MDK 安装目录下找到,如 MDK5 安装在 D 盘时,可以在路径: D:\MDK5.36\ARM\ARMCC\include 找到。stdint.h 的作用就是提供了类型定义,其部分类型定 义代码如下:

HAL的框架结构

HAL 库头文件和源文件在 STM32Cube 固件包的 STM32F1xx_HAL_Driver 文件夹中,打
开该文件夹,如图所示。

STM32F1xx_HAL_Driver 文件夹下的 Src(Source 的简写)文件夹存放是所有外设的驱动 程序源码,Inc(Include 的简写)文件夹存放的是对应源码的头文件。Release_Notes.html 是 HAL 库的版本更新信息。最后三个是库的用户手册,这个需要可以去熟悉一下,查阅起来很 方便。

HAL库文件介绍

HAL 库关键文件介绍如下表所示,表中 ppp 代表任意外设。

以上是 HAL 库最常见的文件的列表,在 Src/Inc 下面还有 Legacy 文件夹,用于特殊外设 的补充说明。使用较少不做说明

不止文件命名有一定规则,stm32f1xx_hal_ppp (c/h)中的函数和变量命名也严格按照命名 规则,如表所示的命名规则在大部分情况下都是正确的:

对于 HAL 的 API 函数,常见的有以下几种:

初始化/反初始化函数:HAL_PPP_Init(),HAL_PPP_DeInit()

外设读写函数:HAL_PPP_Read(),HAL_PPP_Write(),HAL_PPP_Transmit(), HAL_PPP_Receive()

控制函数:HAL_PPP_Set (),HAL_PPP_Get ()

状态和错误:HAL_PPP_GetState (),HAL_PPP_GetError ()

HAL 库封装的很多函数都是通过定义好的结构体将参数一次性传给所需函数,参数也有 一定的规律,主要有以下三种:

• 配置和初始化用的结构体 一般为 PPP_InitTypeDef 或 PPP_ ConfTypeDef 的结构体类型,根据外设的寄存器设计成易 于理解和记忆的结构体成员。

• 特殊处理的结构体 专为不同外设而设置的,带有“Process”的字样,实现一些特异化的中间处理操作等。

• 外设句柄结构体 HAL 驱动的重要参数,可以同时定义多个句柄结构以支持多外设多模式。HAL 驱动的操 作结果也可以通过这个句柄获得。有些 HAL 驱动的头文件中还定义了一些跟这个句柄相关的 一些外设操作。如用外设结构体句柄与 HAL 定义的一些宏操作配合,即可实现一些常用的寄 存器位操作。比较常见的 HAL 库寄存器操作如表所示:

但是对于 SYSTICK/NVIC/RCC/FLASH/GPIO 这些内核外设或共享资源来说,不需要使用 到 PPP_HandleTypedef 这类外设句柄进行控制,如:HAL_GPIO_Init()只需要初始化的 GPIO 编 号和具体的初始化参数。

HAL库回调函数

最后要分享的是 HAL 库的回调函数,如表 7.3.2.4 所示。这部分允许用户重定义,并在其 中实现用户自定义的功能,也是我们使用 HAL 库的最常用的接口之一:

至此,我们大概对 HAL 库驱动文件的一些通用格式和命名规则有了初步印象,记住这些 规则可以帮助我们快速对 HAL 库的驱动进行归类和判定这些驱动函数的用法。 ST 官方给我们提供了快速查找 API 函数的帮助文档。在路径: “STM32Cube_FW_F1_V1.8.3\Drivers\STM32F1xx_HAL_Driver”下有几个 chm 格式的文档, 根据我们开发板主控芯片 STMF103RC 我们没有找到直接可用的,但可以查看型号接近的: STM32F103xG_User_Manual.chm(因为 G 系列比 C 系列引脚功能更多,只是查看 API 函数不响 应使用的)。双击打开后,可以看到左边目录下有四个主题,我们来查看 Modules。以外设 GPIO 为例,讲一下怎么使用这个文档。点击 GPIO 外设的主题下的 IO operation functions / functions 看看里面的 API 函数接口描述,如图所示。

这个文档提供的信息很全,不看源码都可以直接使用它来编写代码,还给我们指示源码位 置,非常方便。大家多翻一下其他主题了解一下文档的信息结构,很容易使用。 下面举个例子,比如我们要让 PB4 输出高电平。先看函数功能,HAL_GPIO_WritePin 函 数就是我们的 GPIO 口输出设置函数

函数有三个形参:

第一个形参是 GPIO_TypeDef *GPIOx,形参描述说:x 可以是 A 到 G 之间任何一个,而 我们是 PB4 引脚,所以第一个形参确认是 GPIOB。

第二个形参是 uint16_t GPIO_Pin,看形参描述:该参数可以是 GPIO_PIN_x,x 可以 1 到 15,那么我们第二个形参就是 GPIO_PIN_4。

第三个形参是 GPIO_PinState PinState,看形参描述:该参数可以是枚举里的两个数,一个是 GPIO_PIN_RESET:表示该位清零,另一个是 GPIO_PIN_SET:表示设置该位,即置 1,我 们要输出 1,所以要置 1 该位,那么我们第三个形参就是 GPIO_PIN_SET。

最后看函数返回值:None,没有返回值。

所以最后得出我们要调用的函数是:

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);

帮助文档的使用就讲到这。 本节只针对 HAL 库作了一个简单的介绍,想要了解更多知识,ST 提供了关于 HAL 库 LL 库的更详细的说明文档,我们已经把它放到光盘资料 A 盘《8,STM32 参考资料》中了,大家 可以自行查阅《Description of STM32F1 HAL and low-layer drivers.pdf》获取所需知识。

HAL库使用注意事项

1,使用HAL库出现问题,还是得通过参考手册检查是否硬件操作是否有问题
2,尽量不通过修改库源码实现功能,这样不方便库更新
3,HAL库可能会存在错误,要有质疑精神
4,有些HAL库API函数执行效率偏低,我们可能会直接通过操作寄存器的方式代替

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值