第3章 开发环境搭建:Keil MDK安装与配置、STM32CubeMX初始化工程、J-Link调试器连接与测试

好,咱们正式开始动手了。这一章我带你搭好开发环境。说实话,环境搭建这事儿看着简单,但坑不少。我见过太多新手卡在这一步,一卡就是半天。咱们一步步来,稳一点。

3.1 Keil MDK安装与配置

Keil MDK,说白了就是咱们写代码、编译、下载、调试的一站式工具。我个人习惯用MDK 5.38版本,太新的版本有时候兼容性反而不好。

3.1.1 安装步骤

  1. 下载安装包:去Keil官网下载MDK-ARM。注意别下成C51了,那是给51单片机用的。
  2. 运行安装程序:一路Next就行。但我建议你改一下安装路径,别放C盘。我习惯放D:\Keil_v5。
  3. 安装器件支持包:这一步很多人会忘。装完MDK后,还得装你用的芯片的Pack。咱们用STM32F103,那就装Keil.STM32F1xx_DFP。
  4. 破解:嗯,这个你懂的。用注册机生成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 新建项目

  1. 打开STM32CubeMX,点击New Project。
  2. 在Board Selector里搜STM32F103C8,或者直接在MCU Selector里选。
  3. 选好后,系统会问你要不要初始化所有外设。点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。这里要注意:

  1. Toolchain / IDE选MDK-ARM V5
  2. Firmware Package选你之前下载的版本
  3. 勾选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标签页:

  1. Use选择J-LINK / J-TRACE Cortex
  2. 点Settings,进入Cortex JLink/JTrace Target Driver Setup
  3. Port选SW(不是JTAG,SWD只需要两根线)
  4. 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函数的开头

如果连不上,别慌。检查这几样:

  1. 开发板供电了吗?J-Link的VTref引脚有没有3.3V?
  2. SWDIO和SWCLK有没有接反?
  3. 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代码。到时候你会发现,环境搭得越稳,后面写代码越顺。