初识HAL库(了解)
ST 为了方便用户开发 STM32芯片开发提供了三种库:
- 标准外设库 (Standard Peripheral Libraries)
- HAL库(硬件抽象层):Hardware Abstraction Layer
- LL库:Low Layer
一、获取STM32Cube固件包
方式一:ST官网( 意法半导体-STMicroelectronics )搜索STM32Cube
选择你需要的stm32cube的文件包(根据你的硬件型号进行选择,我的型号是stm32F108c)
新页面往下滑。选择要下载的版本
或者使用git进行代码拉取(这里拉取的是v1.8.0的版本)
git clone http://github.com/STMicroelectronics/STM32CubeF1.git -b v1.8.0 --depth 1
方式二:开发板A盘资料:A 盘→8,STM32 参考资料→1,STM32CubeXX固件包
二、STM32文件结构分布
要想学会stm32hal库首先要了解总体的文件架构,总体架构分为三部分 MCU硬件层
、CMSIS接口层
、用户程序层
以下就是各个文件描述CMSIS (微控制器软件接口标准):Cortex Microcontroller Software Interface Standard,是由ARM和与其合作的芯片厂商、软件工具厂商,共同制定的标准
三、STM32Cube固件库文件简介
其中STM32Cube固件库文件中最重要的是Drivers和Middlewares文件夹中的文件和了解project文件夹
Drivers文件夹介绍:
BSP文件夹
存放开发板板级支持包驱动代码,如各种外设驱动
CMSIS文件夹
STM32F1xx_HAL_Driver文件夹
文件介绍
HAL库API函数和变量命名规则
文件名 | stm32f1xx_hal_ppp .(c/h) | stm32f1xx_hal_ppp .(c/h) |
---|---|---|
函数名 | HAL_PPP_Function | HAL_PPP_Function |
外设句柄 | PPP_HandleTypeDef | 无 |
外设工作参数初始化结构体 | PPP_InitTypeDef | PPP_InitTypeDef |
配置参数结构体 | PPP_ YyyyConfTypeDef | PPP_ YyyyConfTypeDef |
初始化/反初始化函数: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库对寄存器位操作的相关宏定义
宏定义结构 | 用途 |
---|---|
__HAL_PPP_ENABLE_IT(HANDLE, INTERRUPT) | 使能外设中断 |
__HAL_PPP_DISABLE_IT(HANDLE,INTERRUPT) | 禁用外设中断 |
__HAL_PPP_GET_IT (HANDLE, __ INTERRUPT __) | 获取外设某一中断源 |
__HAL_PPP_CLEAR_IT (HANDLE, __ INTERRUPT __) | 清除外设中断 |
__HAL_PPP_GET_FLAG (HANDLE, FLAG) | 获取外设的状态标记 |
__HAL_PPP_CLEAR_FLAG (HANDLE, FLAG) | 清除外设的状态标记 |
__HAL_PPP_ENABLE(HANDLE) | 使能某一外设 |
__HAL_PPP_DISABLE(HANDLE) | 禁用某一外设 |
__HAL_PPP_XXXX (HANDLE, PARAM) | 针对外设的特殊操作 |
_HAL_PPP_GET IT_SOURCE (HANDLE, __INTERRUPT __) | 检查外设的中断源 |
HAL库回调函数
回调函数 | 举例 |
---|---|
HAL_PPP_MspInit() / _MspDeInit() | 举例: HAL_USART_MspInit()会被HAL_PPP_Init() 函数调用,该函数主要用于存放外设使用到的GPIO、CLOCK、NVIC、DMA等初始化代码 |
HAL_PPP_ProcessCpltCallback | 举例: HAL_USART_TxCpltCallback由外设中断或DMA中断调用,HAL库中断公共处理函数已经实现对中断标记位读取、判断和清除操作,用户只需要专注于中断逻辑功能的实现即可 |
HAL_PPP_ErrorCallback | 举例: HAL_USART_ErrorCallback外设或DMA中断中发生的错误,用于发生错误处理 |
此类函数通常被_weak修饰(弱函数),允许用户重新定义该函数
Middlewares文件夹介绍
该文件夹下面有 ST 和 Third_Party 2 个子文件夹。
ST 文件夹下面存放的是 STM32 相关的一些文件,包括 STemWin 和 USB 库等。
Third_Party 文件夹是第三方中间件,这些中间件都是非常成熟的开源解决方案。
Projects 文件夹
该文件夹存放的是一些可以直接编译的实例工程。每个文件夹对应一个 ST 官方的 Demo板。比如要查看 STM32L476 相关工程,直接打开子文件夹 STM32L476G-EVAL即可。里面有很多实例,都可以用来参考。
这里注意,每个工程下面都有一个MDK-ARM 子文件夹,该子文件夹内部会有名称为 Project.uvprojx 的工程文件,我们只需要点击它就可以在MDK中打开工程。 例如打 开Projects\STM32L476G-EVAL\Templates\MDK-ARM 文件夹,内容如下图:
四、使用
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中。。
HAL 库的用户配置文件
如果是F1系列那么就修改stm32f1xx_hal_conf.h。获取此文件可以从STM32官方例程中获取,也可以从HAL库驱动源码中获取,只是名称不同,复制时只需要将template删除即可。
裁剪HAL库外设驱动源码(不进行编译)
STM32HAL库裁剪就是将stm32f1xx_hal_conf.h中用不到的宏定义注释掉,因为在HAL库驱动源码中都是用的ifdef判断宏是否被定义。以GPIO为例如下所示:
通过对工程中用到什么外设就加什么驱动文件,也是起到裁剪作用。如下所示,是部分HAL库驱动文件:
stm32f1xx_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每次读取指令,将指令放在预取缓冲区,就可以起到程序加快运行的效果。
-
第二段程序是设置中断优先级分组,默认情况下设置位为4,正点原子默认设置成2。
-
第三段是使能系统滴答定时器,并且配置为1ms。正点原子实际配置滴答定时器在delay.c中的delay_Init()函数中。
-
HAL_MspInit()为空函数