2. 嵌入式系统基础

做嵌入式开发,选对硬件平台和搭好开发环境,是后面所有工作的基础。这一章我带你过一遍主流MCU选型、IDE配置和调试工具的使用。这些内容看起来琐碎,但直接影响你后续的开发效率。

2.1 主流MCU选型:STM32 vs GD32

先聊聊芯片选型。目前市面上最常用的就是STM32和GD32这两大系列。很多人问我到底选哪个?我的回答是:看项目需求。

对比维度 STM32(ST) GD32(兆易创新)
内核 Cortex-M0/M3/M4/M7 Cortex-M3/M4/M23/M33
主频 最高 480MHz(H7系列) 最高 200MHz(GD32F5系列)
价格 较高,供货波动大 便宜 30%~50%,供货稳定
生态 极其完善,资料丰富 兼容STM32,但资料略少
DMA通道数 2~16个(视型号) 2~14个(视型号)
中断优先级 16级可编程 16级可编程

我的建议:如果是做产品量产,成本敏感就用GD32;如果是做原型验证或学习,STM32的生态会让你少踩很多坑。我个人习惯在项目初期先用STM32开发,后期再根据成本评估是否切换到GD32。

2.2 IDE配置:Keil vs IAR

IDE的选择其实是个老话题。Keil MDK和IAR Embedded Workbench各有千秋。我两个都用过,说说我的感受。

2.2.1 Keil MDK配置要点

Keil的界面更友好,上手快。但要注意几个关键配置:

  1. 芯片选择:在Device选项卡里选对具体型号,比如STM32F407VG
  2. Flash烧录算法:在Utilities选项卡里添加对应的Flash算法文件
  3. 调试器设置:在Debug选项卡里选择J-Link或ST-Link
  4. 优化等级:调试阶段用-O0,发布阶段用-O2或-Os

小技巧:Keil的工程文件(.uvprojx)是XML格式的,有时候配置乱了可以直接用文本编辑器打开修改。我曾经遇到过工程文件损坏,用这个方法救回来了。

2.2.2 IAR配置要点

IAR的编译器优化做得更好,生成的代码体积更小。配置时注意:

  1. 芯片选择:在General Options里选对器件
  2. 链接脚本:IAR使用.icf文件,需要根据芯片Flash和RAM大小调整
  3. 调试器:在Debugger选项卡里选择驱动
  4. C-Runtime:建议关闭semihosting,否则调试会卡死

避坑指南:我曾经在IAR里忘记关闭semihosting,结果程序一跑就卡在printf函数里。排查了半天才发现是这个问题。所以,嵌入式开发里printf不是随便用的。

2.3 调试工具:J-Link vs ST-Link

调试工具是开发者的眼睛。选对了,调试效率翻倍。

特性 J-Link(SEGGER) ST-Link(ST)
速度 最高 50MHz SWO 最高 4MHz SWO
断点数量 无限(硬件+软件) 6个硬件断点
RTT支持 原生支持 不支持
价格 较贵(正版) 便宜(开发板自带)
适用场景 复杂调试、性能分析 日常开发、简单调试

我个人习惯:调试DMA和中断协同这类复杂逻辑时,一定用J-Link。它的RTT功能可以实时输出日志,比串口打印方便太多。

2.4 开发环境搭建流程图

下面这张图展示了从选型到调试的完整流程:

开发环境搭建流程图 MCU选型 IDE安装配置 调试器连接 工程创建与配置 验证与调试 选型要点 • 根据外设需求选DMA通道数 • 考虑中断优先级需求 • 评估成本与供货 调试器选择 • 复杂调试用J-Link • 日常开发用ST-Link • 注意SWD接线正确

2.5 实战:搭建一个最小工程

说了这么多理论,我们来动手搭一个最小工程。以STM32F407VG + Keil MDK为例:

// 1. 新建工程,选择芯片 STM32F407VG
// 2. 添加启动文件 startup_stm32f40xx.s
// 3. 添加系统时钟配置 system_stm32f4xx.c
// 4. 编写主函数 main.c

#include "stm32f4xx.h"

int main(void) {
    // 使能GPIO时钟
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
    
    // 配置PD12为推挽输出
    GPIOD->MODER |= GPIO_MODER_MODER12_0;
    
    while(1) {
        // 点亮LED
        GPIOD->BSRR = GPIO_BSRR_BS_12;
        delay(1000000);
        // 熄灭LED
        GPIOD->BSRR = GPIO_BSRR_BR_12;
        delay(1000000);
    }
}

调试技巧:第一次下载程序时,记得检查BOOT0和BOOT1的电平设置。我遇到过好几次因为BOOT引脚配置不对,导致程序下载成功但跑不起来的情况。

2.6 常见问题与解决方案

  • 下载失败:检查SWD接线,确保SWDIO、SWCLK、GND三根线都接好
  • 调试器识别不到:更新驱动,或者换个USB口试试
  • 程序跑飞:检查中断向量表是否配置正确,堆栈大小是否足够
  • 优化后功能异常:降低优化等级,或者用volatile修饰关键变量