HAL库是什么,HAL库的定义
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库的定义相关推荐
- STM32 HAL库学习笔记1-HAL库简介
STM32 HAL库学习笔记1-HAL库简介 HAL库 SPL 库 和 HAL 库两者相互独立,互不兼容.几种库的比较如下 目前几种库对不同芯片的支持情况如下 ST 中文官网上有一篇<关于ST库 ...
- 论STM32标准库程序修改为HAL库
标准库占绝大多数,自己买的板子跟的资料也一般是标准库,HAL库很少,不过要是使用STM32CubeMx配置,那么就是使用的HAL库了,而参考资料是标准库的,就没有办法用. 注意: 1.标准库与HAL库 ...
- keil添加hal库_Stm32CubeMX生成的hal库工程加入标准库的库函数的方法
本帖最后由 seawind1986 于 2017-4-7 22:30 编辑 第一步用Stm32CubeMX创建一个工程并生成Keil MDK的工程,不多赘述. 001.jpg (127.92 KB, ...
- 【08】STM32·HAL库开发-HAL库介绍 | STM32Cube固件库介绍 | HAL库框架结构 | 如何使用HAL库及使用注意事项
目录 1.初识HAL库(了解) 1.1CMSIS简介 1.2HAL库简介 2.STM32Cube固件包浅析(了解) 2.1如何获取STM32Cube固件包? 2.2STM32Cube固件包文件夹简介 ...
- 【STM32F4系列】【HAL库】【自制库】WS2812(软件部分)(PWM+DMA)
文章目录 相关链接 协议 外设设置 硬件PWM 分析 HAL设置 DMA 分析 HAL设置 方案设计 代码实现 解码函数 开始发送和复位 发送函数 波形 成品 相关链接 硬件介绍(PCB设计方案) 模 ...
- h7的HAL 1.8.0版本库的RTC时钟没起振 死循环 无法退出
h7的HAL 1.8.0版本库 和1.7.0的版本都存在RTC 退出去的情况 当外部晶振不起振会出现在RTC函数出不来的情况 H7的RTC有bug的地方 没改动之前的代码 这个只有H7的1.8.0 ...
- STM32 HAL库开发转固件库开发杂谈
前言 本文使用代码工程 STM32HAL库开发转固件库开发杂谈-嵌入式文档类资源-CSDN文库 STM32 最早提供固件库开发,在当时也是一个很大的创新.导致大量攻城狮熟悉了固件库开发,后面STM32 ...
- python RE库的基本使用!基本定义详细讲解!来源于MOOCpython,课程链接文章末尾有!
前言: 代码的格式为中文,因为是在WORD里黏贴过来的.默认的是中文,所以代码仅供参考,直接复制黏贴使用不OK的!要改为英文格式下的: ' Re库介绍: Re库是Python的标准库,主要用于字符串匹 ...
- Android HAL原理实现 GPS HAL实现
1 android HAL框架 Android HAL是google应厂商不希望公开源码的要求所推出的新概念.它能以封闭源码的形式提供硬件驱动模块,其目的是把Android Framework 和li ...
- 第2课【CMSIS和标准库开发】标准库 CMSIS 分层
目录 基本知识框架 课堂笔记 CMSIS CMSIS的分层关系和作用 CMSIS层文件结构 内核函数层文件 外设函数访问层文件 标准库开发 标准库开发 LED-GPIO 标准库开发 KEY-GPIO ...
最新文章
- 程序员:我受够了!不想再在小厂里干Java了!
- JavaScript 技术篇-js获取iframe内的元素方法实例演示
- ASP.NET-Session cooike
- 基于JBoss Fuse 6.2的JBoss BPM微服务集成指南
- android webview控件的缩放问题 隐藏缩放控件
- PaperNotes(15)-图神经网络、PyG极简版入门笔记
- linux 修改用户登录密码
- java jdbc 传参_java – 将参数传递给JDBC PreparedStatement
- 用计算机坑人,10大坑人专业,坑你没商量!
- Spring 基础概念——DI、IOC(一)
- 基于Android 9.0 电池温度异常提醒
- 5. 使用字符串库函数
- Window平台下通过cmd命令查看端口占用、查看进程、结束进程
- python处理时间序列非平稳_推荐 :手把手教你用Python处理非平稳时间序列(附代码)...
- 485芯片RO 口收不到信号问题分析
- 采集宝贝提示“属性值最大长度为42个字符(21个汉字)”怎么解决?
- php嵌入图片代码,php如何添加图片
- 奢华和生活方式酒店品牌阿丽拉将引入上海;施华洛世奇揭幕全新品牌视觉形象 | 美通企业日报...
- html和css实现导航栏样式
- 云计算产品学习(2)