7-STM32固件库模板工程指南

1 CMSIS 标准及库层次关系

CMSIS(Cortex Microcontroller Software Interface Standard)是由 ARM 与芯片厂商共同建立的一个标准,旨在解决不同 Cortex 微控制器在软件兼容性方面的问题。尽管基于 Cortex 系列的芯片使用相同的内核,但由于片上外设的差异,软件在不同芯片上的移植常常面临困难。CMSIS 通过提供一个软件抽象层,简化了这一过程。

1.1 CMSIS 架构

  • 内核函数层
    • 包含用于访问内核寄存器的名称和地址定义。
    • 主要由 ARM 公司提供,确保了对 Cortex 内核的统一访问方式。
  • 设备外设访问层
    • 提供片上核外外设的地址和中断定义。
    • 主要由芯片生产商提供,确保与特定芯片的外设功能的兼容性。

1.2 CMSIS 的优势

  • 硬件抽象层:CMSIS 创建了一个与芯片厂商无关的硬件抽象层,使得软件开发者可以编写与特定硬件无关的代码,从而提高了代码的可移植性。
  • 简化接口:为外设和实时操作系统提供简单的处理器软件接口,降低了开发的复杂性。
  • 移植性:通过屏蔽硬件差异,CMSIS 大大简化了软件在不同 Cortex 微控制器之间的移植过程,使得开发者能够更专注于应用逻辑,而不是底层硬件的细节。

2 固件库下载

参考文章:http://ckun.fun/index.php/2024/11/29/stm32-sld/

3 库文件介绍

解压后进入库文件夹 STM32F4xx_DSP_StdPeriph_Lib_V1.8.0 目录下,会有四个文件夹和相关文件,它们的作用如下:

  • _htmresc:
  • Libraries:标准库函数的文件
  • Project:官方提供的工程例程和模板,使用库函数的时候可以参考
  • Utilities:这个STM32官方评估板的相关例程
  • stm32f4xx_dsp_stdperiph_lib_um.chm:固件库使用帮助说明

3.1 Libraries

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

进入Libraries 文件夹,下面有两个文件夹,他们分别是:

  • 内核库文件:CMSIS
  • 外设库文件:STM32F4xx_StdPeriph_Driver

3.1.1 CMSIS

进入CMSIS 文件夹下,里面有很多文件夹和文件:

  • Device:芯片相关文件
  • Documentation:说明文档
  • DSP_Lib:DSP函数源文件
  • Include:内核相关头文件
  • Lib:DSP库函数
  • RTOS:实时操作系统头文件
3.1.1.1 Include

在 CMSIS 标准中,特别是针对 Cortex-M 核的设计,包含了一系列通用的头文件。这些头文件的主要作用是为采用 Cortex-M 核设计的系统单芯片(SoC)提供一个与内核交互的接口,并定义了一些与内核相关的寄存器。这些文件的定义是标准化的,因此在不同厂商的 Cortex-M 系列芯片中,它们是相同的。

头文件的作用:定义了内核的相关寄存器,通过这些头文件,芯片制造商可以为外设提供一个进入内核的接口,使得开发者能够方便地访问和控制内核功能。

在 STM32F4 项目中,通常需要包含以下四个核心文件:

  • core_cm4.h提供 Cortex-M4 内核的基本定义和功能
    • core_cm4.c 文件有一些与编译器相关条件编译语句,用于屏蔽不同编译器的差异
    • core_cm4.c 跟启动文件一样都是底层文件,都是由 ARM 公司提供的,遵守 CMSIS 标准,即所有CM4 芯片的库都带有这个文件,这样软件在不同的 CM4 芯片的移植工作就得以简化。
  • core_cmFunc.h:包含与内核功能相关的函数和宏定义。
  • core_cmInstr.h:定义了 Cortex-M4 指令集相关的功能
  • core_cmSimd.h: 提供 SIMD(单指令多数据)操作的支持
3.1.1.2 Device

CMSIS 文件夹中的 Device 文件夹提供了 STM32F4 系列微控制器开发所需的基础文件,包括系统时钟初始化启动文件外设寄存器定义等。通过这些文件,开发者可以方便地配置和控制 STM32 芯片的硬件功能,为应用程序的开发提供了重要支持。

  • system_stm32f4xx.c:在 \Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates 文件夹下。
    • 包含 STM32 芯片上电后的系统时钟初始化功能以及扩展外部存储器的初始化函数
    • 主要函数 SystemInit 用于在芯片上电后初始化系统时钟。调用这个函数后,STM32F429 系列芯片的系统时钟会被设置为 180MHz。
    • 用户可以根据需求修改此文件中的内容,以设置所需的时钟频率。
  • 启动文件:在 Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\arm 文件夹下
    • STM32F429 芯片的启动文件名:startup_stm32f429_439xx.s
    • 对应芯片选择对应信号的启动文件
  • stm32f4xx.h:在Libraries\CMSIS\Device\ST\STM32F4xx\Include 文件夹下
    • 这是一个非常重要的头文件,包含 STM32F4 系列芯片的所有外设寄存器地址结构体类型定义
    • 在使用 STM32 标准库时必须包含此头文件,以便正确访问和操作外设。

3.1.2 STM32F4xx_StdPeriph_Driver

  • inc:包含各个外设头文件
  • src:库函数源文件
  • Release_Notes.html:库版本更新说明

在 STM32F4xx_StdPeriph_Driver 文件夹中,包含了两个子文件夹:inc(包含头文件)和 src(包含源文件)。这些文件主要涉及芯片的片上外设,属于 CMSIS 之外的内容。

在 src 和 inc 文件夹中,文件的命名遵循统一的规则,即 stm32f4xx_ppp.c 和 stm32f4xx_ppp.h,其中 PPP 表示外设名称。

在这两个文件夹中,还有一个特别的文件:misc.c。这个文件提供了外设与内核中的 NVIC(中断向量控制器)之间的访问函数。在配置中断时,开发者必须将这个文件添加到工程中,以确保能够正确管理和响应中断。

3.1.2.1 src
  • 这个文件夹包含了每个外设的驱动源程序。每个外设通常会有一个对应的 .c 文件;
  • 例如,针对模数转换(ADC)外设,src 文件夹下会有一个名为 stm32f4xx_adc.c 的源文件。
3.1.2.2 inc
  • 包含与每个外设对应的头文件,通常以 .h 后缀命名;
  • 例如,与 ADC 外设相关的头文件为 stm32f4xx_adc.h。

3.2 库工程模板

在STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Project\STM32F4xx_StdPeriph_Templates 文件夹下。

3.2.1 stm32f4xx_it.c

在 src 目录下,这个文件是专门用来编写中断服务函数的。在这个文件中,已经定义了一些系统异常(特殊中断)的接口,而其他普通中断服务函数需要由开发者自己添加。但是,开发者需要遵循特定的接口规范来编写这些中断服务函数,这些规范可以在汇编启动文件中找到。

3.2.2 stm32f4xx_it.h

在inc目录下,这个文件是 stm32f4xx_it.c 文件的头文件,包含了中断服务函数的声明。

3.2.3 stm32f4xx_conf.h

这个文件被包含进 stm32f4xx.h 文件中。ST 标准库支持所有 STM32F4 型号的芯片,但是有的型号芯片外设功能比较多。因此,使用这个配置文件可以根据芯片型号增减 ST 库的外设文件。具体来说,这个文件用于指定芯片的型号,从而确定哪些外设文件需要被包含。

4 库各文件间的关系

5 标准库模板搭建(STM32F429IGTb)

5.1 创建一个新工程

  • 首先创建一个名为 engineering_template 的文件夹,等下创建的工程模板文件就放在这个文件夹下

5.2 keil 新建工程

  • project -> new uVision Project…
  • 在弹出窗口,进入刚创建的工程文件夹,并在文件名处录入 demo 的工程文件名
  • 保存后,弹出 选择目标设备 窗口,在搜索栏填写自己的芯片型号,回车自动搜索,在列表中找到对应的芯片型号,选择点击ok,这时会弹出一个 在线添加库文件 窗口,这里我们不用,直接关闭窗口
  • 此时工程创建完成,但工程中没有任何文件,还需要创建一些必要文件

5.3 固件库文件迁移

  • 打开固件库文件夹
  • 在‪STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\arm\ 目录下找到startup_stm32f429_439xx.s启动文件,复制
  • 打开自己的工程模板文件夹,创建一个Libraries 文件夹,Libraries 下再创建一个STARTUP 文件夹,将复制的启动文件放在startup 文件夹下。
  • 打开自己的工程模板文件夹,在Libraries 下创建一个CMSIS 文件夹,将下面这些文件都放入其中
  • STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\CMSIS\Device\ST\STM32F4xx\Include\stm32f4xx.h
  • STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\CMSIS\Device\ST\STM32F4xx\Include\system_stm32f4xx.h
  • STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c
  • STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\CMSIS\Include 下的所有文件
  • 在固件库下,复制STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\STM32F4xx_StdPeriph_Driver 文件夹
  • 打开自己的工程模板文件夹,将复制的文件夹放入Libraries 文件夹下
  • 打开自己的工程模板文件夹,创建一个USER 文件夹,将下面这些文件都放入其中
  • STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Project\STM32F4xx_StdPeriph_Templates\main.c
  • STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h
  • STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_it.c
  • STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_it.h

到此本地工程文件迁移完成,接下来需要进行软件配置。

5.4 keil 添加组文件夹

  • STARTUP:启动文件
  • CMSIS:核心库文件
  • FWLB:外设文件
  • USER:用户文件、中断文件

5.4.1 添加文件

  • 将工程模板文件夹下的STARTUP 文件夹下的文件全部添加进STARTUP 组中
  • 将工程模板文件夹下的CMSIS 文件夹下的部分文件全部添加进CMSIS 组中,如下图
  • 将工程模板文件夹下的STM32F4xx_StdPeriph_Driver文件夹中src 文件夹下的文件全部添加进FWIB 组中
  • 将工程模板文件夹下的USER 文件夹下的部分文件添加进USER 组中,如下图

5.4.2 设置文件是否加入编译

STM32F429 比较特殊,它有用 FMC 外设代替了 FSMC 外设的功能,所以它的库文件与其它型号的芯片不一样,在添加外设文件时,stm32f4xx_fmc.c 和 stm32f4xx_fsmc.c 文件只能存在一个,而且我们的 STM32F429 芯片必须用 fmc 文件。如果我们把外设库的所有文件都添加进工程,也可以使用下面的方法,设置文件不加入编译,这样也不会导致编译问题。这种设置在开发时也很常用,暂时不把文件加进编译,方便调试。

5.4.3 配置魔术棒

  • Target 中选中微库“Use MicroLib”,为的是在日后编写串口驱动的时候可以使用 printf 函数。而且有些应用中如果用了 STM32 的浮点运算单元 FPU,一定要同时开微库,不然有时会出现各种奇怪的现象。FPU 的开关选项在微库配置选项下方的“Use Single Precision”中,默认是开的。
  • 在 C/C++ 选项卡中添加处理宏及编译器编译的时候查找的头文件路径。
  • 将工程模板文件夹下带有头文件(.h)的文件夹目录添加进去
  • USE_STDPERIPH_DRIVER,STM32F429_439xx,
  • 在这个选项中添加宏,就相当于我们在文件中使用“#define”语句定义宏一样。在编译器中添加宏的好处就是,只要用了这个模版,就不用源文件中修改代码。
    • STM32F429_439xx 宏:为了告诉 STM32 标准库,我们使用的芯片是 STM32F429 型号,使STM32 标准库根据我们选定的芯片型号来配置。
    • USE_STDPERIPH_DRIVER 宏:为了让 stm32f4xx.h 包含 stm32f4xx_conf.h 这个头文件。
  • “Include Paths ”这里添加的是头文件的路径。
  • 下载器配置,本次仿真使用的是ST-link
  • 选择默认仿真器 Use Debug Driver
  • Debug setting 配置

5.5 编译

5.5.1 main.c

  • 由于这个main 文件是从参考文件中迁移过来的,里边的代码不是我们所需要的,全部删除,将下列代码粘贴进去即可
#include "stm32f4xx.h"

int main(void){}

5.5.2 stm32f4xx_it.c

  • 由于这个中断文件是从参考文件中迁移过来的,里面有部分是用不成的,需要将下列两个部分删除,不然编译会报错。

5.5.3 编译

  • 此时触发编译按钮,程序进行编译
  • 自此,模板文件创建大功告成

发表评论