第一章:课程导论与开发环境搭建

各位同学好,我是你们的嵌入式讲师。说实话,做了十几年嵌入式开发,串口通信是我打交道最多的外设,没有之一。从最早的51单片机到现在的STM32,串口调试就像工程师的“听诊器”——项目跑不起来,第一件事就是看串口打印。

这一章我们不急着写代码。先把路铺好,后面才能跑得快。我个人习惯是:环境搭建阶段多花半小时,调试阶段就能省下半天。

1.1 课程目标与学习路径

这门课的核心目标只有一个:让你真正掌握STM32 HAL库下的串口不定长数据接收与DMA传输。不是停留在“能跑例程”的程度,而是遇到问题能自己定位、自己修。

课程三大能力目标:

  • 能写:独立完成串口+DMA的工程配置与代码编写
  • 能调:使用调试器、逻辑分析仪、串口助手定位故障
  • 能修:解决实际项目中遇到的丢帧、死机、DMA卡死等问题

学习路径我建议这样走:

  1. 基础夯实(第1-5章):环境搭建、HAL库串口基础、DMA原理
  2. 核心实战(第6-15章):不定长接收的多种实现方案
  3. 调试进阶(第16-25章):故障定位方法论、常见坑点解析
  4. 项目整合(第26-30章):综合案例与性能优化

你想想看,如果连printf都打不出来,后面谈DMA传输就是空中楼阁。所以我们先从最基础的串口打印开始。

1.2 STM32CubeMX与HAL库概述

STM32CubeMX是ST官方推出的图形化配置工具。说白了,就是帮你自动生成初始化代码的。我刚开始用的时候还不太信任它,总觉得手写寄存器更“可控”。直到有一次项目赶工期,CubeMX帮我省了整整两天的配置时间——嗯,从那以后我就真香了。

对比项 标准库 HAL库 LL库
抽象层次 中等 高 低
代码量 较多 少(自动生成) 较少
移植性 差 好 中等
学习曲线 陡峭 平缓 中等
适合场景 老项目维护 快速开发/原型 性能敏感场景

这门课我们全程使用HAL库。原因很简单:串口+DMA的配置逻辑在HAL库中封装得相当完善,我们能把精力集中在业务逻辑和调试方法上,而不是跟寄存器位定义死磕。

我的建议:如果你之前用过标准库,别急着排斥HAL。先跟着做两个项目,你会发现HAL的中断回调机制其实很优雅。当然,LL库也有它的用武之地——我们在第28章讲性能优化时会提到。

1.3 硬件平台介绍

课程选用的是STM32F103C8T6,也就是大家常说的“蓝 pills”核心板。为什么选它?

  • 性价比高:十几块钱一块板,坏了不心疼
  • 资料丰富:网上随便一搜都是案例
  • 外设齐全:3路USART、1路DMA1(7通道)、1路DMA2(5通道)
  • 市场占有率高:很多工业产品还在用这个型号

核心参数一览:

参数 值
内核 ARM Cortex-M3 @ 72MHz
Flash 64KB
SRAM 20KB
USART 3路(USART1/2/3)
DMA DMA1(7通道)+ DMA2(5通道)
调试接口 SWD(4线)/ JTAG(5线)

我在项目中遇到过用F103做串口服务器的情况,挂4个串口同时收发,DMA全开,跑了两年没出过问题。这颗芯片的稳定性是经过市场验证的。

注意:F103的USART2和USART3挂载在APB1总线上,时钟最高36MHz。如果你要用高波特率(如921600),建议优先使用挂载在APB2上的USART1。我曾经在这个坑上浪费了半天——USART2在2M波特率下死活收不到数据,换到USART1就好了。

1.4 开发环境安装与配置

我个人习惯用Keil MDK,但IAR也完全没问题。这里以Keil为例,步骤很简洁:

  1. 安装Keil MDK:建议5.27及以上版本,对HAL库支持更好
  2. 安装器件包:Keil→Pack Installer→搜索STM32F1xx→安装最新版
  3. 安装STM32CubeMX:从ST官网下载,建议6.x版本
  4. 安装驱动:CH340串口驱动(板载USB转串口用)
  5. 验证安装:打开CubeMX,能识别到STM32F103C8Tx即可

环境配置中最容易出问题的就是器件包版本不匹配。我记得有一次帮学生远程调试,折腾了半小时发现他装的是F4的包,工程却是F1的——编译不报错,下载就死机。

避坑指南:安装完成后,建议先跑一个官方的Blinky例程。如果LED能闪,说明环境基本没问题。不要一上来就搞串口——先确认MCU能跑起来,再谈外设。

1.5 第一个串口打印工程

好,现在我们来动手。用CubeMX创建一个最简单的串口打印工程。

CubeMX配置步骤:

  1. 新建工程,选择STM32F103C8Tx
  2. 在Pinout视图找到USART1,Mode选Asynchronous
  3. Parameter Settings:Baud Rate=115200,Word Length=8,Parity=None,Stop Bits=1
  4. NVIC Settings:使能USART1全局中断
  5. Clock Configuration:HSE=8MHz,SYSCLK=72MHz
  6. Project Manager:Project Name=uart_print,Toolchain=MDK-ARM
  7. 点击GENERATE CODE

生成代码后,在main.c的main()函数中添加:

#include "stdio.h"

// 重定向printf到串口
int fputc(int ch, FILE *f)
{
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100);
    return ch;
}

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USART1_UART_Init();

    while (1)
    {
        printf("Hello from STM32F103! System running at %d MHz\r\n", HAL_RCC_GetSysClockFreq() / 1000000);
        HAL_Delay(1000);
    }
}

编译下载,打开串口助手(波特率115200),你应该能看到每秒打印一次的信息。

常见问题:如果串口助手收不到数据,先检查三件事:

  • 板子的USB转串口驱动装了吗?(CH340最常见)
  • TX/RX接反了吗?(STM32的TX接串口助手的RX)
  • 波特率一致吗?(CubeMX配的115200,串口助手也得是115200)

我曾经遇到过一个很隐蔽的问题:某品牌的USB转串口模块在115200下不稳定,降到9600就好了。后来换了FT232的模块才解决。所以如果你死活调不通,不妨换个串口模块试试。

1.6 本章知识体系

下面这张图帮你梳理本章的核心脉络:

第一章知识体系结构图 第一章:课程导论与开发环境搭建 课程目标与路径 HAL库与CubeMX 硬件平台介绍 环境安装与配置 串口打印工程 能写·能调·能修 图形化配置 F103C8T6 Keil MDK CubeMX CH340驱动 本章核心:从零搭建可用的串口调试环境 → 理解HAL库设计哲学 → 掌握CubeMX配置流程 → 跑通第一个串口工程

这张图把本章的四个模块串起来了。你会发现,所有工作最终都指向一个目标:让串口能打印出东西。这是后面所有DMA传输、不定长接收实验的基础设施。