国内使用STM32 单片机的人很多,ST 为开发者提供了非常方便的开发库:有标准外设库(SPL 库)、HAL 库、LL 库 三种。前者是ST的老库,后两者是ST现在主推的开发库,其中 LL 库是 ST 新添加的,随 HAL 源码包一起提供。各库关系如下所示:
其中,SPL 库 和 HAL 库两者相互独立,互不兼容,标准外设库比较老了,现在推荐使用HAL/LL库。几种库的比较如下:
目前几种库对不同芯片的支持情况如下:
以下是标准库支持的stm32系列,和上图是一致的,可见标准库并不支持最新的高性能的F7/H7系列:
ST 中文官网上有一篇关于ST库函数的代码性能的对比:
STM32 Snippets
stm32 snippet是高度优化的代码示例的集合,它使用符合CMSIS规范的直接寄存器访问方式来减少代码开销,从而使STM32 mcu在各种应用程序中的性能达到最大化。目前STM32系列共有100多个snippet片段代码,演示了如何以最小的内存占用率、高效地使用STM32外围设备。stm32 snippet是直接读写STM32的外设寄存器,需要开发者直接操作外设寄存器,对开发者要求比较高。
这个库使用比较少,目前只在 STM32F0 和 STM32L0 系列中有提供,如下图所示:
stm32 snippet就是将 MCU 中的寄存器进行了结构化的封装,库文件主要就是一些 .h 文件。如下是对 ADC 的封装
typedef struct{
__IO uint32_t ISR; /*!< ADC Interrupt and Status register,Address offset:0x00 */
__IO uint32_t IER; /*!< ADC Interrupt Enable register, Address offset:0x04 */
__IO uint32_t CR; /*!< ADC Control register, Address offset:0x08 */
__IO uint32_t CFGR1; /*!< ADC Configuration register 1, Address offset:0x0C */
__IO uint32_t CFGR2; /*!< ADC Configuration register 2, Address offset:0x10 */
__IO uint32_t SMPR; /*!< ADC Sampling time register, Address offset:0x14 */
uint32_t RESERVED1; /*!< Reserved, 0x18 */
uint32_t RESERVED2; /*!< Reserved, 0x1C */
__IO uint32_t TR; /*!< ADC watchdog threshold register,Address offset:0x20 */
uint32_t RESERVED3; /*!< Reserved,0x24 */
__IO uint32_t CHSELR; /*!< ADC channel selection register, Address offset:0x28 */
uint32_t RESERVED4[5]; /*!< Reserved, 0x2C */
__IO uint32_t DR; /*!< ADC data register, Address offset:0x40 */
}ADC_TypeDef;
typedef struct{
__IO uint32_t CCR;}ADC_Common_TypeDef;
在实际使用时,我们就可以结构化的访问 MCU 的寄存器,如下是配置 ADC 的函数实现:
__INLINE void ConfigureADC(void){
ADC1->CFGR2 |= ADC_PRESCALER;
ADC1->CFGR1 |= ADC_CFGR1_AUTOFF;
ADC1->CHSELR = ADC_CHSELR_CHSEL17;
ADC1->SMPR |= ADC_SMPR_SMP_0 | ADC_SMPR_SMP_1 | ADC_SMPR_SMP_2;
ADC->CCR |= ADC_CCR_VREFEN;
}
标准外设库(Standard Peripheral Libraries)
标准外设库(Standard Peripherals Library)是对 STM32 芯片的一个完整的封装,包括所有标准器件外设的器件驱动器。几乎全部使用 C 语言实现。但是,标准外设库也是针对某一系列芯片而言的,没有可移植性。
相对于 HAL 库,标准外设库仍然接近于寄存器操作,其是将一些基本的寄存器操作封装成了 C 函数。相对于 STM32 Snippets,标准外设库对各外设进行了一次封装,而不是仅仅局限在对寄存器的封装,标准外设库实现了各外设的基本操作接口。
标准外设库的文件基本架构并不复杂。下图显示了 STM32F10xx 标准外设库文件的基本架构
其他系列的库文件结构和上图基本都是一致的。ppp是代表不同的具体外设,比如ADC、DAC、SPI。。。
STM32 的标准外设库涵盖以下内容:
位域和寄存器的完整的寄存器地址映射
涵盖所有外围功能的例程和数据结构的集合。
一组包含所有可用外设的示例,其中包含最常用的开发工具的模板项目。
STM32Cube
ST 为新的标准库注册了一个新商标:STMCube™。并且,ST专门为其开发了配套的桌面软件 STMCubeMX,开发者可以直接使用该软件进行可视化配置,大大节省开发时间。
这其中就包含了 HAL 库和LL 库。如下图:
从上图看出,LL 库和 HAL 库两者相互独立,只不过 LL 库更底层。而且,部分 HAL 库会调用LL库(例如:USB驱动)。同样,LL 库也会调用 HAL 库
用户可以使用 STMCubeMX 直接生成对应芯片的整个项目(目前主流开发工具IAR/KEIL的项目全支持),STMCubeMX 负责给整理各种需要的源码文件。
HAL 库
HAL是 Hardware Abstraction Layer 的缩写,即硬件抽象层。HAL 库是 ST 为 STM32 最新推出的抽象层嵌入式软件,可以更好的确保跨 STM32 产品的最大可移植性。该库提供了一整套一致的中间件组件,如 RTOS、USB、TCP/IP 和图形库等。
ST的中间件堆栈有USB 主机和设备库,STemWin图形库、FreeRTOS,FatFs,LwIP等。HAL 库就是用来取代之前的标准外设库的。相比标准外设库,STM32Cube HAL 库表现出更高的抽象水平,HAL API 集中关注各外设的公共函数功能,这样便于定义一套通用的用户友好的API函数接口,从而可以轻松实现从一个STM32产品移植到另一个不同的STM32系列产品。HAL库是ST未来主推的库,当前ST新出的芯片已经没有STD库了,比如 F7/H7系列都没有标准库,只有HAL/LL库。目前,HAL库已经支持STM32全线产品。关于HAL库的使用,在后续推文中将重点介绍。
LL 库
LL库(Low Layer)是 ST 新增的库,与 HAL 库捆绑发布,文档也是和 HAL 库文档在一起的,比如:在STM32F3x 的 HAL 库说明文档中,ST 新增了LL库这一章节。LL 库更接近硬件层,是直接操作寄存器,效率更高,很少在复杂外设中使用。其支持所有外设。使用有两种方法:
独立使用,该库完全独立实现,可以完全抛开 HAL 库,只用LL库编程完成。在使用STM32CubeMX生成项目时,直接选LL库即可。如果使用了复杂的外设,例如 USB,则会调用 HAL 库
混合使用,和 HAL 库结合使用。
目前,CubeMX 在生成项目时,可以选择采用 LL 库。
LL 库文件的命名方式和 HAL 库基本相同。LL 库就是原来的标准外设库移植到 Cube下的新的实现,但是其实现方法更加高效、简洁。使用 LL 库编程和使用标准外设库的方式基本一样,会得到比标准外设库更高的效率。
视频简单示例stm32cubeMX: