Logo

郎哥编程

初识STM32固件库

2026-11-02 4

1.什么是STM32固件库

STM32固件库是ST公司针对STM32单片机提供的函数接口,开发者可以调用这些函数接口来配置STM32单片机的寄存器,让开发人员可以脱离最底层的寄存器操作。

STM32固件库开发方式

实际上,固件库是架设在用户驱动层与寄存器层之间的代码,向下处理与寄存器直接相关的配置,向上为用户提供配置寄存器的接口,固件库开发方式与寄存器开发方式的区别见上图。

2.STM32结构及库层次关系

2.1.CMSIS标准

我们知道,由ST公司开发的STM32系列单片机采用了Cortex-M3内核,该内核作为微控制器的核心处理单元(CPU),是整个芯片的运算中枢。这一内核由ARM公司设计,属于其处理器架构体系的一部分。ARM公司本身并不直接生产芯片,而是通过技术授权的方式向芯片制造商提供内核设计方案。ST公司或其他芯片生产厂商在获得授权后,负责设计内核之外的附加部件,这些部件被称为核外外设、片上外设或设备外设。例如,芯片内部集成的模数转换器(ADC)、通用异步收发器(UART)、定时器(TIM)等模块,均属于此类外设范畴。

Cortex-M3内核

观察上图,可以发现Cortex - M3内核由ARM公司设计,是芯片的‌核心处理单元(CPU)‌,负责指令执行、数据运算等核心计算任务;而外设、存储器、时钟和复位、I/O‌等模块,由芯片制造商(如ST公司)自主设计开发,属于“核外外设”范畴。这种分工模式下,ARM提供内核技术授权,芯片厂商则围绕内核构建差异化功能模块,实现“通用内核 + 定制外设”的灵活架构。

因为基于Cortex-M3内核的系列芯片采用的内核都是相同的,区别主要为核外的片上外设的差异,这些差异却导致软件在同内核、不同外设的芯片上移植困难。为了解决不同芯片厂商的生产的Cortex微控制器软件的兼容性问题,ARM与芯片厂商建立了CMSIS标准。因此CMSIS标准,实际上是建立了一个软件抽象层,见下图:

CMSIS架构

用户层处于整个架构的最上层,是开发者进行应用开发的地方,开发者编写的各种应用程序代码都位于此层。

CMSIS层是整个架构的核心中间层,它分为内核函数层和设备外设访问层。

内核函数层由ARM公司提供,包含用于访问内核寄存器的名称、地址定义等,这为访问Cortex-M4内核相关的功能提供了统一的接口和标准。

设备外设访问层则由芯片生产商提供,提供了片上核外外设的地址和中断定义,像外设寄存器定义以及中断向量定义就属于这部分,这使得不同芯片厂商的外设访问有了统一的规范。

CMSIS层还包含CMSIS-DSP库,它主要用于数字信号处理相关的功能实现。

CMSIS实时系统API则为实时系统的开发提供了应用程序接口,实时系统内核通过这些API与上层的用户代码进行交互。

设备外设函数,例如STM32驱动函数库,也是CMSIS层的一部分,它提供了对各种外设进行操作的函数,方便开发者对芯片的外设进行控制。

核内外设函数则是针对内核内部外设的操作函数,用于实现对内核相关外设的管理和控制。

2.2.获得STM32固件库

本教程采用STM32F103R6芯片作为教学芯片,因此主要下载STM32 F1系列芯片固件库,若使用其它系列芯片,需要下载对应的芯片固件库。

第一步:访问ST官网

打开浏览器进入ST官网,选择中文语言。

第二步:进入“工具与软件”页面

点击导航菜单“工具与软件”命令,进入“工具与软件页面”。

第三步:进入“嵌入式软件”页面

点击左侧“嵌入式软件”标签,进入“嵌入式软件”页面。

第四步:进入“STM32嵌入式软件”页面

点击右侧“STM嵌入式软件”标签,进入“STM32嵌入式软件”页面。

第五步:进入“STM32 标准外设库”页面

点击左侧“STM标准外设库”标签,进入“STM32标准外设库”页面。

 

第六步:下载固件库

在“STM32标准外设库”页面,点击图形中的“F1”区域,进入固件库下载页面。

标准固件库的最新版本为V3.6.0(适用于STM32F10x全系列)。点击“获取最新版本”,会弹出接受协议的对话框。

无需登录,点击“作为访客下载”即可。在随后的对话框中,输入名字、姓氏和真实的邮箱地址(用于接收下载连接)。邮箱收到下载连接后,单击下载连接即可下载固件库。

2.3.库目录和文件

解压库文件后进入目录:

STM固件库目录和文件结构及功能如下:

Release_Notes.html:发布说明文件,包含固件库版本信息、更新内容等信息。

stm32f10x_stdperiph_lib_um.chm:库帮助文档,为编译的HTML文件,详细讲述驱动库使用方法及各外设函数说明,开发中可查询函数使用信息。

Libraries目录:固件库的源代码及启动文件。

Project目录:ST官方提供的外设驱动例程,涵盖多种外设使用方法,供开发者学习和参考以快速驱动外设。

Utilities目录:包含基于ST官方实验板的例程,使用非官方实验板时可忽略。

_htmresc目录:存放ST公司logo图片,与工程模板创建无关,可忽略。

在使用固件库时,我们需要把Libraries目录下的库函数文件添加到工程中,并查阅库帮助文档来了解ST提供的库函数,这个文档说明了每一个库函数的使用方法。

进入Libraries文件夹,Libraries文件夹内组织结构如下图:

CMSIS目录:存放Cortex-M3文件,包括启动文件、内核文件、外设头文件等,实现不同厂家Cortex芯片软件兼容。

STM32F10x_StdPeriph_Driver目录:包含外设驱动代码,inc目录存外设头文件(.h),src目录存外设源文件(.c),每个外设对应一组.c和.h文件,是开发中操作外设的核心文件。

CMSIS\CMS目录下又分为CoreSupport和DeviceSupport目录。

1、core_cm3.c文件

在CoreSupport文件夹中的是位于CMSIS标准的核内设备函数层的CM3核通用的源文件core_cm3.c和头文件core_cm3.h。它们的作用是为采用Cortex-M3内核的芯片商设计的芯片外设提供一个进入CM3内核的接口。对于其它公司的CM3系列芯片,这两个文件也是相同的。它实现了对内核寄存器、NVIC(嵌套向量中断控制器)、SysTick定时器等关键组件的访问函数。

core_cm3.c文件中包含大量与编译器相关的条件编译语句,主要目的是兼容不同的ARM编译器,这些语句通过预定义宏来识别特定的编译器,并为不同编译器提供相应的内联汇编实现,在Keil MDK开发环境中,该文件使用__CC_ARM宏来标识ARM编译器,并据此定义一系列内核访问函数。如下面的代码:

/* define compiler specific symbols */
#if defined ( __CC_ARM   )
  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */
  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */
#elif defined ( __ICCARM__ )
  #define __ASM           __asm                                       /*!< asm keyword for IAR Compiler          */
  #define __INLINE        inline                                      /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
#elif defined   (  __GNUC__  )
  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
#elif defined   (  __TASKING__  )
  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler      */
  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler   */
#endif

上述代码是条件编译指令,用于根据不同的ARM编译器定义统一的内联汇编和inline关键字宏。代码具体解析如下:

‌检测ARM编译器 (__CC_ARM)‌:如果使用ARM Compiler (如Keil MDK中的armcc),则将__ASM宏定义为__asm,将__INLINE宏定义为__inline。

‌检测IAR编译器 (__ICCARM__)‌:如果使用IAR编译器,则将__ASM宏定义为__asm,将__INLINE宏定义为inline,并特别注明inline关键字仅在高优化模式下可用。

‌检测GNU编译器 (__GNUC__)‌:如果使用GNU编译器 (如GCC),则将__ASM宏定义为__asm,将__INLINE宏定义为inline。

‌检测TASKING编译器 (__TASKING__)‌:如果使用TASKING编译器,其宏定义与GNU编译器相同。

这段代码的目的在于屏蔽不同编译器在内联汇编和inline关键字语法上的差异,通过定义统一的__ASM和__INLINE宏,使得上层代码可以无需修改即可在不同编译环境下编译,从而提高了代码的可移植性。

core_cm3.c文件还包含了<stdint.h>头文件,这是一个ANSI C文件,独立于处理器之外,主要是提供一些新数据类型的定义。如定义了下面的数据类型:

int8_t、int16_t、int32_t、int64_t 分别表示8位、16位、32位、64位的有符号整数;

uint8_t、uint16_t、uint32_t、uint64_t 分别表示8位、16位、32位、64位的无符号整数。

2、system_stm32f10x.c文件

在DeviceSupport文件夹下的是启动文件、外设寄存器定义和中断向量层的一些定义文件,这是由ST提供的。如下图所示:

system_stm32f10x.c文件主要用于系统初始化与时钟配置。该文件主要包含 SystemInit() 和 SystemCoreClockUpdate() 这两个关键函数,以及一个重要的全局变量 SystemCoreClock。

SystemInit() 函数负责在上电复位后初始化系统时钟,包括配置时钟源、PLL倍频因子以及AHB/APB总线的预分频器等,确保整个芯片的各个部分能以正确的时钟频率运行。这个函数通常由汇编编写的启动文件(如 startup_stm32f10x_hd.s)在跳转到 main 函数之前自动调用。

SystemCoreClock 全局变量记录了当前内核的运行频率,用户在配置 SysTick 定时器或其他依赖于精确时钟的参数时,可以直接引用此变量。

SystemCoreClockUpdate() 函数则用于在系统内核时钟(HCLK)发生改变后,同步更新 SystemCoreClock 全局变量的值。

3、stm32f10x.h文件

stm32f10x.h是STM32F10x系列微控制器开发中的核心头文件,该文件通过结构体封装完成了所有外设寄存器的地址映射,将每个外设的基地址强制转换为对应的结构体指针类型。开发者可以直接通过类似GPIOA->ODR的方式访问寄存器,无需手动计算地址偏移。同时文件中包含了完整的寄存器位定义,方便进行位操作。

作为工程的基础头文件,它通过包含stm32f10x_conf.h来间接管理所有外设头文件。这种设计让开发者能够统一配置所需的外设模块,通过简单的宏定义切换即可适配不同型号的STM32F10x芯片。

4、启动文件

Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm文件夹下是由汇编语言编写的系统启动文件,不同的文件对应不同的芯片型号,在使用时要注意,见下图;

文件名的英文缩写意义如下:

vl : 超值型产品,STM32F100系列;

cl:互联网型产品;

hd:高密度产品,Flash大于128KB;

ld: 低密度产品,Flash小于64KB;

md:中密度产品,Flash等于64KB或128KB。

本课程采用的是STM32F103R6,STM32F103R6的Flash容量为32KB,因此属于低密度产品,启动文件要选择startup_stm32f10x_ld.s。

启动文件(如startup_stm32f10x_ld.s)是系统上电后第一个执行的程序,主要负责硬件初始化和运行环境搭建,为后续用户代码(如main函数)的执行奠定基础。‌

5、STM32F10x_StdPeriph_Driver文件夹

Libraries\STM32F10x_StdPeriph_Driver文件夹下面有in(include的缩写)和src(source的缩写)这两个文件夹,这都属于CMSYS的设备外设函数部分,src里面是每个外设的驱动程序,这些外设是芯片制造商Cortex-M3核外加进去的。

在src和in文件里面的就是ST公司针对每个STM32外设编写的库函数文件,每个外设对应一个.c和.h后缀的文件。把这类外设文件统称为:stm32f10x_mmm.c或stm32f10x_mmm.h文件,mmm表示外设名称。

如针对异步通信外设,在src文件夹下有一个stm32f10x_usart.c文件,在in文件夹下有一个stm32f10x_usart.h头文件,若我们的工程用到了异步通信外设,就需要把这两个文件包含到工程里。

在这两个文件夹中还有一个文件misc.c和misc.h文件,这个文件提供了外设对内核中的NVIC(中断向量控制器)的访问函数,在配置中断时,必须把这个文件添加到工程里。

6、stm32f10x_it.c和stm32f10x_conf.h文件

在库目录的Project\STM32F10x_StdPeriph_Template文件夹下,存放了官方提供的一个库工程模板,我们在用库建立一个完整的工程时,还需要添加这个目录下的stm32f10x_it.c、stm32f10x_conf.h和stm32f10x_it.h到工程里。

stm32f10x_it.c是用来编写中断服务函数的,这个文件已经定义了一些系统异常中断的接口,其它普通中断服务函数需要我们自己添加和编写,中断服务函数的接口命名可以在汇编启动文件中找到。

stm32f10x_conf.h文件被包含进stm32f10x.h文件,是用来配置使用了什么外设的头文件,用这个头文件,我们可以方便地增加或删除上面STM32F10x_StdPeriph_Driver目录下的外设驱动函数库。

3.使用库帮助文档

STM32固件库的库帮助文档是开发过程中非常重要的参考资料,它详细介绍了所有外设的驱动函数、参数说明和使用方法。

固件库帮助文档已经随固件库安装到本地电脑,一般存储在固件库根目录下,文件名称为:

stm32f10x_stdperiph_lib_um.chm

在使用库函数时,我们最好通过查阅此文件来了解库函数原型或库函数调用的方法,也可以直接阅读源码里面的函数说明。

打开库帮助文档,如下图:

帮助文档的左侧为目录树,列出了所有外设模块(如GPIO、USART、ADC等)。点击你感兴趣的外设名称,右侧会显示该外设的所有相关函数或针对该外设的结构体定义。

在目标外设的Functions列表中,你可以找到所有可用的库函数。点击函数名,即可查看其详细说明,包括:

‌函数原型‌:函数的声明和参数列表。

‌功能描述‌:函数的作用和用途。

‌参数说明‌:每个参数的具体含义和取值范围。

‌返回值‌:函数的返回值类型和意义。

‌示例‌:部分函数会提供简单的使用示例‌

如下图所示:

帮助文档的内容通常是从固件库源码中提取的。因此,你也可以在开发环境中(如Keil)直接查看库函数的源码,以获取更深入的理解。

4.常用官方资料

STM32单片机的官方资料可以从官网下载,具体包括:《数据手册》、《参考手册》、《编程手册》等官方资料,如下图所示。

 

评论区

请 登录 后发表评论
暂无评论