第3章 开发环境搭建:Keil MDK安装、工程模板建立、J-Link调试配置、Makefile入门

说实话,很多初学者一上来就急着写代码,结果卡在环境搭建上大半天。我当年也干过这事——装了个Keil就以为万事大吉,结果编译报错、下载失败、调试器不识别,折腾到半夜。嗯,这一章咱们就把这些坑提前填上。

3.1 Keil MDK安装与激活

Keil MDK,说白了就是ARM内核单片机的主流IDE。飞控里用的STM32、GD32这些芯片,基本都靠它吃饭。

安装步骤:

  1. 去官网下载MDK-ARM最新版(目前是5.38或5.39)
  2. 双击安装包,一路Next。注意安装路径不要有中文
  3. 安装完成后,打开Keil uVision5
  4. 点击File → License Management
  5. 用注册机生成激活码(具体操作网上很多,不展开)
注意: 激活时一定要以管理员身份运行Keil和注册机。我遇到过好几次因为权限不够导致激活失败的情况。

安装完Keil之后,还得装对应的芯片包。比如你用STM32F407,就去Pack Installer里搜STM32F4xx_DFP。这个包不装,你连芯片型号都选不了。

3.2 工程模板建立

我个人习惯,每个项目都从零搭一个模板。为什么?因为官方例程太臃肿,很多用不到的东西全塞进来,看着就烦。

一个干净的飞控工程模板应该包含:

  • startup_stm32f4xx.s — 启动文件,汇编写的
  • system_stm32f4xx.c — 系统时钟配置
  • stm32f4xx.h — 外设寄存器定义
  • main.c — 主函数入口
  • core_cm4.h — Cortex-M4内核相关

建立步骤:

  1. 新建一个文件夹,比如 FlightCtrl_Template
  2. 在里面建三个子文件夹:UserStartupDrivers
  3. 把启动文件和系统文件丢进 Startup
  4. 把HAL库或标准库的源文件丢进 Drivers
  5. 打开Keil,新建工程,选择对应芯片型号
  6. 把刚才的文件分组添加进去
小技巧: 我习惯在工程里加一个 bsp 文件夹,专门放板级支持包。这样以后换板子,只改bsp层就行,上层逻辑不用动。

3.3 J-Link调试配置

调试器是嵌入式开发的命根子。没有它,你只能靠printf和LED灯猜问题。J-Link是我用得最多的调试器,稳定、速度快。

配置步骤:

  1. 安装J-Link驱动(SEGGER官网下载)
  2. 用SWD线连接J-Link和目标板:SWDIO、SWCLK、GND、VCC(可选)
  3. 打开Keil工程,点击魔法棒 → Debug选项卡
  4. 选择 J-LINK / J-TRACE Cortex
  5. 点击Settings,确认SWD模式,速度选1MHz(别选太高,容易不稳定)
  6. 在Flash Download选项卡里,添加对应芯片的算法文件

我曾经踩过的坑:

有一次怎么都连不上J-Link,折腾了两小时。最后发现是SWDIO和SWCLK接反了。嗯,接线前一定多看几遍原理图。

配置好之后,点一下Download按钮,程序就能烧进去了。如果报错 No Cortex-M SW Device Found,先检查接线,再检查供电,最后看看J-Link固件是不是太老了。

3.4 Makefile入门

Keil虽然方便,但做大型项目时,Makefile才是王道。为什么?因为自动化。你想想看,每次改个文件都要点一下编译,多累啊。用Makefile,一条命令搞定全部。

一个最简单的Makefile示例:

# 编译器
CC = arm-none-eabi-gcc

# 目标文件
TARGET = flight_ctrl

# 源文件
SRCS = main.c system_stm32f4xx.c

# 编译选项
CFLAGS = -mcpu=cortex-m4 -mthumb -O2

# 链接选项
LDFLAGS = -T stm32f4xx.ld

all: $(TARGET).bin

$(TARGET).elf: $(SRCS)
	$(CC) $(CFLAGS) $(SRCS) $(LDFLAGS) -o $@

$(TARGET).bin: $(TARGET).elf
	arm-none-eabi-objcopy -O binary $< $@

clean:
	rm -f *.elf *.bin *.o

这个Makefile干了三件事:编译源文件、生成ELF、再转成bin。你只需要在终端敲个 make,一切自动完成。

建议: 刚开始用Makefile时,别搞太复杂。先写个能编译的,后面再慢慢加自动搜索源文件、依赖检查这些功能。

Makefile的核心概念就三个:

  • 目标(target) — 你要生成什么文件
  • 依赖(prerequisites) — 生成目标需要哪些文件
  • 命令(recipe) — 怎么生成目标

说白了,Makefile就是告诉编译器:先做A,再做B,最后做C。如果A没变,就跳过。这个增量编译的特性,在大型飞控项目里特别有用。

3.5 环境验证

环境搭好了,怎么知道对不对?写个点灯程序试试。

#include "stm32f4xx.h"

int main(void)
{
    // 使能GPIO时钟
    RCC->AHB1ENR |= (1 << 3);  // GPIOD时钟
    
    // 配置PD13为输出
    GPIOD->MODER |= (1 << 26); // PD13输出模式
    
    while(1)
    {
        GPIOD->ODR ^= (1 << 13); // 翻转PD13
        for(volatile uint32_t i = 0; i < 500000; i++); // 延时
    }
}

编译通过,下载到板子上,LED开始闪烁。恭喜你,环境搭建成功了。

注意: 如果LED不亮,先检查硬件——我见过有人把LED接反了,折腾半天才发现是极性反了。

这一章的内容就这些。环境搭建虽然枯燥,但它是后面所有工作的基础。你想想看,如果连编译下载都搞不定,后面那些PID调参、姿态解算、传感器驱动,根本跑不起来。所以,花点时间把这一步做扎实,后面会省很多事。

下一章,咱们开始真正接触飞控的核心——传感器驱动。到时候我会讲讲怎么用I2C和SPI读陀螺仪和加速度计的数据。嗯,那才是真正有意思的部分。