一、为什么使用固件库

用函数封装寄存器操作(我能解释的只有这一句话......),相比于51单片机,STM32功能强大的多,寄存器也多了不知道多少倍,要是像51单片机那样直接操作寄存器开发会给人搞得头晕。用户可以自行在官网下载适合自己开发板的固件库,也可以向开发板客服直接要,一般都会提供。我所使用的是STM32F407ZGT6,原子哥提供的固件库为stm32f4_dsp_stdperiph_lib

官方标准的固件库已经不维护,在一些高端的STM32芯片甚至直接不发布固件库,提倡使用封装度更高的HAL库。但为什么还是要使用固件库呢?因为在使用固件库开发过程中,可以让我们更直观的理解芯片的工作流程,相比于HAL库,固件库占用资源更少。固件库学好了之后,HAL库便大同小异,后续使用CubeMx软件开发便更加简单。此外,前几年国内芯片收到制裁时,ST官方直接禁止了CubeMx软件的国内使用,国内很多国产芯片与STM32的寄存器也基本一致,这时候能够学会使用固件库便尤为重要

二、STM32F407新建工程模板,基于固件库

本流程完全参考正点原子的新建流程,读者可直接在B站上搜索相应的视频学习

(流程很长,芯片不同参考意义不大,请自行查阅其他参考资料!!!)

1. 新建文件目录

我们建立一个文件夹为 Template。 这是工程的根目录文件夹。然后为了方便我们存放工程需要的一些其他文件,这里我们还新建下面 5 个子文件夹: CORE ,FWLIB,OBJ,SYSTEM,USER。

2. 新建工程

打开 Keil,点击 Keil 的菜单: Project –>New Uvision Project ,然后将目录定位到刚才建立的文件夹Template 之下的USER 子目录, 同时,工程取名为 Template 之后点击保存,我们的工程文件就都保存到 USER 文件夹下面。

3. 芯片选型

接下来会出现一个选择 Device 的界面,就是选择我们的芯片型号,这里我选择STMicroelectronics 下面的 STM32F407ZG,如果使用的是其他系列的芯片,选择相应的型号即可,一定要安装相应的器件支持包,否则无法选型

点击 OK, MDK 会弹出 Manage Run-Time Environment 对话框,添加RTE组件,关于RTE后续介绍,此处直接cancel即可

此时,USER文件夹中的内容为下图所示

Template.uvprojx 是工程文件,非常关键,不能轻易删除,Listings和ObjectsListings 和 Objects 文件夹是 MDK 自动生成的文件夹,用于存放编译过程产生的中间文件。这里,我们把两个文件夹删除,我们会在下一步骤中新建一个 OBJ 文件夹,用来存放编译中间文件。当然,我们不删除这两个文件夹也是没有关系的,只是我们不用它而已

4. 复制相关库文件

(1) FWLib 文件夹

打开官方固件库包,定位到我们之前准备好的固件库包的目录: \STM32F4xx_DSP_StdPeriph_Lib_V1.4.0\Libraries\STM32F4xx_StdPeriph_Driver 下面,将目录下面的 src,inc 文件夹 copy 到我们刚才建立的 FWLib 文件夹下面

(2) CORE文件夹

 将固件库包里面相关的启动文件复制到我们的工程目录 CORE 之下。

打开官方固件库包,定位到目录\STM32F4xx_DSP_StdPeriph_Lib_V1.4.0\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templat es\arm 下面,将文件 startup_stm32f40_41xxx.s 复制到 CORE 目录下面。然后定位到目录\STM32F4xx_DSP_StdPeriph_Lib_V1.4.0\Libraries\CMSIS\Includ , 将 里 面 的 四 个 头 文 件 : core_cm4.h、 core_cm4_simd.h、 core_cmFunc.h 以及 core_cmInstr.h 同样复制到 CORE 目录下面。

现在 CORE 文件夹下面的文件有

(3) USER文件夹

首先定位到目录: STM32F4xx_DSP_StdPeriph_Lib_V1.4.0\Libraries\CMSIS\Device\ST\STM32F4xx\Include 将里面的 2 个头文件 stm32f4xx.h 和 system_stm32f4xx.h 复制到 USER 目录之下。

然后进入目录\STM32F4xx_DSP_StdPeriph_Lib_V1.4.0\Project\STM32F4xx_StdPeriph_Templates ,将 目 录 下 面 的 5 个 文 件 main.c , stm32f4xx_conf.h , stm32f4xx_it.c , stm32f4xx_it.h , system_stm32f4xx.c 复制到 USER 目录下面。

5. 添加.c/.s文件

前四步骤将文件夹创建好,但是Keil不会自动添加文件夹,需要手动添加

点击图标,Project Targets 一栏,我们将 Target 名字修改为 Template,然后在 Groups 一栏删掉一个 SourceGroup1,建立三个 Groups: USER,CORE,FWLIB。

而后为每一个Group添加.c文件:这里第一步我们选择 FWLIB,然后点击右边的 Add Files,定位到我们刚才建立的目录\FWLIB\src 下面,将里面所有的文件选中(Ctrl+A),然后点击 Add,然后 Close.可以看到 Files 列表下面包含我们添加的文件,如下图 所示。

这里需要说明一下,对于我们写代码,如果我们只用到了其中的某个外设,我们就可以不用添加没有用到的外设的库文件。例如我只用 GPIO,我可以只用添加 stm32f4xx_gpio.c 而其他的可以不用添加。全部添加进来是为了后面方便,不用每次添加,当然这样的坏处是工程太大,编译起来速度慢。

这里有个文件 stm32f4xx_fmc.c 比较特殊。这个文件是 STM32F42 和 STM32F43 系列才用到,所以我们这里要把它删掉(注意是 stm32f4xx_fmc.c 要删掉,不要删掉 stm32f4xx_fsmc.c)

用同样的方法,将 Groups 定位到 CORE 和 USER 下面,添加需要的文件。这里我们的 CORE 下面需要添加的文件为 startup_stm32f40_41xxx.s(注意,默认添加的时候文件类型为.c,也就是添加 startup_stm32f40_41xxx.s 启动文件的时候,你需要选择文件类型为 All files才能看得到这个文件 ), USER 目录下面需要添加的文件为 main.c, stm32f4xx_it.c, system_stm32f4xx.c。 这样我们需要添加的文件已经添加到我们的工程中去了,最后点击 OK,回到工程主界面。

6. 设置.h文件引用路径

我们需要添加的头文件路径包括: \CORE, \USER\以及\FWLIB\inc。这里大家务必要仔细,固件库存放的头文件子目录是\FWLIB\inc,不是 FWLIB\src。

7. 设置宏定义

接下来对于 STM32F40 系列的工程,还需要添加一个全局宏定义标识符。添加方法是点击魔术棒之后,进入 C/C++选项卡,然后在 Define 输入框连输入:STM32F40_41xxx,USE_STDPERIPH_DRIVER。注意这里是两个标识符 STM32F40_41xxx和 USE_STDPERIPH_DRIVER, 他们之间是用逗号隔开的

8. 设置编译文件输出路径

接下来我们要编译工程,在编译之前我们首先要选择编译中间文件编译后存放目录。方法是点击魔术棒 ,然后选择“Output”选项下面的“Select folder for objects…” ,然后选择目录为我们上面新建的 OBJ 目录。 同时将下方的三个选项框都勾上

9. 修改代码

(1) main.c

该文件中的代码修改为

#include "stm32f4xx.h"

void Delay(__IO uint32_t nCount);

void Delay(__IO uint32_t nCount)
{
    while(nCount--){}
}

int main(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOF, &GPIO_InitStructure);
    while(1)
    {
        GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);
        Delay(0x7FFFFF);
        GPIO_ResetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);
        Delay(0x7FFFFF);
    }
}

(2) stm32f4xx_it.c

删掉其中的 对main.h 头文件的引入以及 144 行 SysTick_Handler 函数内容

(3) 时钟修改

时钟系统将在后续文章中详细介绍,此处先改

System_stm32f4xx.c文件中,PLL 第一级分频系数 M 修改为 8


在 stm32f4xx.h 里面修改外部时钟 HSE_VALUE 值为 8MHz,因为我的开发板外接晶振8MHz,读者需根据实际情况修改

注:若.c文件的展开菜单中没有.h文件,需要先编译,编译后还没有,那就重启电脑之后编译

重新编译,

至此,STM32F407工程模板已经建立完成。

三、结语

固件库模板工程的建立非常复杂,步骤非常多,但只要建立一次,后续便可直接复制使用。若使用HAL库,结合CubeMx软件建立新工程相当简单,该部分内容放在时钟系统之后介绍。

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐