先确认:本篇教的是哪一套工作流
原文以 Keil MDK 5.23、STM32F407IGT6、STM32F4 标准外设库 为例。它的目标不是讲所有 STM32 工程方式,而是建立一个可复用的 MDK 工程模板:有清晰的目录、启动文件、标准外设库、用户代码与编译配置。请先确认你的芯片系列、IDE 版本和库类型;不同 MCU 系列、HAL/CubeMX 工程或 Keil MDK v6 的界面和文件结构不应机械照搬。
版本校正。原文中的 MDK 5.23 属于历史版本。Keil 官方下载页当前列出的 MDK-Arm 版本为 5.43a(页面标注 2025 年 8 月);官方同时提供 MDK v6 产品线。因此,本文保留原文截图来解释操作概念,但下载时应以官方产品页显示的当前版本、许可与系统要求为准。[1]
| 你需要准备 | 本文中的对应位置 | 确认方式 |
|---|---|---|
| Windows 电脑与管理员权限 | MDK 安装 | 确保有可写入的英文目录,例如 D:\Keil_v5。 |
| 正确的目标芯片型号 | 选择 Device / 安装 DFP | 以芯片丝印、开发板原理图或项目规格为准;示例是 STM32F407IGT6。 |
| 对应 DFP 芯片包 | Pack 安装 | 在 Keil CMSIS-Pack 目录检索厂商与系列,而不是只搜索“STM32F4”。[2] |
| 固件库或现有项目文件 | 工程创建 | 原文采用 STSW-STM32065 标准外设库;其为旧式 StdPeriph 工作流。[3] |
下载 MDK 与芯片支持包
- 从官方 MDK 产品下载页开始。原文使用
keil.com/update/rvmdk.asp并展示 5.23 页面;现在优先访问 Keil 的产品下载页,选择 MDK-Arm,再按页面说明取得当前安装程序。[1] - 不要靠修改文件名猜版本。原文曾给出通过替换
MDK523文件名下载其他版本的做法。这种方式不应再作为推荐路径,因为文件命名、许可和可用版本均可能变化;如需历史版本,应按官方“Previous Versions”与许可要求操作。 - 安装 DFP 前先查芯片。CMSIS-Pack 是为 CMSIS 工具(含 Keil MDK)提供软件组件、设备驱动与中间件的分发格式。进入官方 Pack 目录后,按厂商、系列和设备筛选;示例需 STM32F4xx DFP。[2]
- 下载来源保持可追溯。若继续使用标准外设库,请通过 ST 的 STSW-STM32065 产品页取得;该页说明其为 STM32F4 DSP 与标准外设库,并提供不同 IDE 的模板项目。[3]


安装 MDK:逐屏确认,不跳步
原文的安装界面来自 MDK 5.23,因此文字与按钮位置可能随版本轻微变化,但流程仍是“启动安装程序 → 接受许可 → 选安装目录 → 填写信息 → 完成安装”。
- 启动来自官方来源的安装程序。下载完成后先核对文件来源和签名;Keil 官方建议从仅含安装程序的可信目录运行安装程序,以降低篡改风险。[1]
- 阅读并接受许可协议。只有接受适用许可后才能继续。是否为 Lite/Evaluation、是否需要许可证,由当前下载页和许可说明决定。[1]
- 选择全英文、无空格歧义的安装目录。原文示例为
D:\Keil_V5。不要与已有 Keil4/旧 Keil 目录混用,以免包、配置或工具链相互覆盖。 - 填写用户信息后等待安装完成。原文允许填写 First name 与 E-mail;实际页面以当前版本为准。安装期间若安全软件阻止可信安装程序,请先查看拦截记录和官方签名,不建议为了安装而长期关闭整机防护。
- 安装后再安装 DFP。双击目标
.pack文件或使用 Pack Installer;必须让 DFP 与目标 MCU 系列匹配。原文的Keil.STM32F4xx_DFP.1.0.8.pack只是历史示例。
原文“关闭防病毒软件”的安全注释。原文把关闭防病毒软件列为安装条件。更稳妥的做法是:只从官方站点取得安装包;在可信目录运行;若发生拦截,先检查证书、哈希或安全日志,并仅在确认可信且有必要时按组织安全政策处理例外。不要因安装 IDE 而永久关闭防护。



先建目录,再在 Keil 中创建工程
原文的关键经验是将磁盘目录和Keil 内部 Group对齐。下面的五个目录不是 Keil 强制规定,而是为了让启动文件、库文件、外设驱动和应用代码有稳定位置。
| 目录 | 原文用途 | 创建工程时的操作重点 |
|---|---|---|
CMSIS | 启动文件、核心头文件、system_stm32f4xx.c 等。 | 后续把 system_stm32f4xx.c 与启动汇编文件导入对应 Group。 |
FWLIB | 标准外设库的 inc 和 src。 | 将 src 中需要的 C 文件加入工程;头文件路径指向 FWLIB\inc。 |
HARDWARE | 板级外设驱动,例如 LED、按键。 | 后续按模块建立并导入。 |
SYSTEM | 延时、串口等系统函数。 | 后续按模块建立并导入。 |
USER | .uvprojx、main.c、中断文件与用户层代码。 | 新建工程时把工程文件保存到该目录。 |
- 在磁盘创建工程根目录及五个子目录。原文示例名称为“STM32F4xx 库函数工程模板”;你可以改名,但保持目录语义一致。
- 在 Keil 执行 Project → New uVision Project。若已有项目,先 Project → Close Project;随后进入
USER目录,以Test为例保存工程。 - 在 Device 选择具体芯片,而非只选择系列。原文路径是 STMicroelectronics → STM32F4 Series → STM32F407 → STM32F407IG。若看不到系列,优先检查 DFP 是否安装成功。
- Software Component 页面可暂不改动。原文示例直接取消该页面,随后采用自己准备的标准外设库文件。

拷贝文件只是准备;“导入工程”才会参与编译
这是原文最容易被初学者漏掉的分界线:把文件复制到磁盘并不会自动编译。必须在 Keil 的 Manage Project Items 中创建 Group,并使用 Add Files… 将需要编译的源文件加入对应 Group。
- 从标准外设库拷贝 CMSIS 文件。原文列出
core_cm4.h、core_cmFunc.h、core_cmInstr.h、core_cmSimd.h、startup_stm32f40_41xxx.s、stm32f4xx.h、system_stm32f4xx.c与system_stm32f4xx.h。复制时保留文件名与层级。 - 拷贝 FWLIB 的
inc与src。原文建议将标准外设驱动目录的两个子目录完整拷贝到FWLIB。 - 拷贝 USER 文件。将
stm32f4xx_it.c、stm32f4xx_it.h、stm32f4xx_conf.h放入USER;稍后创建main.c。 - 创建同名 Group。打开
Test.uvprojx,右键 Target1 → Manage Project Items;新建 CMSIS、FWLIB、HARDWARE、SYSTEM、USER 五个组。 - 按 Group 添加文件。CMSIS 组至少加入
system_stm32f4xx.c与启动汇编;FWLIB 组加入所需src文件;USER 组加入stm32f4xx_it.c与后续的main.c。添加后必须点 OK 保存。
为什么要删 stm32f4xx_fmc.c?原文指出 STM32F407 只支持 FSMC,不适用面向 STM32F42/F43 的 FMC 文件,因此示例工程应删除 stm32f4xx_fmc.c,但不要误删 stm32f4xx_fsmc.c。这是一条与具体芯片相关的处理规则:换芯片前先查数据手册与库文件说明。


创建 main.c、设置 Include Paths 与全局宏
- 新建并保存
main.c。通过 File → New 创建,再保存到USER文件夹;之后把它添加到 USER Group。 - 设置头文件搜索路径。在 Options for Target → C/C++ → Include Paths 中逐项添加相对路径:
..\CMSIS、..\FWLIB\inc、..\HARDWARE、..\SYSTEM、..\USER。原文特别提醒:包含路径不会自动递归子目录,因此FWLIB必须具体写到inc。 - 设置预处理宏。原文在 Define 中填写
STM32F40_41xxx,USE_STDPERIPH_DRIVER;两项由逗号分隔。宏名必须与你的芯片系列、所用库和头文件配置一致。 - 先用 Build,再根据需要用 Rebuild。Build 主要编译修改过的文件及依赖,Rebuild 强制重新编译全部源文件。首次完成配置、修改库文件或遇到缓存疑问时,Rebuild 更有助于排除旧对象文件影响。
#include "stm32f4xx.h"
void GPIO_Config(void) {
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
}
int main(void) {
int i;
GPIO_Config();
while (1) {
GPIO_ToggleBits(GPIOB, GPIO_Pin_13);
for (i = 0; i < 50000000; i++);
}
}
上方代码与原文代码段 2.2.1 一致地用于 GPIOB Pin13 翻转演示。它只是编译与引脚初始化的最小示例;是否真的驱动 LED 还取决于开发板原理图、LED 极性和 Pin13 是否接到目标外设。

STM32F40_41xxx,USE_STDPERIPH_DRIVER 宏。原文已给出的三类典型错误
| 现象 | 原文处理 | 先检查什么 |
|---|---|---|
| Device 列表没有 STM32F4 Series | 安装对应 STM32F4xx DFP。 | 确认 Pack 安装成功;确认芯片型号与所下载 DFP 匹配。 |
main.h: No such file or directory | 在 USER 中新建 main.h,或在 stm32f4xx_it.c 中删除/注释 #include "main.h"。 | 优先确认该 include 是否真的需要;若需要,就创建正确声明的头文件,避免只为消错而随意删除业务依赖。 |
TimingDelay_Decrement(); 引发后续错误 | 原文建议定位后注释或删除。 | 先判断项目是否真的使用 SysTick 延时逻辑;如果需要,应补充正确的函数实现,而不是直接移除关键时基。 |
| 编译包含不支持的 FMC 文件 | 对 STM32F407 删除 stm32f4xx_fmc.c,保留 stm32f4xx_fsmc.c。 | 查具体芯片数据手册与标准库支持范围。 |

main.h 错误定位与处理提示。原文完整分页影印:23 页不删减保留
以下 23 张页面图按用户提供 PDF 的原始顺序渲染。正文的所有步骤、文件清单、路径、代码、图号和界面截图均可在此回查;正文中的“版本校正”和“安全注释”是新增说明,不会替代或篡改原始内容。
展开查看原文第 16–23 页:下载、DFP 与安装








展开查看原文第 24–31 页:工程目录、芯片选择与文件导入








展开查看原文第 32–38 页:main.c、路径、宏定义与编译排错







参考来源与说明
[0] 用户提供文件:《keil5下载教程.pdf》,第 2 章“嵌入式开发与调试”,原始页码 16–38。本页的分页图由该 PDF 逐页渲染。
[1] Keil 官方产品下载页:MDK-Arm 当前下载信息、许可与历史版本说明。
[2] Arm Keil CMSIS Packs:CMSIS-Pack 的用途以及设备、驱动和中间件包目录。
[3] STSW-STM32065:STM32F4 DSP 与标准外设库的官方产品说明、模板项目与下载条件。