Keil MDK V5 完整教程:从零开始学 ARM 开发
目录
-
第一部分:准备工作
(图片来源网络,侵删)- 1 什么是 Keil MDK?
- 2 为什么选择 Keil MDK?
- 3 环境搭建:安装 Keil MDK
- 4 安装芯片支持包
- 5 连接硬件:J-Link / ST-Link 驱动安装
-
第二部分:第一个项目 - 点亮一个 LED (Blinky)
- 1 创建新项目
- 2 选择目标芯片
- 3 添加启动文件
- 4 添加用户代码文件
- 5 编译和配置工程选项
- 6 下载程序到开发板
- 7 调试程序
-
第三部分:核心功能详解
- 1 工程窗口详解
- 2 代码编辑器
- 3 编译系统
- 4 调试器
- 5 Peripherals 视图与寄存器查看
-
第四部分:进阶技巧与最佳实践
- 1 使用
#include和头文件 - 2 配置系统时钟 (System Clock)
- 3 使用
printf重定向到串口 - 4 使用 RTX 实时操作系统
- 5 版本控制集成
- 1 使用
-
第五部分:常见问题与资源
(图片来源网络,侵删)
第一部分:准备工作
1 什么是 Keil MDK?
Keil MDK(以前称为 Keil uVision)是 ARM 公司推出的官方集成开发环境,它是一个功能强大的软件套件,专门用于基于 ARM Cortex-M, Cortex-R 和经典 ARM7/9 内核的微控制器的软件开发,MDK 包含了:
- IDE (集成开发环境):代码编辑器、项目管理器。
- ARMCC/ARMCLANG 编译器:将 C/C++ 和汇编代码编译成机器码。
- uVision 调试器:强大的硬件调试功能,支持断点、单步执行、变量监视等。
- RTX 实时操作系统:一个免费、小巧的 RTOS。
- 中间件:如 TCP/IP 网络协议栈、文件系统、USB 堆栈等。
- 设备支持包:针对不同厂商(如 ST, NXP, TI)芯片的底层驱动和配置文件。
2 为什么选择 Keil MDK?
- 官方支持:ARM 官方出品,对 ARM 内核的支持最完善、最稳定。
- 功能全面:从编码、编译、链接到调试,一站式完成。
- 生态成熟:拥有最广泛的用户群体和最多的教程、例程和社区支持。
- 易于上手:图形化界面直观,尤其适合初学者。
3 环境搭建:安装 Keil MDK
- 下载:访问 Keil 官网,下载最新版的 MDK 安装包,通常需要注册一个免费账号。
- 安装:双击安装包,按照向导提示进行安装,建议安装在默认路径,路径中不要包含中文或空格。
- 首次启动:安装完成后首次启动,会要求你进行产品注册,选择 "Pack Installer" 模式可以免费使用,但有 32KB 的代码限制,对于学习和大多数项目来说,这已经足够了,如果需要去除限制,可以购买授权。
4 安装芯片支持包
Keil MDK 的核心是 Pack 机制,Pack 包含了特定芯片的所有信息:数据手册、参考手册、启动文件、设备外设驱动库、示例代码等。
- 启动 Keil MDK。
- 点击工具栏上的 "Pack Installer" 图标(像一个带芯片的盒子)。
- 在左侧的 "Devices" 树中,找到你的芯片厂商(如 STMicroelectronics)。
- 在展开的列表中,找到你具体使用的芯片型号(如
STM32F103C8T6)。 - 点击右侧的 "Install" 按钮,等待安装完成。这一步至关重要!
5 连接硬件:J-Link / ST-Link 驱动安装
要将程序下载到开发板,你需要一个调试器,如 J-Link 或 ST-Link。
- ST-Link:如果你使用的是 STM32 官方或兼容的开发板(如 Blue Pill),通常会自带 ST-Link,Windows 10/11 通常能自动识别并安装驱动,如果没有,可以从 ST 官网下载 "STM32CubeMX" 或独立的 "STSW-LINK009" 驱动。
- J-Link:如果你使用的是 J-Link 调试器,需要从 Segger 官网 下载并安装最新的 J-Link 驱动和软件包。
安装完成后,将开发板通过 USB 连接到电脑,打开设备管理器,在 "通用串行总线设备" 下应该能看到你的调试器(如 "STLink Virtual COM Port" 或 "J-Link")。
第二部分:第一个项目 - 点亮一个 LED (Blinky)
我们将以一个经典的 "Hello World" 级别的项目——点亮一个 LED,来熟悉 Keil MDK 的基本操作,这里以 STM32F103C8T6 为例。
1 创建新项目
- 打开 Keil MDK。
- 点击菜单
Project -> New uVision Project...。 - 选择一个空文件夹作为你的项目存放地,输入项目名(如
Blinky),然后点击Save。
2 选择目标芯片
- 保存后,会弹出 "Select Device for Target" 对话框。
- 在左上角的搜索框中输入你的芯片型号(如
STM32F103C8)。 - 从列表中选择
STMicroelectronics -> STM32F1 Series -> STM32F103 -> STM32F103C8。 - 点击
OK。
3 添加启动文件
- 选择芯片后,会弹出 "Manage Run-Time Environment" 窗口,这里让你选择需要运行时组件。
- 展开
CMSIS -> CORE,勾选Startup,这会添加启动文件startup_stm32f10x_md.s(md代表中等容量,根据你的 Flash 选择)。 - 点击
OK,在左侧的 "Project" 窗口中,你会看到Startup文件夹和其中的启动文件。
4 添加用户代码文件
- 在 "Project" 窗口中,右键点击
Source Group 1,选择Add New Item to Group 'Source Group 1'...。 - 选择 "C File (.c)",输入文件名
main.c,点击Add。 - 再次右键点击
Source Group 1,选择Add New Item to Group 'Source Group 1'...。 - 选择 "C Header File (.h)",输入文件名
stm32f10x.h,点击Add,这个头文件通常由 Pack 自动提供,你也可以手动添加一个。 - 在
main.c中,输入以下代码:
#include "stm32f10x.h" // 包含 STM32F10x 的头文件
// 简单的延时函数
void delay(volatile uint32_t count) {
while(count--);
}
int main(void) {
// 1. 使能 GPIOC 的时钟
RCC->APB2ENR |= (1 << 4); // APB2ENR 寄存器的第 4 位对应 GPIOC
// 2. 配置 PC13 为推挽输出模式
GPIOC->CRH &= ~(0xF << 20); // 清除 PC13 的原有配置 (4 bits)
GPIOC->CRH |= (3 << 20); // 设置为推挽输出模式 (最大速度 50MHz)
while (1) {
// 3. 点亮 LED (PC13 输出低电平)
GPIOC->BSRR = (1 << 13); // 置位 BSRR 的低 16 位,对应引脚输出低电平
delay(500000);
// 4. 熄灭 LED (PC13 输出高电平)
GPIOC->BSRR = (1 << (13 + 16)); // 置位 BSRR 的高 16 位,对应引脚输出高电平
delay(500000);
}
}
提示:上面的代码是直接操作寄存器的,在实际开发中,我们更推荐使用 ST 提供的标准外设库或 HAL 库,它们提供了更易读的 API,但为了理解底层原理,直接操作寄存器是最好的学习方式。
5 编译和配置工程选项
-
编译:点击工具栏上的 "Build" 按钮(一个锤子图标),如果一切顺利,底部的 "Build Output" 窗口会显示
0 Error(s), 0 Warning(s),这会在你的项目目录下生成一个.hex文件,这就是可以烧录到芯片的程序。 -
配置工程选项:
- 点击菜单
Project -> Options for Target...。 - Target 选项卡:
- Xtal:设置晶振频率,如
0MHz。
- Xtal:设置晶振频率,如
- **C/C++` 选项卡:
- Define:可以添加宏定义,如
USE_STDPERIPH_DRIVER。 - Include Paths:添加头文件路径,如果使用了标准外设库,需要在这里指定库的
inc文件夹路径。
- Define:可以添加宏定义,如
- **Debug` 选项卡:
- Use:选择
ULINK Pro / J-Link。 - Settings:点击进入,在
Flash Download选项卡中,勾选Reset and Run,这样每次下载程序后,芯片会自动复位并开始运行。
- Use:选择
- 点击菜单
6 下载程序到开发板
- 确保你的开发板已通过 J-Link/ST-Link 连接到电脑。
- 在 Keil MDK 中,点击工具栏上的 "Download" 按钮(一个向下的箭头)。
- 程序会被编译(如果需要)并下载到开发板的 Flash 中。
- 如果成功,LED 应该会开始闪烁!
7 调试程序
调试是开发中最重要的环节。
- 点击工具栏上的 "Start/Stop Debug Session" 按钮(一个虫子图标)。
- 程序会下载到芯片,并在
main函数的第一行暂停。 - 常用调试功能:
- F5 (Run):全速运行,直到遇到断点。
- F10 (Step Over):单步执行,将函数调用视为一条语句。
- F11 (Step Into):单步进入,如果遇到函数调用,会跳转到函数内部。
- Shift + F11 (Step Out):跳出当前函数。
- F9 (Toggle Breakpoint):在光标所在行设置/取消断点。
- 查看变量:
- 在代码中右键点击一个变量,选择 "Add 'var_name' to 'Watch#'"。
- 右侧的 "Watch" 窗口会实时显示该变量的值。
- 查看内存:
点击 "Memory" 标签页,可以查看指定内存地址的数据。
- 查看外设寄存器:
点击 "Peripherals" 标签页,可以以图形化方式查看 GPIO, UART, TIM 等外设的寄存器状态,非常直观!
第三部分:核心功能详解
1 工程窗口详解
- 文件标签:可以切换不同的编辑窗口。
- 项目窗口:
- Target 1:代表一个目标设备。
- Source Group 1, 2...:用于逻辑分组管理 C/C++ 和汇编文件。
- Groups:可以创建自定义的组,如
Drivers,Middlewares,Application,使项目结构更清晰。
2 代码编辑器
- 语法高亮:自动识别 C/C++ 关键字、注释等。
- 代码折叠:可以折叠/展开代码块。
- 代码提示:输入函数名或变量名时,会自动提示。
- 函数列表:点击左侧的
Structure标签,可以快速定位到某个函数。
3 编译系统
- Build Output:显示编译和链接的详细信息,包括错误和警告,双击错误信息,可以快速跳转到出错的代码行。
- 优化级别:在
Options for Target -> C/C++ -> Optimization中设置。O0(无优化,调试方便),O1/O2/O3(性能优化,发布版本使用)。
4 调试器
- 实时变量更新:在 Watch 窗口中,可以修改变量的值,实时观察程序行为。
- 逻辑分析仪:可以配置一些 GPIO 引脚,在调试时捕获其波形,帮助分析时序问题。
5 Peripherals 视图与寄存器查看
这是 Keil 的一个巨大优势,在调试模式下,Peripherals 窗口将所有外设(如 GPIO, USART, ADC, TIM)以树状结构列出,点击每个外设,下方会显示其所有寄存器的当前值,并允许你直接修改,这对于学习和调试外设配置非常有帮助。
第四部分:进阶技巧与最佳实践
1 使用 #include 和头文件
将代码按功能模块化,每个模块一个 .c 文件和一个 .h 文件。.h 文件中声明函数和宏,.c 文件中实现,其他文件通过 #include "xxx.h" 来使用。
2 配置系统时钟
系统时钟是 MCU 的心脏,直接配置 RCC 寄存器非常复杂,推荐使用 ST 提供的 SystemClock_Config() 函数,通常在 main.c 中调用,这个函数在 system_stm32f1xx.c 文件中定义,可以根据你的晶振和 PLL 配置生成。
3 使用 printf 重定向到串口
在调试时,通过串口打印信息是最高效的调试手段之一。
- 重定向
fputc:在main.c中添加以下代码:
#include <stdio.h>
// 重定向 printf 到串口
int fputc(int ch, FILE *f) {
// 假设你的串口发送函数是 USART_SendChar
USART_SendChar(ch);
return ch;
}
-
实现串口发送函数:你需要自己实现一个
USART_SendChar函数,它负责将一个字符通过 UART 发送出去。 -
在
Options for Target -> Debug -> Settings -> I/O中,勾选Serial并选择你的串口 COM 号。
4 使用 RTX 实时操作系统
MDK 自带了 RTX5 实时操作系统,你可以创建多个任务,让它们并发执行,这对于复杂的项目(如同时处理按键、显示、通信)非常有用,通过 Pack Installer 安装 RTX 后,Keil 会提供相应的例程。
5 版本控制集成
Keil MDK 内置了对 Git 版本控制的支持,在 Project -> Version Control 中可以初始化仓库、提交、查看历史等,方便团队协作和代码回溯。
第五部分:常见问题与资源
常见问题
- Q: 编译时提示 "access violation" 或 "L6218E" 错误?
A: 通常是工程路径或文件名中包含中文或空格导致,请确保所有路径和文件名都是英文。
- Q: 无法连接到 J-Link / ST-Link?
- A: 检查硬件连接是否牢固,驱动是否正确安装,在
Debug -> Settings -> Debug中尝试更换不同的算法。
- A: 检查硬件连接是否牢固,驱动是否正确安装,在
- Q: 程序下载后,行为与预期不符?
A: 1. 检查时钟配置是否正确,2. 检查 GPIO 引脚模式、速度是否正确,3. 使用调试器单步运行,观察变量和寄存器值的变化。
学习资源
- 官方资源:
- 教程与社区:
- Bilibili:有大量中文 Keil 教程,搜索 "Keil MDK 入门"、"STM32"。
- CSDN / 博客园:大量技术博客和项目分享。
- GitHub:搜索 "STM32 Keil Project",可以找到开源项目作为参考。
这份教程涵盖了 Keil MDK 的核心使用流程和技巧,最好的学习方式就是 动手实践,从点亮一个 LED 开始,逐步尝试更复杂的项目,你会很快掌握这个强大的开发工具,祝你学习愉快!
