【08】STM32·HAL库开发-HAL库介绍 | STM32Cube固件库介绍 | HAL库框架结构 | 如何使用HAL库及使用注意事项

1.初识HAL库(了解)

1.1CMSIS简介

  CMSIS (微控制器软件接口标准):Cortex Microcontroller Software Interface Standard,是由ARM和与其合作的芯片厂商(比如ST、NXP公司等)、软件工具厂商(Keil、IAR公司等),共同制定的标准。如果没有此标准,ARM公司的产品兼容性非常差。
  下图中分为三层,第一层是用户层,主要是用户代码、在线调试;第二层是中间层(CMISIS),具体CMSIS体现到用户手册是CMSIS-Pack,每个公司提供的包可能不太一样,会根据自己的产品制作CMSIS包,其中HAL库(Peripheral HAL)属于其内容;第三层是硬件层。用户想要去开发硬件层,需要经过中间层,中间层的CMSIS包由众多厂商提供。
在这里插入图片描述

1.2HAL库简介

  ST 为了方便用户开发 STM32芯片开发提供了三种库:

  1. 标准外设库 (Standard Peripheral Libraries),也就是“标准库”。
  2. HAL库(硬件抽象层):Hardware Abstraction Layer
  3. LL库:Low Layer,也就是“底层库”,更加接近硬件,也就是更加接近寄存器。

  下图是直接操作寄存器、标准库、HAL库(不同系列兼容性好,具体表现是不同外设初始化都是使用一个函数,只是结构体、变量不一样,但是函数接口一样,移植方便。HAL库是抽象层的库,经过很多次的封装,导致效率比较低)、LL库(弥补了HAL库执行效率低的缺点,在HAL库内部一些API函数就会调用LL库中内容,但是LL库也有其缺点,不匹配部分复杂外设,比如USB)的特点:
在这里插入图片描述

2.STM32Cube固件包浅析(了解)

  Cube固件包其实就说CMSIS-Pack,STM32Cube固件包是ST公司根据标准提供的CMSIS-Pack。

2.1如何获取STM32Cube固件包?

  之前文章中已经总结如何获取,具体查看【07】STM32·HAL库开发-新建寄存器版本MDK工程 |下载STM32Cube固件包 | 新建MDK工程步骤中的第1.1小节。

2.2STM32Cube固件包文件夹简介

【_htmresc】文件夹中包含了一些图片之类的,对我们来说没任何作用;
【Documentation】文件夹中为固件包说明文档;
【Drivers】文件夹比较重要是驱动源码,新建工程时需要用到
【Middlewares】中为中间文件,保存的是ST或者第三方的一些中间文件,后续会用到,新建工程可能暂时用不到;
【Projects】为ST官方开发板例程,参考作用;
【Utilities】为ST关方开发板例程提供公共组件,一般用不到,可以用作参考;
License.md文件包含了软件许可、软件版本信息;
package.xml为固件包版本信息;
Readme.md为自述文件;
Release_Notes.html为补充或更新说明的链接,可用浏览器打开。

在这里插入图片描述

2.3CMSIS文件夹关键文件

  F1系列【Drivers】文件夹中包含了三个文件夹【BSP】、【CMSIS】、HAL库驱动【STM32F1xx_HAL_Driver】。【BSP】中为板级驱动源码,也就是板级支持包,适配ST官方的开发板板级驱动(针对外设、或者板子上面的资源做的驱动),不同开发板板级驱动是不一样的,所以此文件更多是参考意义;【CMSIS】文件夹包含符合CMSIS的组件,包括:DSP库、Cortex-M内核及其设备文件、微控制器专用头文件、启动文件、专用系统文件等,创建工程时会复制其中部分文件;【STM32F1xx_HAL_Driver】为F1系列HAL库外设驱动源码,创建工程时会复制其中部分文件
在这里插入图片描述
  【Middlewares】中包含了【ST】和【Third_Party】两个文件夹。
在这里插入图片描述
  在【CMSIS】文件夹中主要关注【Device】和【include】两个文件夹,新建工程时也是用到这两个文件夹;【Device】文件夹中包含微控制器专用头文件、启动文件、专用系统文件;【include】文件夹中包含Cortx-M内核及其设备文件、编译器相关头文件。

在这里插入图片描述

2.3.1CMSIS标准规定软件包目录

   CMSIS标准规定软件包目录也就是STM32Cube固件库文件夹所包含的内容。用到的有【Driver】和【Include】文件夹。
在这里插入图片描述

2.3.2Device和Include文件夹的关键文件介绍

   【Device】文件夹中用到的文件包含以下文件,以下文件是简略后的文件。
在这里插入图片描述
   stm32f103后面的xe是根据FLASH容量进行选择,在【include】文件夹中保存3个文件:stm32f1xx.h、stm32f103xe.h、system_stm32f1xx.h。
在这里插入图片描述
   以下目录中保留文件system_stm32f1xx.c,因为编译器是ARM,所以保留【arm】文件夹中的启动文件,并根据型号和容量来选择保留哪个启动文件。
在这里插入图片描述
在这里插入图片描述
   【include】文件夹中用到以下文件:cmsis_armcc.h(针对AC5编译器)、cmsis_armclang.h(针对AC6编译器)、cmsis_compiler.h(AC5和AC6编译器共用)、cmsis_version.h(编译器版本,也是共用的)、core_cm3.h (Cortex-M3内核,重点关注此文件)、 mpu_armv7.h(mpu内存保护)。
在这里插入图片描述

3.HAL库框架结构(了解)

3.1HAL库文件夹结构

   F1系列的HAL库被保存到【STM32F1xx_HAL_Driver】文件夹中,Src(Source):外设驱动源码;Inc(Include):外设驱动源码头文件。前面提到HAL库和LL库是捆绑发布的,就体现在驱动源码包含在【Inc】和【Src】文件夹中。【Inc】和【Src】文件夹中的【Legacy】文件夹是补充源文件,并不是所有系列都需要。
在这里插入图片描述

3.2HAL库文件介绍

   文件名中有hal的就是hal库文件,有ll的就是LL库文件。stm32f1xx_hal_conf.h文件可用于裁剪HAL库中用不到的功能,减少编译后得文件大小。
在这里插入图片描述

3.3HAL库API函数和变量命名规则

   用户一般不会直接调用LL库,而是通过调用HAL库间接使用LL库,所以不必深入学习LL库。
在这里插入图片描述
  可以将以下初始化函数中的PPP替换成GPIO,反初始化函数很少用到,主要用于失能时钟、恢复默认配置等。

初始化/反初始化函数: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 ()

3.3.1HAL库对寄存器位操作的相关宏定义

在这里插入图片描述

3.3.2HAL库回调函数

在这里插入图片描述
  此类回调函数通常被_weak修饰(弱函数),允许用户重新定义该函数。

4.如何使用HAL库(熟悉)

4.1基于CMSIS应用程序文件描述

  CMSIS核心层文件就是将【CMSIS】文件夹中的【Device】和【Include】文件夹中裁剪后剩的11个文件,这11个文件对于新建MDK工程是必须包含的;设备驱动层就是HAL库及LL库的源码,也就是【STM32F1xx_HAL_Driver】文件夹中的源码;用户程序文件,正点原子例程都将main.h、stm32f1xx_hal_msp.c删除掉了,放到了例如初始化UART就将UART的在stm32f1xx_hal_msp.c中的回调函数放到usart.c中,stm32f1xx_it.c和stm32f1xx_it.h里面本身就定义了一些中断,所以选择保留,如果写串口中断,推荐写到usart.c中。
在这里插入图片描述

4.1.1STM32开发文件结构分布

在这里插入图片描述

4.2HAL 库的用户配置文件

  如果是F1系列那么就修改stm32f1xx_hal_conf.h。获取此文件可以从STM32官方例程中获取,也可以从HAL库驱动源码中获取,只是名称不同,复制时只需要将template删除即可。
在这里插入图片描述
在这里插入图片描述

4.2.1裁剪HAL库外设驱动源码(不进行编译)

  STM32HAL库裁剪就是将stm32f1xx_hal_conf.h中用不到的宏定义注释掉,因为在HAL库驱动源码中都是用的ifdef判断宏是否被定义。以GPIO为例如下所示:
在这里插入图片描述
  通过对工程中用到什么外设就加什么驱动文件,也是起到裁剪作用。如下所示,是部分HAL库驱动文件:
在这里插入图片描述

4.2.2设置外部高速晶振频率(根据开发板实际情况设置)

  以下代码是设置高速外部晶振,宏USE_STM3210C_EVAL判断是否使用ST官方开发板,默认为25MHz,否则为8MHz。要根据开发板实际情况进行设置。如果要省事可以简化以下代码为:#define HSE_VALUE 8000000U

#if !defined  (HSE_VALUE) 
#if defined(USE_STM3210C_EVAL)
  #define HSE_VALUE    25000000U /*!< Value of the External oscillator in Hz */
#else
  #define HSE_VALUE    8000000U /*!< Value of the External oscillator in Hz */
#endif
#endif /* HSE_VALUE */

  高速内部晶振和低速内部晶振可以根据芯片手册进行设置:

#if !defined  (HSI_VALUE)
  #define HSI_VALUE              8000000U  
#endif /* HSI_VALUE */
#if !defined  (LSI_VALUE) 
 #define LSI_VALUE               40000U  
#endif /* LSI_VALUE */

4.2.3设置外部低速晶振频率(根据开发板实际情况设置)

#if !defined  (LSE_VALUE)
 #define LSE_VALUE               32768U    
#endif /* LSE_VALUE */

在这里插入图片描述

4.3stm32f1xx_hal.c 文件

  使用HAL库最关心的就说HAL库初始化函数HAL_Init(),不同系列可能有些小区别,但是核心代码如下:

HAL_StatusTypeDef  HAL_Init(void) 
{ 
	__HAL_FLASH_PREFETCH_BUFFER_ENABLE(); 	                    /* 使能FLASH预取缓冲 */ 

	HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2); /* 配置中断优先级分组 */ 

	/* 使用滴答定时器作为时钟基准,配置 1ms 滴答(重置后默认的时钟源为 HSI) */ 
	HAL_InitTick(TICK_INT_PRIORITY); 

	HAL_MspInit(); 	/* 初始化其它底层硬件(如果必要) */ 

	return HAL_OK; 	/* 返回函数状态 */ 
}

   第一段程序作用是使能FLASH预取缓冲,STM32是32位的,每次读取的指令也是32位的,FLASH存在预取缓冲区,预取缓冲区由2个64位组成,CPU每次读取指令,将指令放在预取缓冲区,就可以起到程序加快运行的效果。

__HAL_FLASH_PREFETCH_BUFFER_ENABLE(); 	                    /* 使能FLASH预取缓冲 */ 

   第二段程序是设置中断优先级分组,默认情况下设置位为4,正点原子默认设置成2。

HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2); /* 配置中断优先级分组 */ 

  第三段是使能系统滴答定时器,并且配置为1ms。正点原子实际配置滴答定时器在delay.c中的delay_Init()函数中。

/* 使用滴答定时器作为时钟基准,配置 1ms 滴答(重置后默认的时钟源为 HSI) */ 
	HAL_InitTick(TICK_INT_PRIORITY); 

  HAL_MspInit()为空函数,不用管它。

HAL_MspInit(); 	/* 初始化其它底层硬件(如果必要) */

5.HAL库使用注意事项(了解)

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

6.总结(了解)

在这里插入图片描述

  • 38
    点赞
  • 155
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花落指尖❀

您的认可是小浪宝宝最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值