第一章 MCU基础与开发环境搭建

大家好,欢迎来到这门课。我是你们的讲师,一个在嵌入式圈子里摸爬滚打了十几年的老工程师。

今天咱们聊点最基础的——认识MCU、搭建开发环境,再跑个LED灯。别小看这一步,万丈高楼平地起,地基打不牢,后面有你哭的。我见过太多新手,一上来就啃RTOS、啃网络协议栈,结果连个GPIO都配置不明白。嗯,咱们慢慢来。

1.1 到底什么是MCU?

MCU,全称Microcontroller Unit,中文叫微控制器。说白了,就是一台缩在芯片里的微型计算机。

它跟咱们电脑里的CPU不一样。CPU只管算数,你得给它配内存、配硬盘、配各种外设。MCU不一样,它把CPU、内存(RAM)、程序存储器(Flash)、各种外设(定时器、串口、ADC)全都集成在一个芯片里。你给它通上电,写个程序,它就能干活。

我刚开始做项目时,用的是8051单片机。那时候Flash才几KB,RAM才几百字节,写程序得精打细算,一个变量都不敢多定义。现在好了,Cortex-M系列动不动就几百KB Flash、几十KB RAM,甚至还有带DSP指令的。时代变了,但底层逻辑没变。

核心要点:MCU = CPU + 存储器 + 外设,三者集成在一个芯片上。

1.2 Cortex-M系列,你该选哪个?

现在市面上主流的MCU内核,基本都被ARM Cortex-M系列统治了。你想想看,从几块钱的M0到几十块钱的M7,覆盖了从简单到复杂的各种应用。

内核 特点 典型应用
Cortex-M0/M0+ 超低功耗、成本低、指令简单 智能家居传感器、小家电、玩具
Cortex-M3 性能均衡、中断响应快、性价比高 工业控制、电机驱动、物联网终端
Cortex-M4 带FPU和DSP指令,适合数字信号处理 音频处理、电机FOC控制、无人机飞控
Cortex-M7 高性能、带缓存、支持双精度浮点 高端仪表、图像处理、AI边缘计算

我个人习惯,做简单项目用M0,省电又便宜。做复杂控制用M4,算力够用。M7嘛,除非你跑图形界面或者做音频算法,否则有点浪费。

我的建议:新手入门,首选Cortex-M3或M4内核的芯片。比如STM32F103(M3)或STM32F407(M4)。资料多、社区活跃、遇到问题好查。

1.3 开发环境:Keil还是IAR?

这个问题,几乎每个新手都会问。我直接说结论:两个都能用,但Keil更主流。

Keil MDK,全称Microcontroller Development Kit。它由ARM公司官方出品,对Cortex-M系列支持最好。界面友好,调试方便,而且网上教程一抓一大把。

IAR Embedded Workbench,编译优化更强,代码密度更高。但界面风格有点老派,新手可能不太适应。

我曾经在两个环境之间反复横跳过。后来发现,其实没必要纠结。选一个你看着顺眼的,用熟了都一样。我个人推荐Keil,因为它的调试器(ULINK、J-Link)兼容性更好,省心。

安装Keil MDK的步骤(简单版)

  1. 去Keil官网下载MDK-ARM安装包(需要注册账号)。
  2. 双击安装,一路Next。注意安装路径不要有中文。
  3. 安装完成后,打开Keil uVision5。
  4. 点击「Pack Installer」,安装你所用芯片的器件支持包(比如STM32F1系列)。
  5. 破解(你懂的)。不破解的话,代码有32KB限制,跑个LED灯倒是够了。

注意:安装路径和工程路径都不要出现中文或空格。否则编译时可能报一些莫名其妙的错误。我当年就被这个坑过,折腾了一下午才发现是路径问题。

1.4 第一个LED程序——点灯仪式

好了,环境搭好了,咱们来写第一个程序。点灯,是嵌入式工程师的「Hello World」。每个新板子到手,我第一件事就是点灯。灯亮了,说明芯片活着、时钟对了、GPIO配置对了,后面的事才好办。

咱们以STM32F103为例,用标准外设库(Standard Peripheral Library)来写。为什么不用HAL库?因为标准库更接近寄存器,适合理解底层原理。

步骤一:新建工程

  1. 打开Keil,点击Project -> New uVision Project。
  2. 选择芯片型号:STM32F103C8。
  3. 在弹出的Manage Run-Time Environment中,勾选CMSIS -> CORE,以及Device -> Startup。
  4. 点击OK,工程就建好了。

步骤二:编写代码

在工程中新建一个main.c文件,输入以下代码:

#include "stm32f10x.h"   // 包含芯片头文件

int main(void)
{
    // 1. 使能GPIOB时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    
    // 2. 配置GPIOB的Pin0为推挽输出,50MHz
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    // 3. 主循环:点亮LED,延时,熄灭,延时
    while(1)
    {
        GPIO_SetBits(GPIOB, GPIO_Pin_0);   // 输出高电平,灯亮
        Delay();                            // 延时
        GPIO_ResetBits(GPIOB, GPIO_Pin_0); // 输出低电平,灯灭
        Delay();                            // 延时
    }
}

// 简单的延时函数(不精确,但够用)
void Delay(void)
{
    uint32_t i;
    for(i = 0; i < 500000; i++);
}

代码解析:

  • RCC_APB2PeriphClockCmd:使能GPIOB的时钟。记住,STM32的外设默认时钟是关闭的,你得手动打开。这是新手最容易忘的一步。
  • GPIO_Init:配置GPIO的模式。推挽输出(Out_PP)是最常用的输出模式,能输出高低电平。
  • GPIO_SetBitsGPIO_ResetBits:分别设置引脚为高电平和低电平。
  • Delay:简单的软件延时。不精确,但点个灯足够了。

步骤三:编译下载

  1. 点击编译按钮(或者按F7),确保没有错误。
  2. 用J-Link或ST-Link连接开发板和电脑。
  3. 点击下载按钮(或者按F8),程序烧录到芯片中。
  4. 按下复位键,看LED是不是在闪烁?

避坑指南:我曾经遇到过一个问题——代码编译没问题,下载也成功,但LED就是不亮。查了半天,发现是LED接的引脚跟代码里写的不一样。所以,拿到开发板第一件事,看原理图!确认LED接在哪个GPIO上,是高电平点亮还是低电平点亮。

1.5 小结

这一章,咱们认识了MCU,了解了Cortex-M系列的选型,安装了Keil开发环境,还亲手跑了一个LED闪烁程序。

别觉得简单。你想想看,从零开始,让一个芯片按照你的意愿工作,这本身就是一件很酷的事。后面咱们会一步步深入,从GPIO到定时器,从串口到I2C,从中断到DMA。每学一个外设,你都会对MCU有更深的理解。

下一章,咱们聊聊GPIO的进阶玩法——按键输入、外部中断。到时候见。

课后作业:

  1. 修改代码,让LED以不同的频率闪烁(比如快闪3次,慢闪3次)。
  2. 尝试用寄存器方式(直接操作GPIOB->ODR)来实现同样的功能,对比一下代码量。

公众号:蓝海资料掘金营,微信deep3321