第3章 开发环境搭建:Keil MDK安装与配置、STM32CubeMX初始化工程、J-Link调试器连接与测试
好,咱们正式开始动手了。这一章我带你搭好开发环境。说实话,环境搭建这事儿看着简单,但坑不少。我见过太多新手卡在这一步,一卡就是半天。咱们一步步来,稳一点。
3.1 Keil MDK安装与配置
Keil MDK,说白了就是咱们写代码、编译、下载、调试的一站式工具。我个人习惯用MDK 5.38版本,太新的版本有时候兼容性反而不好。
3.1.1 安装步骤
- 下载安装包:去Keil官网下载MDK-ARM。注意别下成C51了,那是给51单片机用的。
- 运行安装程序:一路Next就行。但我建议你改一下安装路径,别放C盘。我习惯放D:\Keil_v5。
- 安装器件支持包:这一步很多人会忘。装完MDK后,还得装你用的芯片的Pack。咱们用STM32F103,那就装Keil.STM32F1xx_DFP。
- 破解:嗯,这个你懂的。用注册机生成License,填进去就行。注意要以管理员身份运行Keil。
注意:破解时一定要关闭杀毒软件。我遇到过好几次,注册机被当成病毒直接删了。还有,License填完后重启一下Keil,不然可能不生效。
3.1.2 工程配置要点
装好后,咱们创建一个新工程试试。打开Keil,Project -> New uVision Project。选好芯片型号,我这里选STM32F103C8。
然后会弹出一个Manage Run-Time Environment的窗口。这里我建议你只勾选最基础的组件,别一股脑全选上。咱们做Bootloader,用不到那么多外设库。
我的习惯配置:
- CMSIS - CORE:必选
- Device - Startup:必选
- Device - StdPeriph Drivers:按需选,我一般只选GPIO、USART、Flash
3.1.3 编译器设置
工程建好后,点那个魔术棒图标(Options for Target)。这里有几个关键设置:
| 设置项 | 推荐值 | 说明 |
|---|---|---|
| Target - ARM Compiler | V5.06 update 7 (build 750) | V6编译器优化太激进,容易出问题 |
| Output - Select Folder for Objects | .\Objects | 编译中间文件放这里,好管理 |
| Listing - Select Folder for Listings | .\Listings | 列表文件,调试时有用 |
| C/C++ - Optimize | Level 0 (-O0) | 调试阶段别开优化,不然单步执行会跳来跳去 |
我曾经在调试一个Bootloader的Flash写入函数时,开了-O2优化。结果单步执行时,代码顺序全乱了,根本看不出问题在哪。后来关了优化,一下子就定位到了bug。所以调试阶段,老老实实用-O0。
3.2 STM32CubeMX初始化工程
Keil装好了,接下来咱们用STM32CubeMX生成一个基础工程。这个工具能帮我们省去很多寄存器配置的麻烦。
3.2.1 新建项目
- 打开STM32CubeMX,点击New Project。
- 在Board Selector里搜STM32F103C8,或者直接在MCU Selector里选。
- 选好后,系统会问你要不要初始化所有外设。点Yes,但后面我们会删掉不需要的。
3.2.2 配置时钟树
时钟配置是重中之重。Bootloader对时序要求很严格,尤其是Flash操作。
我一般这样配:
- HSE:8MHz外部晶振
- PLL:9倍频,得到72MHz主频
- APB1:36MHz(不能超过36MHz)
- APB2:72MHz
小技巧:配置时钟时,CubeMX会实时显示当前频率。如果某个总线超频了,它会变红提示你。别硬着头皮点确定,先看看哪里配错了。
3.2.3 配置GPIO
咱们的Bootloader需要几个基本引脚:
- USART1_TX (PA9):输出
- USART1_RX (PA10):输入
- Bootloader状态指示LED:随便选一个GPIO,比如PC13,推挽输出
在Pinout & Configuration里,找到USART1,Mode选Asynchronous。然后去GPIO标签页,把PA9和PA10的上下拉都设成No pull-up/pull-down。为什么?因为USART协议本身有起始位和停止位,不需要额外的上下拉。
3.2.4 生成代码
配置完成后,点Project -> Generate Code。这里要注意:
- Toolchain / IDE选MDK-ARM V5
- Firmware Package选你之前下载的版本
- 勾选Generate peripheral initialization as a pair of .c/.h files per peripheral
生成后,用Keil打开工程。你会看到CubeMX帮你生成了main.c、stm32f1xx_it.c等文件。别急着改,先编译一下,确保0 error 0 warning。
注意:CubeMX生成的代码里,HAL_Init()和SystemClock_Config()是自动调用的。但MX_USART1_UART_Init()需要你自己在main函数里调用。很多人忘了这步,结果串口死活不通。
3.3 J-Link调试器连接与测试
环境搭好了,代码生成了,接下来就是连上硬件,看看能不能跑起来。
3.3.1 硬件连接
J-Link和STM32开发板的连接很简单:
| J-Link引脚 | STM32引脚 | 说明 |
|---|---|---|
| VTref | 3.3V | 目标板供电检测 |
| GND | GND | 共地 |
| SWDIO | PA13 (SWDIO) | 数据线 |
| SWCLK | PA14 (SWCLK) | 时钟线 |
我建议你用杜邦线连接,别焊死了。调试阶段经常要换板子,焊死了很麻烦。
3.3.2 Keil中配置调试器
回到Keil,点魔术棒 -> Debug标签页:
- Use选择J-LINK / J-TRACE Cortex
- 点Settings,进入Cortex JLink/JTrace Target Driver Setup
- Port选SW(不是JTAG,SWD只需要两根线)
- Max Clock选4MHz(别选太高,容易不稳定)
然后点Flash Download标签页:
- 勾选Reset and Run
- Programming Algorithm选STM32F10x Med-density Flash
关键一步:点Settings里的Auto Cllk,让Keil自动检测J-Link的时钟。我遇到过手动设成10MHz,结果调试器死活连不上。后来改成Auto,一切正常。
3.3.3 测试连接
配置好后,点Debug -> Start/Stop Debug Session。如果一切正常,你会看到:
- J-Link指示灯变绿
- Keil进入调试界面
- 代码停在main函数的开头
如果连不上,别慌。检查这几样:
- 开发板供电了吗?J-Link的VTref引脚有没有3.3V?
- SWDIO和SWCLK有没有接反?
- J-Link驱动装了吗?去SEGGER官网下个J-Link Software Pack。
我曾经有一次,折腾了半小时连不上。最后发现是J-Link的USB线接触不良。换了一根线,秒连。所以有时候问题不在软件,就在这些不起眼的硬件上。
3.3.4 简单测试程序
连上后,咱们写个简单的程序测试一下。在main函数里加几行:
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
while (1)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_Delay(500);
}
编译下载,如果看到板子上的LED以0.5秒间隔闪烁,说明环境搭建成功了。串口的话,用串口助手连上,发个数据看看能不能收到回显。
我的经验:第一次调试时,别急着跑复杂的Bootloader代码。先让LED闪起来,让串口发个"Hello World"。确认硬件链路没问题了,再往上加功能。这样出了问题,你能快速定位是硬件问题还是软件问题。
好,环境搭好了。下一章咱们开始写真正的Bootloader代码。到时候你会发现,环境搭得越稳,后面写代码越顺。