本帖最后由 正点原子运营 于 2024-6-6 11:01 编辑
1)实验平台:正点原子 精英STM32F103开发板
2) 章节摘自【正点原子】STM32F103开发指南 V1.3
6)正点原子STM32技术交流QQ群:672399978
HAL,英文全称Hardware Abstraction Layer,即硬件抽象层。HAL库是ST公司提供的外设驱动代码的驱动库,用户只需要调用库的API函数,便可间接配置寄存器。我们要写程序控制STM32芯片,其实最终就是控制它的寄存器,使之工作在我们需要的模式下,HAL库将大部分寄存器的操作封装成了函数,我们只需要学习和掌握HAL库函数的结构和用法,就能方便地驱动STM32工作,以节省开发时间。 本章将分为如下几个小节 7.1 认识STM32 HAL 7.2 HAL库驱动包 7.3 HAL库框架结构 7.4 如何使用HAL库 7.5 HAL库使用注意事项
7.1 初识STM32 HAL库 STM32开发中常说的HAL库开发,指的是利用HAL库固件包里封装好的C语言编写的驱动文件,来实现对STM32内部和外围电器元件的控制的过程。但只有HAL库还不能直接驱动一个STM32的芯片,其它的组件已经由ARM与众多芯片硬件、软件厂商制定的通用的软件开发标准CMSIS实现了,本文只简单介绍这个标准,等大家熟悉开发后再研究这个框架。 简单地了解HAL库的发展和作用,可以方便学习者确定HAL库是否适合作为学习者自己长期开发STM32的工具,以降低开发、学习的成本。
7.1.1CMSIS标准 根据一些调查研究表明,软件开发已经被嵌入式行业公认为最主要的开发成本,为了降低这个成本,ARM与Atmel、IAR、KEIL、SEGGER和ST等诸多芯片和软件工具厂商合作,制定了一个将所有Cortex芯片厂商的产品的软件接口标准化的标准CMSIS(CortexMicrocontroller Software Interface Standard)。下面来看ARM官方提供的CMSIS规范架构,如图7.1.1.1所示: 图7.1.1.1 CorteX芯片的CMSIS分级实现 从图中可以看出这个标准分级明显,从用户程序到内核底层实现做了分层。按照这个分级,HAL库属于CMSIS-Pack中的“Peripheral HAL”层。CMSIS规定的最主要的3个部分为:核内外设访问层(由ARM负责实现)、片上外设访问层和外设访问函数(后面两个由芯片厂商负责实现)。ARM整合并提供了大量的模版,各厂商根据自己的芯片差异修改模版,这其中包括汇编文件startup_device.s、system_.h和system_.c这些与初始化和系统相关的函数。 结合STM32F1的芯片来说,其CMSIS应用程序的简单结构框图,不包括实时操作系统和中间设备等组件,其结构如图7.1.1.2所示。 图7.1.1.2 CMSIS分级下的stm32f1的文件分布 上面的框架是根据我们现在已经学习到的知识回过头来作的一个总结,这里只是作简单的介绍,告诉大家它们之间存在一定联系,关于组成这些部分的文件、文件的作用及各文件如何组合、各分层的作用和意义,我们会在今后的学习过程中慢慢学习。 7.1.2 HAL库简介 库函数的引入,大大降低了STM主控芯片开发的难度。ST公司为了方便用户开发STM32芯片开发提供了三种库函数,从时间产生顺序是:标准库、HAL库和LL库。目前ST已经逐渐暂停对部分标准库的支持,ST的库函数维护重点对角已经转移到HAL库和LL库上,下面我们分别为这三种库作一下简单的介绍。 1. 标准外设库(Standard Peripheral Libraries) 标准外设库(Standard Peripherals Library)是对STM32芯片的一个完整的封装,包括所有标准器件外设的器件驱动器,是ST最早推出的针对STM系列主控的库函数。标准库的设计的初衷是减少用户的程序编写时间,进而降低开发成本。几乎全部使用C语言实现并严格按照“StrictANSI-C”、MISRA-C 2004等多个C语言标准编写。但标准外设库仍然接近于寄存器操作,主要就是将一些基本的寄存器操作封装成了C函数。开发者仍需要关注所使用的外设是在哪个总线之上,具体寄存器的配置等底层信息。 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库的关系, 如图7.1.2.2 CubeF1的软件框架所示,可以看出它们设计为彼此独立的分支,但又同属于HAL库体系。 通过以上简介我们对目前主流的STM32开发库有了一个初步的印象。标准库和HAL库、LL库完全相互独立,HAL库更倾向于外设通用化,扩展组件中解决芯片差异操作部分;LL倾向于最简单的寄存器操作,ST在未来还将重点维护和建设HAL库,标准库已经部分停止更新。HAL库和LL库的应用将是未来的一个趋势。 7.1.3HAL库能做什么 用过标准库的朋友应该知道,使用标准库可以忽略很多芯片寄存器的细节,根据提供的接口函数快速配置和使用一个STM32芯片,使用HAL库也是如此。不论何种库,本质都是配置指定寄存器使芯片工作在我们需要的工作模式下。HAL库在设计的时候会更注重软硬件分离。HAL库的API集中关注各个外设的公共函数功能,便于定义通用性更好、更友好的API函数接口,从而具有更好的可移植性。HAL库写的代码在不同的STM32产品上移植,非常方便。 我们需要学会调用HAL库的API函数,配置对应外设按照我们的要求工作,这就是HAL库能做的事。但是无论库封装得多高级,最终还是要通过配置寄存器来实现。所以我们学习HAL库的同时,也建议同时学习外设的工作原理和寄存器的配置。只有掌握了原理,才能更好的使用HAL库,一旦发生问题也能更快速了定位和解决问题。 HAL库还可以和STM32CubeMX(图形化软件配置工具)配套一起使用,开发者可以使用该工具进行可视化配置,并且自动生成配置好的初始化代码,大大的节省开发时间。 7.2HAL库驱动包 HAL库是一系列封装好的驱动函数,本节将从下载渠道、固件包的内容分析及在实际开发中用到的几个文件的详细介绍。 7.2.1 如何获取HAL库固件包 HAL库是ST推出的STM32Cube软件生态下的一个分支。STM32Cube是ST公司提供的一套免费开发工具和STM32Cube固件包,旨在通过减少开发工作、时间和成本来简化开发人员的工作,并且覆盖整个STM32产品。它包含两个关键部分: 1、允许用户通过图形化向导来生成C语言工程的图形配置工具STM32CubeMX。可以通过CubeMX实现方便地下载各种软件或开发固件包。 2、包括由STM32Cube硬件抽象层(HAL),还有一组一致的中间件组件(RTOS、USB、FAT文件系统、图形、TCP/IP和以太网),以及一系列完整的例程组成的STM32Cube固件包。 ST提供了多种获取固件包的方法。本节只介绍从ST官方网站上直接获取固件库的方法。网页登陆:www.st.com,在打开的页面中依次选择: “Tools &Software”->“Ecosystem”->“STM32Cube”->新页面->选择“Prodcutselector”,如图7.2.1.1: 图7.2.1.1 找到STM32CubeF1的固件下载位置 在展开的页面中选择我们需要和固件,这展开“STM32CubeF1”即可看到我们需要的F1的安装包,按下图操作,在新的窗口中拉到底部,选择适合自己的下载方式,注册帐号即可获取相应的驱动包。 图7.2.1.2 下载STM32CubeF1固件包 STM32Cube固件包,我们已经给大家下载好并且放到A盘à8,STM32参考资料à1,STM32F1xx固件库,当前固件包版本是:STM32Cube_FW_F1_V1.8.3(注意这个压缩包是1.8.3,但压缩包里的文件夹命名是1.8.0,后面讲到文件夹路径时我们按ST给的1.8.0来说明)。因为现在是STM32F103的学习,所以我们准备好的固件包是F1的。大家要根据自己学习的芯片,下载对应的固件包。如果需要最新的HAL库固件,大家可按照上述方法到官网重新获取即可。 7.2.2 STM32Cube固件包分析 STM32Cube 固件包完全兼容STM32CubeMX。对于图形配置工具STM32CubeMX入门使用,由于需要STM32F1基础才能入门使用,所以我们安排在后面第十章给大家讲解。本小节,我们主要讲解STM32Cube固件包的结构。 解压缩后的STM32CubeF1固件包的目录结构,如图7.2.2.1所示。 图7.2.2.1 STM32CubeF1固件包的目录结构 下面对STM32CubeF1固件包进行简要介绍。对于Documentation文件夹,里面是一个STM32CubeF1英文说明文档,是ST官方指导如何使用HAL库。接下来我们通过几个表格依次来介绍一下STM32CubeF1中几个关键的文件夹。 (1)Drivers文件夹 Drivers文件夹包含BSP,CMSIS和STM32F1xx_HAL_Driver三个子文件夹。三个子文件夹具体说明请参考下表7.2.2.1: (2)Middlewares文件夹 该文件夹下面有ST和Third_Party 2个子文件夹。ST文件夹下面存放的是STM32相关的一些文件,包括STemWin和USB库等。Third_Party文件夹是第三方中间件,这些中间价都是非常成熟的开源解决方案。具体说明请见下表7.2.2.2: 表7.2.2.2 Middlewares文件夹介绍 (3)Projects文件夹 该文件夹存放的是ST官方的开发板的适配例程,每个文件夹对应一个ST官方的Demo板,根据型号的不同提供MDK和IAR等类型的例程。里面有很多实例,读者可以根据自己的需要来作为参考。 (4)Utilities文件夹 该文件夹是一些公用组件,也是主要为ST官方的DEMO板提供的,在我们的例程中使用得不多。有兴趣的同学可以深入研究一下,这里我们不做过多介绍。 (5)其它几个文件 文件夹中还有几个单独的文件,用于声明软件版本或者版权信息,我们使用ST的芯片已经默认得到这个软件的版权使用授权,可以简单了解一下各文件的内容,实际项目中我们一般不添加。 License.md:用于声明软件版权信息的文件。 package.xml:描述固件包版本信息的文件。 Release_Notes.html:超文本文件,用浏览器打开可知它是对固件包的补充描述和固件版本更新的记录说明。 7.2.3 CMSIS文件夹关键文件 上一节中我们对STM32cube固件包的主要目录结构做了分析。这一小节在上一小节的基础上,我们来分析一下CMSIS文件夹:由命名可知该文件夹和7.1.1小节中提到的CMSIS标准是一致的,CMSIS为软件包的内容制定了标准,包括文件目录的命名和内容构成,CMSIS版本5.7.0的规定软件包目录如表7.2.3.1所示: 表7.2.3.1 CMSIS v5.7.0的文件夹规范 知道了CMSIS规定的组件及其文件目录的大概内容后,我们再来看看ST提供的CMSIS文件夹,如上节提到的,它的位置是“STM32Cube_FW_F1_V1.8.0\Drivers\CMSIS”。打开文件夹内容如图7.2.3.1所示,可以发现它的目录结构完全按照CMSIS标准执行,仅仅是作了部分删减。 图7.2.3.1 STM32CubeF1固件包的CMSIS文件夹 CMSIS文件夹中的Device和Include这两个文件夹中的文件是我们工程中最常用到的。下面对这两个文件夹作简单的介绍: (1)Device文件夹 Device文件夹关键文件介绍如下表7.2.3.2所示: 表7.2.3.4列出的文件都是正式工程中必须的文件。固件包的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。 7.2.4 stdint.h简介 stdint.h是从c99中引进的一个标准C库的文件。在2000年3月,ANSI 采纳了 C99 标准。ANSI C被几乎所有广泛使用的编译器(如:MDK、IAR)支持。多数C代码是在ANSI C基础上写的。任何仅使用标准C并且不和硬件相关的代码,在任意平台上用遵循ANSI C标准的编译器下能编译成功。就是说这套标准不依赖硬件,独立于任何硬件,可以跨平台。 stdint.h可以在MDK安装目录下找到,如MDK5安装在C盘时,可以在路径:C:\Keil_v5\ARM\ARMCC\include找到。stdint.h的作用就是提供了类型定义,其部分类型定义代码如下: - <div align="left"><font face="Tahoma"><font size="3">/* exact-width signed integer types */</font></font></div><div align="left"><font face="Tahoma"><font size="3">typedef signed char int8_t;</font></font></div><div align="left"><font face="Tahoma"><font size="3">typedef signed short int int16_t;</font></font></div><div align="left"><font face="Tahoma"><font size="3">typedef signed int int32_t;</font></font></div><div align="left"><font face="Tahoma"><font size="3">typedef signed __INT64 int64_t;</font></font></div><div align="left"><font face="Tahoma"><font size="3"> </font></font></div><div align="left"><font face="Tahoma"><font size="3">/* exact-width unsigned integer types */</font></font></div><div align="left"><font face="Tahoma"><font size="3">typedef unsigned char uint8_t;</font></font></div><div align="left"><font face="Tahoma"><font size="3">typedef unsigned short int uint16_t;</font></font></div><div align="left"><font face="Tahoma"><font size="3">typedef unsigned int uint32_t;</font></font></div><div align="left"><font face="Tahoma"><font size="3">typedef unsigned __INT64 uint64_t;</font></font></div>
复制代码在今后的程序,我们都将会使用这些类型,比如:uint32_t(无符号整型)、int16_t等。 |