第二章 嵌入式系统基础与开发环境搭建

各位同学,大家好。这一章我们聊聊嵌入式系统的基础,以及怎么把开发环境搭起来。说实话,很多新手一上来就急着写代码,结果连芯片怎么选、工具链怎么配都没搞明白,后面踩坑踩到怀疑人生。我当年带过一个新人,花了两天装Keil,结果发现装的是51版的,跟STM32完全不搭边……嗯,咱们别走这种弯路。

2.1 嵌入式系统到底是什么?

嵌入式系统,说白了就是「专门干一件事的计算机系统」。它不像你桌上的PC,能打游戏能写文档还能剪视频。嵌入式系统通常只做一件事,比如测血糖、控温度、读心率。

我个人的理解是:嵌入式系统 = 微控制器 + 传感器 + 执行器 + 软件逻辑。你想想看,血糖仪里就一个MCU,加上试纸接口、LCD屏幕、几个按键,再加一套算法,就搞定了。

嵌入式系统有几个特点:

  • 资源受限:RAM可能只有几十KB,Flash也就几百KB。别想着跑Linux了。
  • 实时性要求:血糖仪测完要立刻出结果,不能卡顿。
  • 低功耗:用纽扣电池的设备,一用就是几个月甚至一年。
  • 高可靠性:医疗设备出bug?那可是人命关天的事。

核心要点:嵌入式开发不是写大软件,而是「在有限的资源里,把一件事做到极致」。

2.2 ARM Cortex-M系列介绍

现在市面上主流的MCU,十有八九都是ARM Cortex-M内核。为什么?因为ARM把内核设计好了,各家芯片厂(ST、NXP、TI、GD等)直接买授权,然后加上自己的外设,就成了我们用的MCU。

Cortex-M系列主要分这几个档次:

内核 位宽 典型应用 我常用的场景
Cortex-M0/M0+ 32位 简单传感器、小家电 低功耗血糖仪待机管理
Cortex-M3 32位 工业控制、医疗设备 上一代血糖仪主控
Cortex-M4 32位 带DSP、FPU,适合算法 现在的主力,跑血糖算法
Cortex-M7 32位 高性能,带缓存 高端POCT设备

我个人习惯用Cortex-M4。为什么?因为血糖仪需要做信号处理——试纸上的电流信号很微弱,要滤波、放大、计算。M4带硬件浮点运算单元(FPU),算起来快很多。我在项目中遇到过用M3算浮点,结果CPU占用率飙到80%,后来换成M4直接降到20%。

小提示:选型时别只看主频。外设丰富度、功耗、封装大小、价格、供货稳定性,这些都得考虑。我曾经因为某款芯片缺货,硬生生把方案从ST换成了GD,重新调了两个月。

2.3 Keil MDK / IAR 环境搭建

好,理论说完了,咱们动手搭环境。目前主流的两款IDE:Keil MDK和IAR Embedded Workbench。

2.3.1 Keil MDK

Keil MDK(Microcontroller Development Kit)是ARM官方推荐的IDE之一。界面比较老派,但胜在稳定、兼容性好。

安装步骤:

  1. 去ARM官网下载MDK-ARM安装包(注意版本,我建议用5.38或更新版)。
  2. 安装时一路Next,但注意安装路径不要有中文。
  3. 安装完成后,打开Keil,点击「Pack Installer」安装芯片包。比如STM32F4系列,搜「STM32F4xx_DFP」。
  4. 激活License。如果你有正版License,输入即可;学生可以用评估版(代码限制32KB)。

我第一次用Keil时,死活编译不过,后来发现是没装芯片包。嗯,这里要注意:Pack Installer里的芯片包必须装,否则编译器不认识你的芯片

2.3.2 IAR Embedded Workbench

IAR的编译器优化做得比Keil好,代码密度更高。我个人的感觉是:Keil适合快速上手,IAR适合产品量产阶段。

安装步骤类似:

  1. 下载IAR for ARM安装包。
  2. 安装时选择对应的芯片系列(比如STM32F4)。
  3. 安装完成后,打开IAR,配置工程选项里的芯片型号。

避坑指南:我曾经在IAR里开了最高优化等级,结果代码跑飞了。后来发现是优化把某些变量给优化掉了。所以量产阶段,建议用中等优化,然后逐个模块测试。

2.4 STM32CubeMX 配置入门

STM32CubeMX是ST官方出的图形化配置工具。你点点鼠标,它就能生成初始化代码。说白了,就是帮你省掉写底层寄存器配置的功夫。

我刚开始做开发时,都是对着参考手册一个个寄存器写。后来用了CubeMX,效率提升了好几倍。但要注意:CubeMX生成的代码只是骨架,业务逻辑还得自己写

基本操作流程:

  1. 打开CubeMX,点击「New Project」。
  2. 选择芯片型号,比如STM32F407VGT6。
  3. 在Pinout视图中配置外设:比如使能USART1、配置ADC、设置GPIO。
  4. 在Clock Configuration中配置时钟树。我一般把HCLK设到168MHz(F4的最高主频)。
  5. 在Project Manager中设置工程名、IDE类型(选MDK-ARM或IAR)。
  6. 点击「GENERATE CODE」,生成工程。

举个例子,配置一个LED闪烁:

// CubeMX生成的GPIO初始化代码
void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  __HAL_RCC_GPIOA_CLK_ENABLE();  // 使能GPIOA时钟

  GPIO_InitStruct.Pin = GPIO_PIN_5;       // PA5
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  // 推挽输出
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

// 主循环里翻转LED
while (1)
{
  HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
  HAL_Delay(500);  // 延时500ms
}

你看,就这么几行代码,LED就开始闪了。但这里有个坑:HAL_Delay()依赖SysTick中断,如果你在中断里调用了延时函数,系统会死锁。我当年调试一个血糖仪时,就是因为这个bug,找了两天才发现。

我的建议:CubeMX生成的代码,不要手动修改。如果你要改,请在「User Code」区域里改,否则重新生成代码时会被覆盖。这个教训,我是用加班到凌晨三点换来的。

2.5 本章小结

这一章我们讲了嵌入式系统的定义、ARM Cortex-M系列的区别、Keil和IAR的安装、以及CubeMX的基本用法。说白了,就是让你知道「用什么工具、怎么搭环境」。下一章我们会真正开始写代码,从点亮一个LED开始,一步步搭建血糖仪的核心逻辑。

最后说一句:环境搭好了,别急着写大项目。先跑个点灯程序,确认工具链没问题。我见过太多人,环境没配好就开始写代码,最后编译报错,连是代码问题还是环境问题都分不清。

好,咱们下一章见。