创建STM32标准库工程模板(以F429为例)
目前stm32开发有寄存器、标准库、HAL库三种方式,库函数开发相比寄存器方式具有开发周期短、代码可读性好、便于移植等优点,而使用 Keil 环境的第一步就是新建工程。本文以 STM32F429IGT6 芯片为例,介绍使用标准库函数新建工程的步骤。
需要的东西:STM32F4xx_DSP_StdPeriph_Lib_V1.9.0、Keil-MDK
1.首先先下载好STM32F4xx 固件库,在STM32微控制器软件 - STMicroelectronics




标准库是第一代固件库,实现的外设相对较少,封装上的效率相对较低,而且,随着网路技术和USB技术的快速发展,已经很难满足当代的需求。比如标准库没有网络功能,没有文件系统,没有GUI等等。
现在STM32的固件库有标准库,HAL库和LL库三种,官方现在主推HAL库,标准库不再更新(F1标准库好像干脆直接下架了),新学的话建议直接学习HAL库,配合STM32CubeMX的配置工具非常容易使用STM32。其不仅效率有所提升,而且新增了对网络使用等的协议。
为什么标准库不是通用的?而是需要对应到某种型号的单片机?
因为不同型号的单片机,在CPU设计上,以及外设定义、引脚定义等各方面都有所差异。所以,不可能存在通用的一套代码,只能说,尽可能地通用。
2.下载解压后进入STM32F4xx_DSP_StdPeriph_Lib_V1.9.0目录


3.新建文件夹:Project、Libraries、User、Doc,之后就打开keil 5,在project的目录里新建工程,之后在Libraries中添加固件库里的两个文件
之后再删除我们不需要的文件:比如Release_Notes.html,还有CMSIS中除了Device和Include的:

在 \Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates中只保留如下选中,其余都删除:

在User文件夹我们需要以下文件,可以从固件库中复制过来\STM32F4xx_DSP_StdPeriph_Lib_V1.9.0\Project\STM32F4xx_StdPeriph_Templates
到现在为止,所有文件就大概配置好了,接下来到keil5中将这些文件导入:


然后开始编译:
出现这么多个错是因为我们的根目录的路径问题,所以我们要将包含根目录的文件的路径添加进去:

可是添加完路径后,也无法解决以上的问题,但是根目录这个时候已经都被包含进去了,然后我们打开main.c下包含的stm32f4xx.h文件,找到#if !defined (USE_STDPERIPH_DRIVER),单从字面意思理解就是“使用标准外设驱动”,在C/C++预定义中加入“USE_STDPERIPH_DRIVER”就是允许“使用标准外设驱动”了。
也就是说只有预先定义了USE_STDPERIPH_DRIVER后,才会包含stm32f4xx_conf.h头文件。在stm32f4xx_conf.h中,包含了各个驱动脚本的头文件,从而被main.c用到,这就解释了,为什么我们没有在“main.c”中包含"stm32f4xx_conf.h",而在编译之后却被包含进了"main.c"中。所以,我们需要定义这个USE_STDPERIPH_DRIVER;
之后,再定义一下我们使用此芯片的宏:

但是到这一步只解决了一部分错误,还有几十个错,找到了原因是我们有个驱动外设位FMC,它包含了FSMC,407的芯片没有FMC,它称之为FSMC,这是驱动屏幕使用的,这两个文件产生了冲突,所以我们需要在驱动库中找出这FMC和FSMC两个.c和.h文件,把它删掉,或者是在编译的时候选择不编译:

删除FMC和FSMC后在在编译有可能会发生以下情况:
…\USER\stm32f4xx.h(11581): warning: #47-D: incompatible redefinition of macro “DBGMCU_APB2_FZ_DBG_TIM1_STOP” (declared at line 11574)
#define DBGMCU_APB2_FZ_DBG_TIM1_STOP DBGMCU_APB1_FZ_DBG_TIM1_STOP
…\USER\stm32f4xx.h(11582): warning: #47-D: incompatible redefinition of macro “DBGMCU_APB2_FZ_DBG_TIM8_STOP” (declared at line 11575)
#define DBGMCU_APB2_FZ_DBG_TIM8_STOP DBGMCU_APB1_FZ_DBG_TIM8_STOP
…\USER\stm32f4xx.h(11583): warning: #47-D: incompatible redefinition of macro “DBGMCU_APB2_FZ_DBG_TIM9_STOP” (declared at line 11576)
#define DBGMCU_APB2_FZ_DBG_TIM9_STOP DBGMCU_APB1_FZ_DBG_TIM9_STOP
…\USER\stm32f4xx.h(11584): warning: #47-D: incompatible redefinition of macro “DBGMCU_APB2_FZ_DBG_TIM10_STOP” (declared at line 11577)
#define DBGMCU_APB2_FZ_DBG_TIM10_STOP DBGMCU_APB1_FZ_DBG_TIM10_STOP
…\USER\stm32f4xx.h(11585): warning: #47-D: incompatible redefinition of macro “DBGMCU_APB2_FZ_DBG_TIM11_STOP” (declared at line 11578)
#define DBGMCU_APB2_FZ_DBG_TIM11_STOP DBGMCU_APB1_FZ_DBG_TIM11_STOP
…\FWLIB\src\stm32f4xx_wwdg.c: 5 warnings, 0 errors
linking…
Program Size: Code=912 RO-data=424 RW-data=0 ZI-data=1632
FromELF: creating hex file…
“…\OBJ\Temptate.axf” - 0 Error(s), 220 Warning(s).
Build Time Elapsed: 00:02:04
编译完成后我们发现还有错误,用鼠标双击错误信息找到报错的地方

原因是重复定义了,算是官方bug,需要注释掉报错的代码:

之后再全局编译,出现了这个错误:.\Objects\YH-429.axf: Error: L6218E: Undefined symbol TimingDelay_Decrement (referred from stm32f4xx_it.o)

在中断的文件中将所圈的函数删掉即可,我们不需要使用这个函数,到后面我们使用中断时才需要在这里配置我们想要的。

总结一下:
- 先再本地新建一个文件夹用于存储固件库文件
- 在工程里面添加组,然后再里面添加文件
- 编译,会出现很多的错误,然后打开stm32f4xx.h
- 在工具链中的C/C++选项卡里面指定头文件的目录
- 在工具链中的C/C++选项卡里面添加两个宏:USE_STDPERIPH_DRIVER、STM32F429_439xx
- 把stm32f4xx_fsmc.c屏蔽掉,不编译
- 修改stm32f4xx_it.c文件,去掉#include ”main.h“以及在中断函数下面的一个子函数。
- 配置仿真器,而且这个配置不是一次配置成功之后就不会变,有时候会莫名其妙地改变。
- 配置好输出的文件,如Output、Listing,指定好生成文件后生成在哪个文件,我们最开始也已经配置好了。

浙公网安备 33010602011771号