1、HAL 库的定义

HAL是 Hardware Abstraction Layer 的缩写,中文名:硬件抽象层。HAL 库是 ST 为 STM32 最新推出的抽象层嵌入式软件,可以更好的确保跨 STM32 产品的最大可移植性。该库提供了一整套一致的中间件组件,如 RTOS,USB,TCP/IP 和 图形 等。
  百度有一堆定义, HAL 库是基于一个非限制性的 BSD 许可协议(Berkeley Software Distribution)而发布的开源代码。 ST 制作的中间件堆栈(USB 主机和设备库,STemWin)带有允许轻松重用的许可模式, 只要是在 ST 公司的 MCU 芯片上使用,库中的中间件(USB 主机/设备库,STemWin)协议栈即被允许随便修改,并可以反复使用。
但是我简单通俗的来讲,就是HAL库可以使得用户将代码跨芯片使用,不同的MCU芯片(F1/F2...)都可以使用,体现了可移植性强!!

2、STM32CubeMX

说到 STM32 的 HAL 库,就不得不提 STM32CubeMX,其作为一个可视化的配置工具,对于开发者来说,确实大大节省了开发时间。STM32CubeMX 就是以 HAL 库为基础的,且目前仅支持 HAL 库及 LL 库!

STM32CubeMX软件的特点:

  • 集成了ST的每一款型号的MCU/MPU的可配置的图形界面,能够自动提示IO冲突并且对于复用IO可自动分配;
  • 具有动态验证的时钟树;
  • 能够很方便的使用所集成的中间件;
  • 能够估算MCU/MPU在不同主频运行下的功耗;
  • 能够输出不同编译器的工程,比如能够直接生成MDK、EWARM、STM32CubeIDE、MakeFile等工程;

STM32CubeMX的使用也比较简单:先下载STM32CubeMx软件及对应不同系列MCU/MPU的Packs。

  • 确定要使用的MCU/MPU的型号;
  • 对所选的MCU/MPU的GPIO进行功能配置、配置时钟树及初始化相关参数;
  • 选择要用到的中间件进行配置;
  • 将配置好功能的MCU/MPU生成对应编译器的C语言工程文件;

stm32cubemx官网下载

3、HAL库与标准库(SPL)的区别

 文字性的东西我不宜过多赘述,这里直接上代码!

1、句柄

在STM32的标准库中,假设我们要初始化一个外设(这里以USART为例)
我们首先要初始化他们的各个寄

存器。在标准库中,这些操作都是利用固件库结构体变量+固件库Init函数实现的:

 USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = bound;//串口波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //收发模式USART_Init(USART3, &USART_InitStructure); //初始化串口1

可以看到,要初始化一个串口,需要对六个位置进行赋值,然后引用Init函数,并且USART_InitStructure并不是一个全局结构体变量,而是只在函数内部的局部变量,初始化完成之后,USART_InitStructure就失去了作用。

而在HAL库中,同样是USART初始化结构体变量,我们要定义为全局变量

UART_HandleTypeDef UART1_Handler;

右键查看结构体成员

typedef struct
{USART_TypeDef                 *Instance;        /*!< UART registers base address        */UART_InitTypeDef              Init;             /*!< UART communication parameters      */uint8_t                       *pTxBuffPtr;      /*!< Pointer to UART Tx transfer Buffer */uint16_t                      TxXferSize;       /*!< UART Tx Transfer size              */uint16_t                      TxXferCount;      /*!< UART Tx Transfer Counter           */uint8_t                       *pRxBuffPtr;      /*!< Pointer to UART Rx transfer Buffer */uint16_t                      RxXferSize;       /*!< UART Rx Transfer size              */uint16_t                      RxXferCount;      /*!< UART Rx Transfer Counter           */  DMA_HandleTypeDef             *hdmatx;          /*!< UART Tx DMA Handle parameters      */ DMA_HandleTypeDef             *hdmarx;          /*!< UART Rx DMA Handle parameters      */HAL_LockTypeDef               Lock;             /*!< Locking object                     */__IO HAL_UART_StateTypeDef    State;            /*!< UART communication state           */__IO uint32_t                 ErrorCode;        /*!< UART Error code                    */
}UART_HandleTypeDef;

我们发现,与标准库不同的是,该成员不仅包含了之前标准库就有的六个成员(波特率,数据格式等),还包含过采样、(发送或接收的)数据缓存、数据指针、串口 DMA 相关的变量、各种标志位等等要在整个项目流程中都要设置的各个成员。
该 UART1_Handler 就被称为串口的句柄
它被贯穿整个USART收发的流程,比如开启中断。

HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);

在这些函数中,只需要调用初始化时定义的句柄UART1_Handler就好。

也就是说我们是把各个成员全部封装好,移植的时候就可以直接调用了,那如果与用户需求不符怎么办,别急,后面要讲到的MSP与Callback回调函数:

void HAL_UART_MspInit(UART_HandleTypeDef *huart);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);

2、MSP函数

MCU Specific Package 单片机的具体方案
MSP是指和MCU相关的初始化,引用一下正点原子的解释,个人觉得说的很明白:

我们要初始化一个串口,首先要设置和 MCU 无关的东西,例如波特率,奇偶校验,停止
位等,这些参数设置和 MCU 没有任何关系,可以使用 STM32F1,也可以是STM32F2/F3/F4/F7上的串口。而一个串口设备它需要一个 MCU 来承载,例如用 STM32F4 来做承载,PA9 做为发送,PA10 做为接收,MSP 就是要初始化 STM32F4 的 PA9,PA10,配置这两个引脚。所以 HAL驱动方式的初始化流程就是:HAL_USART_Init()—>HAL_USART_MspInit() ,先初始化与 MCU无关的串口协议,再初始化与 MCU 相关的串口引脚。在 STM32 的 HAL 驱动中HAL_PPP_MspInit()作为回调,被 HAL_PPP_Init()函数所调用。当我们需要移植程序到 STM32F1平台的时候,我们只需要修改 HAL_PPP_MspInit 函数内容而不需要修改 HAL_PPP_Init 入口参数内容。

在HAL库中,几乎每初始化一个外设就需要设置该外设与单片机之间的联系,比如IO口,是否复用等等,可见,HAL库相对于标准库多了MSP函数之后,移植性非常强,但与此同时却增加了代码量和代码的嵌套层级。可以说各有利弊。

3、回调函数(callback)

类似于MSP函数,个人认为Callback函数主要帮助用户应用层的代码编写。
还是以USART为例,在标准库中,串口中断了以后,我们要先在中断中判断是否是接收中断,然后读出数据,顺便清除中断标志位,然后再是对数据的处理,这样如果我们在一个中断函数中写这么多代码,就会显得很混乱,这是标准库的处理:

void USART3_IRQHandler(void)                 //串口1中断服务程序
{u8 Res;if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾){Res =USART_ReceiveData(USART3);   //读取接收到的数据/*数据处理区*/}         }
} 

而在HAL库中,进入串口中断后,直接由HAL库中断函数进行托管:

void USART1_IRQHandler(void)
{ HAL_UART_IRQHandler(&UART1_Handler);  //调用HAL库中断处理公用函数/***************省略无关代码****************/
}

HAL_UART_IRQHandler这个函数完成了判断是哪个中断(接收?发送?或者其他?),然后读出数据,保存至缓存区,顺便清除中断标志位等等操作。
这就需要进去函数设置(嵌套性),比如我提前设置了,串口每接收五个字节,我就要对这五个字节进行处理。
在一开始我定义了一个串口接收缓存区:

/*HAL库使用的串口接收缓冲,处理逻辑由HAL库控制,接收完这个数组就会调用HAL_UART_RxCpltCallback进行处理这个数组*/
/*RXBUFFERSIZE=5*/
u8 aRxBuffer[RXBUFFERSIZE];

在初始化中,我在句柄里设置好了缓存区的地址,缓存大小(五个字节)

/*该代码在HAL_UART_Receive_IT函数中,初始化时会引用*/huart->pRxBuffPtr = pData;//aRxBufferhuart->RxXferSize = Size;//RXBUFFERSIZEhuart->RxXferCount = Size;//RXBUFFERSIZE

则在接收数据中,每接收完五个字节,HAL_UART_IRQHandler才会执行一次Callback函数:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);

在这个Callback回调函数中,我们只需要对这接收到的五个字节(保存在aRxBuffer[]中)进行处理就好了,完全不用再去手动清除标志位等操作。
所以说Callback函数是一个应用层代码的函数,我们在一开始只设置句柄里面的各个参数,然后就等着HAL库把自己安排好的代码送到手中就可以了~

参考

(30条消息) STM32 HAL库与标准库的区别_浅谈句柄、MSP函数、Callback函数_hal库句柄_Error_4O4的博客-CSDN博客

HAL库是什么,HAL库的定义相关推荐

  1. STM32 HAL库学习笔记1-HAL库简介

    STM32 HAL库学习笔记1-HAL库简介 HAL库 SPL 库 和 HAL 库两者相互独立,互不兼容.几种库的比较如下 目前几种库对不同芯片的支持情况如下 ST 中文官网上有一篇<关于ST库 ...

  2. 论STM32标准库程序修改为HAL库

    标准库占绝大多数,自己买的板子跟的资料也一般是标准库,HAL库很少,不过要是使用STM32CubeMx配置,那么就是使用的HAL库了,而参考资料是标准库的,就没有办法用. 注意: 1.标准库与HAL库 ...

  3. keil添加hal库_Stm32CubeMX生成的hal库工程加入标准库的库函数的方法

    本帖最后由 seawind1986 于 2017-4-7 22:30 编辑 第一步用Stm32CubeMX创建一个工程并生成Keil MDK的工程,不多赘述. 001.jpg (127.92 KB, ...

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

    目录 1.初识HAL库(了解) 1.1CMSIS简介 1.2HAL库简介 2.STM32Cube固件包浅析(了解) 2.1如何获取STM32Cube固件包? 2.2STM32Cube固件包文件夹简介 ...

  5. 【STM32F4系列】【HAL库】【自制库】WS2812(软件部分)(PWM+DMA)

    文章目录 相关链接 协议 外设设置 硬件PWM 分析 HAL设置 DMA 分析 HAL设置 方案设计 代码实现 解码函数 开始发送和复位 发送函数 波形 成品 相关链接 硬件介绍(PCB设计方案) 模 ...

  6. h7的HAL 1.8.0版本库的RTC时钟没起振 死循环 无法退出

    h7的HAL 1.8.0版本库  和1.7.0的版本都存在RTC 退出去的情况 当外部晶振不起振会出现在RTC函数出不来的情况 H7的RTC有bug的地方  没改动之前的代码 这个只有H7的1.8.0 ...

  7. STM32 HAL库开发转固件库开发杂谈

    前言 本文使用代码工程 STM32HAL库开发转固件库开发杂谈-嵌入式文档类资源-CSDN文库 STM32 最早提供固件库开发,在当时也是一个很大的创新.导致大量攻城狮熟悉了固件库开发,后面STM32 ...

  8. python RE库的基本使用!基本定义详细讲解!来源于MOOCpython,课程链接文章末尾有!

    前言: 代码的格式为中文,因为是在WORD里黏贴过来的.默认的是中文,所以代码仅供参考,直接复制黏贴使用不OK的!要改为英文格式下的: ' Re库介绍: Re库是Python的标准库,主要用于字符串匹 ...

  9. Android HAL原理实现 GPS HAL实现

    1 android HAL框架 Android HAL是google应厂商不希望公开源码的要求所推出的新概念.它能以封闭源码的形式提供硬件驱动模块,其目的是把Android Framework 和li ...

  10. 第2课【CMSIS和标准库开发】标准库 CMSIS 分层

    目录 基本知识框架 课堂笔记 CMSIS CMSIS的分层关系和作用 CMSIS层文件结构 内核函数层文件 外设函数访问层文件 标准库开发 标准库开发 LED-GPIO 标准库开发 KEY-GPIO ...

最新文章

  1. 程序员:我受够了!不想再在小厂里干Java了!
  2. JavaScript 技术篇-js获取iframe内的元素方法实例演示
  3. ASP.NET-Session cooike
  4. 基于JBoss Fuse 6.2的JBoss BPM微服务集成指南
  5. android webview控件的缩放问题 隐藏缩放控件
  6. PaperNotes(15)-图神经网络、PyG极简版入门笔记
  7. linux 修改用户登录密码
  8. java jdbc 传参_java – 将参数传递给JDBC PreparedStatement
  9. 用计算机坑人,10大坑人专业,坑你没商量!
  10. Spring 基础概念——DI、IOC(一)
  11. 基于Android 9.0 电池温度异常提醒
  12. 5. 使用字符串库函数
  13. Window平台下通过cmd命令查看端口占用、查看进程、结束进程
  14. python处理时间序列非平稳_推荐 :手把手教你用Python处理非平稳时间序列(附代码)...
  15. 485芯片RO 口收不到信号问题分析
  16. 采集宝贝提示“属性值最大长度为42个字符(21个汉字)”怎么解决?
  17. php嵌入图片代码,php如何添加图片
  18. 奢华和生活方式酒店品牌阿丽拉将引入上海;施华洛世奇揭幕全新品牌视觉形象 | 美通企业日报...
  19. html和css实现导航栏样式
  20. 云计算产品学习(2)

热门文章

  1. 无符号整型与有符号整型
  2. 大数据【企业级360°全方位用户画像】项目介绍
  3. 基于SSM的毕业设计管理系统
  4. 嵌入式Linux从入门到精通之第一节:软件安装
  5. 啥是数据处理能力?(二)数据处理工具
  6. JQUERY为元素添加样式的实现方法
  7. iTop-4412 裸机程序(十七)- 按键介绍
  8. 网络引流平台都有哪些?推荐5种引流获客方式!
  9. 【13】变分自编码器(VAE)的原理介绍与pytorch实现
  10. 实现全选和取消全选功能