一、前期准备
1.安装好keil
Keil(MDK) 5 软件安装教程-CSDN博客https://blog.csdn.net/qq_42748213/article/details/90485750
2.安装好STM32F4的芯片包
3.下载好STM32CubeF4固件包(本文STM32Cube_FW_F4_V1.28.0)
二、工程文件移植
1.建立初步的工程文件夹
以STM32F429芯片、STM32Cube_FW_F4_V1.28.0固件包为例:
新建一个“STM32F429_HAL_V1.28.0_Project_20250312”的文件夹,进入文件夹,分别新建如下文件夹:
每个文件夹名称及其作用如表所示:
名称 | 作用 |
Drivers | 存放与硬件相关的驱动层文件 |
Middlewares | 存放正点原子提供的中间层组件文件和第三方中间层文件 |
Output | 存放工程编译输出文件 |
Projects | 存放 MDK 工程文件 |
User | 存放 HAL 库用户配置文件、 main. |
工程根文件目录下还有一个名为 keilkill.bat 的可执行文件,双击便可执行。其作用是删除编译器编译后的无关文件,减少工程占用的内存,方便打包。(相关文件在 五、附录(完整工程)里面有下载链接)
2. 建立和拷贝工程相关文件
2.1 Drivers文件夹详解
下面是已经移植好的Drivers文件夹,其中前3个是直接在STM32CubeF4固件包里面拷贝过来的,最后一个“SYSTEM”文件夹是另外新建的,用于存放系统级核心驱动代码,如 sys.c、 delay.c 和 usart.c。
该文件夹用于存放与硬件相关的驱动层文件,每个文件夹名称及其作用如表所示:
文件夹名称 | 作用 |
BSP | 存放开发板板级支持包驱动代码,如各种外设驱动 |
CMSIS | 存放 CMSIS 底层代码,如启动文件(.s 文件)、 stm32f4xx.h 等 |
STM32F4xx_HAL_Driver | 存放 HAL 库驱动代码源文件 |
SYSTEM | 存放正点原子系统级核心驱动代码,如 sys.c、 delay.c 和 usart.c |
找到我们刚才下载好的STM32CubeF4固件包,解压并打开我们发现里面也有一个Drivers文件夹:
打开Drivers文件夹,里面就是我们移植所需要的核心文件:
为方便,我们先把上面这些STM32Cube文件夹全部拷贝到我们新建的STM32F429_HAL_V1.28.0_Project_20250312工程文件夹里面的Drivers文件夹下,便得到了一个初步移植好的Drivers文件夹:
2.2 CMSIS文件夹移植和裁剪
进入到我们拷贝好的CMSIS文件夹下,对CMSIS文件夹进行裁剪,只保留 Device 和 Include 2个文件夹:
进入裁剪后留下的Include文件夹,对Include里面的头文件进行裁剪,只保留以下6个必要的头文件:
进入我们工程的CMSIS文件夹下的Device 文件夹,一直进入文件夹,直到打开STM32F4xx文件夹,对STM32F4xx文件夹进行裁剪,只保留 Include 和 Source 文件夹:
裁剪完STM32F4xx文件夹后,进一步进入STM32F4xx文件夹下的Include 文件夹,根据自己实际使用到的芯片进行裁剪头文件,我使用的是STM32F429,所以我保留以下3个头文件:
备注:第一个和第三个头文件是F4必要的,第二个头文件是根据你使用的芯片具体选择
进入STM32F4xx文件夹下的 Source 文件夹,一直进去,直到进入到 Templates 文件夹,保留以下2个文件:
进入到 Templates 文件夹下保留的 arm 文件夹,里面是STM32的启动文件,我们根据自己的芯片选择保留对应的文件即可,我使用的是STM32F429,所以我保留startup_stm32f429xx.s:
2.3 STM32F4xx_HAL_Driver 驱动代码移植裁剪
进入我们新建的工程里面拷贝好的的Drivers文件夹下的STM32F4xx_HAL_Driver文件夹,对其进行裁剪,只保留 Inc 和 Src 文件夹:
2.4 SYSTEM文件夹系统级核心驱动代码移植(可以先跳过该步骤)
这里我们便要致敬一下正点原子的杰出贡献:STM32 HAL 库 的 sys、 delay 和usart驱动代码:
注意:(相关文件在 五、附录(完整工程)里面有下载链接)
2.5 User文件夹驱动代码移植
User 文件夹用于存放 HAL 库用户配置文件、 main.c 文件以及中断处理文件,这些文件我们可以在我们下载的STM32Cube_FW_F4_V1.28.0 HAL固件包里面拷贝,打开STM32Cube_FW_F4_V1.28.0\Projects\STM32F429I-Discovery\Templates,里面就有Inc 和 Src 2个文件夹:
直接把这 Inc 和 Src 2个文件夹拷贝到到我们自己新建的工程的 User 文件夹里:
三、建立STM32F4 的Keil工程
1.建立keil工程框架
首先,打开 MDK 软件。然后点击 Project→New uVision Project 如图:
然后弹出工程命名和保存的操作窗口,我们将工程文件保存路径设置在上一节 工程文件移植 步骤中新建的工程文件夹的Projects文件夹内,并取名:STM32F429IGT6 ,然后保存。
之后,弹出器件选择对话框,如图所示。
因为我使用的STM32 型 号 为 STM32F429IGT6,所 以 我 选 择 : STMicroelectronics→STM32F4 Series→STM32F429→STM32F429IGTx
备注:如果使用的是其他系列的芯片,选择相应的型号就可以了,特别注意: 一定要安装对应的器件 pack 才会显示这些内容哦!!(文章第一章里面的芯片包安装)
点击 OK, MDK 会弹出 Manage Run-Time Environment 对话框,直接关闭即可:

2.清理keil工程框架自动生成的个别文件夹
我们打开我们的工程里面的Projects文件夹,会看到 MDK 在该文件夹下自动创建了 3 个文件夹(DebugConfig、 Listings 和 Objects),如图所示:
这三个文件夹的作用如表所示:
文件夹 | 作用 |
DebugConfig | 用于存放调试设置信息文件(.dbgconf),不可删除! |
Listings | 用于存放编译过程产生的链接列表等文件 |
Objects | 用于存放编译过程产生的调试信息、 .hex、预览、 .lib 文件等 |
编译过程产生的链接列表、调试信息、预览、 lib 等文件,统称为中间文件。为了统一管理,方便使用,我们会把输出在 Listings 和 Objects 文件夹的内容,统一改为输出到 Output 文件夹(通过魔术棒设置),我们先把 MDK 自动生成的这两个文件夹(Listings 和 Objects)删除。
至此,我们还只是建了一个框架,还有好几个步骤要做,比如添加文件、魔术棒设置、编写 main.c 等。
3.添加必要文件到keil工程框架
3.1 设置工程名和分组名
在 Project→Target 上右键,选择 Manage Project Items…(方法一)或在菜单栏点击品字形红绿白图标(方法二)进入工程管理界面,如图所示:
在工程管理界面,我们可以执行设置工程名字(Project Targets)、分组名字(Groups)以及添加每个分组的文件( Files)等操作。我们设置工程名字为: Template,并设置四个分组: Startup(存放启动文件)、 User(存放 main.c等用户代码)、 Drivers/SYSTEM(存放系统级驱动代码)、 Drivers /STM32F4xx_HAL_Driver(存放 HAL 库代码)、 Doc(存放工程说明文件),如图 所示:
设置好之后,我们点击 OK,回到 MDK 主界面,可以看到我们设置的工程名和分组名如图所示:
注意:为了让工程结构清晰,我们会尽量让 MDK 的工程分组和我们前面新建的工程文件夹对应起来,由于 MDK 分组不支持多级目录,因此我们将路径也带入分组命名里面,以便区分。如: User分组对应 User文件夹里面的源码, Drivers/SYSTEM分组,对应 Drivers/SYSTEM文件夹里面的源码, Drivers/BSP 分组对应 Drivers/BSP 文件夹里面的源码等。
3.2 添加启动文件
启动文件(.s 文件)包含 STM32 的启动代码,其主要作用包括: 1、堆栈(SP)的初始化; 2、初始化程序计数器(PC); 3、设置向量表异常事件的入口地址; 4、调用 main 函数等,是每个工程必不可少的一个文件。启动文件由 ST 官方提供, 存放在 STM32CubeF4 软件包的: Drivers→CMSIS→Device →ST→STM32F4xx→Source→Templates→arm 文 件 夹 下 。 因 为我使用的是STM32F429IGT6,对应的启动文件为: startup_stm32f429xx.s,为了节省空间,在精简版 CMSIS文件夹里面我们把其他启动文件都删了。
方法一:
上图中,我们也可以点击 Add 按钮进行文件添加。添加完后,点击 Close,完成启动文件添加,得到工程分组如图所示:
3.3 添加STM32F4xx_HAL_Driver里面的HAL库文件
接下来我们往 Drivers/STM32F4xx_HAL_Driver 分组里添加文件。点击: 按钮,进入工程管理界面,选中 Drivers/STM32F4xx_HAL_Driver 分组,然后点击: Add Files,进入文件添加 对 话 框 , 依 次 添 加 stm32f4xx_hal.c 、 stm32f4xx_hal_cortex.c 、 stm32f4xx_hal_dma.c 、stm32f4xx_hal_gpio.c、 stm32f4xx_hal_pwr.c、 stm32f4xx_hal_pwr_ex.c、stm32f4xx_hal_rcc.c、stm32f4xx_hal_rcc_ex.c 、 stm32f4xx_hal_uart.c 和stm32f4xx_hal_usart.c 到该分组下,如图:
方法二:
添加完成后,如图所示:
3.4 添加SYSTEM系统级核心文件(可以先跳过该步骤)
这些文件由正点原子提供,文章前面提到过的,依葫芦画瓢把些文件添加到SYSTEM组:
3.5 添加User用户文件
打开工程文件夹里面的User文件夹,之前已经拷贝好了对应的头文件Inc和源码Src文件:
进入Src文件夹,只保留下面2个文件:main.c 和 stm32f4xx_it.c
依葫芦画瓢按照前面的方法,把这2个文件添加到User组:
最后,还有一个system_stm32f4xx.c文件需要添加到User组,该文件在我们移植好的工程里面的Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates路径下:
到此,main.c、stm32f4xx_it.c 和 stm32f4xx_it.c 3个文件已添加到User组:
4.Keil工程魔术棒设置
为避免编写代码和编译报错,我们需要通过魔术棒对 MDK 工程进行相关设置。在 MDK主界面,点击: (魔术棒图标,即 Options for Target 按钮),进入工程设置对话框,我们将进行如下几个选项卡的设置。
4.1 选择AC5编译器
由于 AC5 对中文支持比较好,且兼容性相对好一点, 为了避免不必要的麻烦,我们推荐大家使用 AC5 编译器。
4.2 设置 Output 选项卡
在魔术棒→Output 选项卡里面,进行如图 设置:
注意,我们勾选: Browse Information,用于输出浏览信息,这样就可以使用 go to definition 查看函数/变量的定义,对我们后续调试代码比较有帮助,如果不需要调试代码,则可以去掉这个勾选,以提高编译速度。
4.3 设置 Listing 选项卡
在魔术棒→Listing 选项卡里面,进行如图设置:
经过 Output 和 Listing 这两步设置,原来存储在 Objects 和 Listings 文件夹的内容(中间文件)就都改为输出到 Output 文件夹了。
4.4 设置 C/C++选项卡
在魔术棒→C/C++选项卡里面,进行如图所示设置:
上图中我们设置了 5 个头文件包含路径,其中 4 个在 Drivers 文件夹下,一个在 User 文件夹下。为避免频繁设置头文件包含路径,正点原子最新源码的 include 全部使用相对路径,也就是我们只需要在头文件包含路径里面指定一个文件夹,那么该文件夹下的其他文件夹里面的源码,如果全部是使用相对路径,则无需再设置头文件包含路径了,直接在 include 里面就指明了头文件所在。
备注:为了开启HAL库,还需要定义USE_HAL_DRIVER宏,使用"," 隔开:
通过查找该宏,我们可以发现,其实就是通过宏开启包含了个F4 HAL库的头文件!如图:
备注:关于芯片宏的获取,我们可以查看stm32f4xx_hal.h ,您需要根据自己选用的芯片查看获取对应的宏:
4.5 设置 Debug 选项卡
根据你使用的下载器选择,我使用的是ST-LINK:
四、编译验证工程
点击编译,编译完成如果是 0 Error(s), 0 Warning(s) ,那工程就是就是移植成功了!
五、附录(完整工程)
1. 正点原子STM32F4 的 HAL 库系统级核心驱动代码( sys、 delay 和usart驱动代码)
2. STM32F429 HAL库 精简版 Keil 5 工程(大小只有11.5M)
备注:如果出现STM32F4串口输出乱码,如图:
产生原因:HAL库晶振频率定义与实际板子用的晶振频率不一致(STM32F4 HAL库默认是8M)
HSE_VALUE这个宏具体在哪个文件可能根据不同的HAL库版本有所不一样,最好自己通过搜索查找HSE_VALUE在哪里定义的
解决办法:把晶振改为您板子实际用的晶振频率。(我的板子用的25M,所以我改为了25M)