STM32四种库对比 STM32标准库和HAL库有什么不同?

发布者:Harmonious222最新更新时间:2024-07-18 来源: elecfans关键字:STM32  HAL库 手机看文章 扫描二维码
随时随地手机看文章

  STM32的四种库:STM32Snippets、Standard Peripheral Library、STM32Cube LL、STM32Cube HAL。

  1STM32Snippets什么是STM32Snippets?STM32Snippets可翻译为“代码片段”、“裁剪”,其实他就是我们常说的“寄存器”开发STM32的底层驱动代码。比如配置ADC引脚的代码片段:

  __INLINE void ConfigureGPIOforADC(void)

  {

  /* (1) Enable the peripheral clock of GPIOA, GPIOB and GPIOC */

  /* (2) Select analog mode for PA1 */

  /* (3) Select analog mode for PB1 */

  /* (4) Select analog mode for PC0 */

  RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN; /* (1) */

  GPIOA->MODER |= GPIO_MODER_MODER1; /* (2) */

  GPIOB->MODER |= GPIO_MODER_MODER1; /* (3) */

  GPIOC->MODER |= GPIO_MODER_MODER0; /* (4) */

  }

  STM32Snippets是 高度优化的示例代码集合 ,使用符合CMSIS的直接寄存器访问来减少代码开销,从而在各种应用程序中最大化STM32 MCUs的性能。

  STM32Snippets主要针对底层开发人员,或者从51转过来,直接操作寄存器开发的人员。 是没有经过封装,可见底层寄存器的一套示例代码。每个STM32系列的100多个片段演示了如何以最小的内存占用有效地使用STM32外围设备。

  STM32Snippets目前官方只提供: STM32F0和L0的示例代码包 。

  提供的示例代码有点类似标准外设库风格,给大家看下F0的代码包:

  

 

  同样也提供Keil MDK、 IAR EWARM的工程。

  2Standard Peripheral Library

  Standard Peripheral Library:简写SPL,也叫标准外设库 。

  相信学习过STM32的朋友,对标准外设库都不陌生,是一组外围设备的C语言代码集合。 (因为现在ST官方主推STM32CubeMX,所以停止了对SPL的更新) 标准外设库是在寄存器的基础上进行了一次简单封装,主要是面向过程的嵌入式系统开发人员。

  

 

  目前标准外设库 支持STM32F0、F1、F2、F3、F4、L1 ,不支持F7、H7、 MP1、L0、L4、L5、G0、G4等后面推出的系列。所以,不要再问: 在哪里下载L0的标准外设库了 。

  3STM32Cube LL 和 HAL

  LL:**** Low-Layer,底层库

  HAL: Hardware Abstraction Layer,硬件抽象层库

  STM32Cube HAL和LL配合STM32CubeMX工具对STM32进行开发。也是目前ST官方主推的一套开发STM32的库。HAL针对的是具有一定嵌入式基础的开发人员,HAL具有很好的移植性。LL库相对HAL,具有简单的结构,针对之前从事SPL(标准外设库),或寄存器开发的人员。

  

 

  STM32Cube HAL和LL是目前官方主推,并重点维护和更新的库,也建议大家都学习一下。而且新出来的型号(如L5、G4等系列)没有标准外设库,只有STM32Cube HAL和LL库了。

  4四种库对比

  来自官方的对比信息,包含可移植性、优化、难易程度等。

  

 

  其中: Portability: 可移植性; Optimization : 优化; Easy: 难易程度; Hardware coverage: 硬件覆盖。

  定位:

  

 

  支持器件:

  

 

  最近新增了STM32Cube MP1,官方没有统计上。

  库之间的转移:

  

 

  STM32标准库和HAL库有什么不同?

  网上关于标准库、HAL库的描述相信是数不胜数。可是一个对于很多刚入门的朋友还是没法很直观的去真正了解这些不同开发发方式彼此之间的区别,下面以一种非常直白的方式,用自己的理解去将这些东西表述出来。

  一、配置寄存器

  不少先学了51的朋友可能会知道,会有一小部分人或是教程是通过汇编语言直接操作寄存器实现功能的,这种方法到了STM32就变得不太容易行得通了。因为STM32的寄存器数量是51单片机的十数倍,如此多的寄存器根本无法全部记忆,开发时需要经常的翻查芯片的数据手册,此时直接操作寄存器就变得非常的费力了。但还是会有很小一部分人,喜欢去直接操作寄存器,因为这样更接近原理,知其然也知其所以然。

  二、标准库

  STM32有非常多的寄存器,而导致了开发困难,所以为此ST公司就为每款芯片都编写了一份库文件,也就是工程文件里stm32F1xx.....之类的。在这些.c .h文件中,包括一些常用量的宏定义,把一些外设也通过结构体变量封装起来,如GPIO口时钟等。所以我们只需要配置结构体变量成员就可以修改外设的配置寄存器,从而选择不同的功能。也是目前最多人使用的方式,也是学习STM32接触最多的一种开发方式。

  三、HAL库

  HAL库是ST公司目前主力推的开发方式,全称就是Hardware Abstraction Layer(抽象印象层)。库如其名,很抽象,一眼看上去不太容易知道其作用是什么。它的出现比标准库要晚,但其实和标准库一样,都是为了节省程序开发的时期,而且HAL库尤其的有效,如果说标准库把实现功能需要配置的寄存器集成了,那么HAL库的一些函数甚至可以做到某些特定功能的集成。也就是说,同样的功能,标准库可能要用几句话,HAL库只需用一句话就够了。并且HAL库也很好的解决了程序移植的问题,不同型号的stm32芯片它的标准库是不一样的,例如在F4上开发的程序移植到F3上是不能通用的,而使用HAL库,只要使用的是相通的外设,程序基本可以完全复制粘贴,注意是相通外设,意思也就是不能无中生有。例如F7比F3要多几个定时器,不能明明没有这个定时器却非要配置,但其实这种情况不多,绝大多数都可以直接复制粘贴。是而且使用ST公司研发的STMcube软件,可以通过图形化的配置功能,直接生成整个使用HAL库的工程文件,可以说是方便至极,但是方便的同时也造成了它执行效率的低下,在各种论坛帖子真的是被吐槽的数不胜数。

  四、总结

  综合上面说的,其实笔者还是强烈推荐HAL库的,理由有二:

  一、 F7系列开始 ST公司就已近开始停止更新标准库,也就是F7开始包括F7已经不能用标准库了,公司对于主打HAL库的目的已经非常明显了。

  二、追求更方便、追求模块化向来是世界的潮流,更方便的HAL库一定会迅速发展,低效的短板迟早会被硬件高度集成化所弥补 。

  当然啦,不能只学习HAL库,底层的原理必需是要懂的,这是每个学有所成的人都公认的事实,HAL库也不是万能的,结合对底层的理解相信一定会让你的开发水准大大提高。

  五、STM32 HAL库与标准库的区别

  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);比如后面要讲到的MSP与Callback回调函数:


void HAL_UART_MspInit(UART_HandleTypeDef *huart); void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);在这些函数中,只需要调用初始化时定义的句柄UART1_Handler就好。

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函数之后,移植性非常强,但与此同时却增加了代码量和代码的嵌套层级。可以说各有利弊。同样,MSP函数又可以配合句柄,达到非常强的移植性:


void HAL_UART_MspInit(UART_HandleTypeDef *huart);

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

[1] [2]
关键字:STM32  HAL库 引用地址:STM32四种库对比 STM32标准库和HAL库有什么不同?

上一篇:ch32和stm32的区别
下一篇:CubeMX配置stm32的DAC

推荐阅读最新更新时间:2024-10-10 11:41

STM32 定时器输出比较翻转模式
STM32的定时器还有一个模式叫做输出比较翻转模式。这种模式,顾名思义,可以翻转电平,但是条件是:当计数值达到比较值时,才会在对应的通道引脚翻转原先的电平。利用这个特点,我们可以在引脚上生成PWM波。 下面就讲讲如何利用这个 翻转 这个特点,来输出PWM波。还是基于我自己的规工程。 1、工程的修改 1)这里用到了定时器,所以需要将stm32f10x_tim.h添加到STM32F10x_StdPeriod_Driver工程组中。 2)打开stm32f0x_conf.h文件,将其中原先被屏蔽的语句:#include stm32f10x_tim.h 的注释去掉。 3)新建OCToggle.c与OCToggle.h两个文件,分别保存
[单片机]
<font color='red'>STM32</font> 定时器输出比较翻转模式
STM32学习笔记----内存管理
1.简介 内存管理: 指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。 内存管理的实现方法有很多种,最终都是要实现两个函数: malloc 和 free。 malloc :函数用于内存申请; free: 函数用于内存释放。 1.1 分块式内存管理原理 由上图可知,分块式内存管理由内存池和内存管理表两部分组成。内存池被等分为 n块,对应的内存管理表,大小也为 n,内存管理表的每一个项对应内存池的一块内存。 内存管理表的项值代表的意义:当该项值为 0 的时候,代表对应的内存块未被占用;当该项值非零的时候,代表该项对应的内存块已经被占用,其数值则代
[单片机]
<font color='red'>STM32</font>学习笔记----内存管理
如何选择合适的MCU
什么是 STM32 STM32,从字面上来理解,ST 是意法半导体,M 是 Microelectronics 的缩写,32 表示 32 位,合起来理解,STM32 就是指 ST 公司开发的 32 位微控制器。在如今的 32 位控制器当中,STM32 可以说是最璀璨的新星,它受宠若娇,大受工程师和市场的青睐,无芯能出其右。 STM32 属于一个微控制器,自带了各种常用通信接口,比如 USART、I2C、SPI 等,可接非常多的传感器,可以控制很多的设备。现实生活中,我们接触到的很多电器产品都有 STM32 的身影,比如智能手环,微型四轴飞行器,平衡车、移动 POST 机,智能电饭锅,3D 打印机等等。下面我们以最近最为火爆的两个
[单片机]
如何选择合适的MCU
基于STM32的术后引流负压吸引器
由于很多病人手术后脏器创口没有得到有效的愈合,此时会在腹腔内积累各种液体。最为常见的就是在临床中,为了保证肠道患者在术后能尽快康复,就需要将来自胃的低PH值的消化液借助引流设备排出体外。目前国内外市场上通常使用一次性负压吸引袋或机械式吸引器将体液引流至体外。但是这种方法产生的负压并不稳定,吸引的压强可能会有较大的变化,导致负压吸引的效果不理想。同时一次性负压吸引袋的后期垃圾处理较为复杂,如果处理不当,易造成较大污染。最重要的是,传统方式气密性不理想,容易造成倒灌而造成患者的二次感染。 相比之下,嵌入式系统通过检测体内腔压的方式控制引流,能动态控制负压大小,也能实时监控病人的体液的各种参数,稳定性好。同时具有自动清洗的功能,操作便捷
[单片机]
基于<font color='red'>STM32</font>的术后引流负压吸引器
STM32 外部GPIO中断配置
源起:项目中需要使用统一的时间触发信号使得采样时间同步,因此需要某一个管脚来进行触发。 硬件情况:采用PA11管脚 需要明确的是,PxN管脚共用外部中断线EXTIN和外部中断向量EXTIN_IRQn和中断服务程序入口EXTIN_IRQHandler,但是需要注意的是 共用EXTI9_5_IRQn和EXTI9_5_IRQHandler、 共用EXTI15_10_IRQn和EXTI15_10_IRQHandler 基本过程: 1、设置时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);  注意需要打开AFIO时钟
[单片机]
STM32通过DMA方式采集多路AD
一个项目需求:使用STM32采集多路AD信号。 一般采集多路信号需要使用DMA方式,步骤如下: 1.使能相应ADC通道,这里使用ADC1的4个通道,分别是ADC123_IN0 ~ ADC123_IN3, 注:ADC123_IN0 表示ADC1, 2, 3 都可以使用该通道。 2.配置ADC, 将ADC设为多通道循环扫描模式,设置各通道扫描顺序(人为设定) 3.配置DMA通道 关键点在DMA的配置,ADC的采样值放在相应的数据寄存器中,通过DMA通道将该寄存器的值传输到内存中的某处(定义一个数组),内存地址自增,外设地址固定。则数组中的值就是各通道的采集数据。 代码如下: adc.c mai
[单片机]
<font color='red'>STM32</font>通过DMA方式采集多路AD
STM32例程之USB HID双向数据传输
程序功能 将STM32的USB枚举为HID设备。 STM32使用3个端点,端点0用于枚举用,端点1和2用于数据的发送和接收。 端点长度为64,也就是单次最多可以传输64个字节数据。 STM32获取上位机下发的数据并将该数据通过USB原样返回,同时将数据打印输出。 上位机程序通过调用windows的API实现对HID设备的读写控制。 USB接口原理图: HID枚举成功: 程序效果图 图一 上位机程序运行图 图二 STM32串口打印输出 图三 Bus Hound抓取的数据 程序部分代码 STM32的报告描述符: const uint8_t CustomHID_ReportDescriptor = { 0
[单片机]
<font color='red'>STM32</font>例程之USB HID双向数据传输
1、STM32学习笔记——系统时钟初始化函数
STM32有三种不同的时钟源可被用来驱动系统时钟(SYSCLK): 1:HSI振荡器时钟(内部时钟) 2:HSE振荡器时钟 (外部时钟,即晶振所提供) 3:PLL时钟(锁相环时钟) 这些设备有以下2种二级时钟源: (1)40kHz低速内部RC,可以用于驱动独立看门狗和通过程序选择驱动RTC。RTC用于从停机/待机模式下自动唤醒系统。 (2)32.768kHz低速外部晶体也可用来通过程序选择驱动RTC(RTCCLK)。 当不被使用时,任一个时钟源都可被独立地启动或关闭,由此优化系统功耗。 1:常用配置如下 使用HSE作为PLL的输入源,将PLL的输出配置为72MHZ,然后将PLL作为系统时钟,最后将其他时钟配置为
[单片机]
1、<font color='red'>STM32</font>学习笔记——系统时钟初始化函数
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved