第一章:课程导学与项目全景

各位同学,欢迎来到《UART裸机驱动开发与环回测试调试优化项目实战》。我是这门课的主讲,一个在嵌入式底层摸爬滚打了十几年的工程师。

这一章,我们不急着写代码。先把整个项目的蓝图看清楚。你想想看,盖房子之前总得先看图纸吧?做嵌入式开发也是一样的道理。我们先搞清楚UART是什么,裸机驱动到底在干什么,环回测试又是怎么一回事。把这些概念理清了,后面动手才不至于跑偏。

1.1 UART协议基础:串行通信的“老黄牛”

UART,全称是Universal Asynchronous Receiver/Transmitter,通用异步收发器。说白了,它就是用来在两个设备之间传数据的。我刚开始做嵌入式那会儿,调试板子最常用的就是UART,打印个日志、跟传感器聊聊天,全靠它。

为什么叫“异步”?因为它没有单独的时钟线。收发双方得事先约定好一个“节奏”——波特率。就像两个人跳舞,得踩在同一个拍子上。

UART通信的核心要素:
  • 波特率(Baud Rate):每秒传输的符号数。常见的有9600、115200。我习惯用115200,速度快,调试起来不卡顿。
  • 数据位(Data Bits):一帧里有效数据的位数。通常是8位,一个字节。
  • 停止位(Stop Bits):帧结束的标志。一般是1位或2位。
  • 校验位(Parity Bit):简单的错误检测。可选奇校验、偶校验或无校验。

一帧UART数据长什么样?我画个图给你看。

UART 数据帧结构 起始位 0 数据位 (5~8位) LSB → MSB 校验位 可选 停止位 1/1.5/2位 空闲位 高电平 关键说明: • 空闲时,TX线保持高电平。 • 起始位是一个位宽的低电平,告诉接收方“我要开始发了”。 • 数据位从最低位(LSB)开始传输,最高位(MSB)最后。 • 停止位必须恢复为高电平,否则下一帧的起始位无法被识别。
我的经验:调试时如果发现数据全是乱码,八成是波特率没对上。我曾经花了一整个下午,最后发现是板子上晶振频率算错了,导致波特率发生器分频不对。嗯,从那以后我每次都会先拿示波器看一眼TX脚的波形,量一下位宽,确认波特率。

1.2 裸机驱动开发概念:没有操作系统,怎么玩?

裸机,就是没有操作系统。你的程序直接跑在硬件上,所有资源都由你一个人管。说白了,你就是操作系统。

裸机驱动开发,核心就是直接操作寄存器。你要去读芯片手册,找到UART模块的基地址,找到控制寄存器、状态寄存器、数据寄存器。然后往里面写值,或者从里面读值。

我习惯把驱动分成三层:

层次 职责 示例
硬件抽象层 (HAL) 直接读写寄存器,封装成最基础的函数 uart_reg_write(), uart_reg_read()
驱动核心层 实现UART的初始化、发送、接收逻辑 uart_init(), uart_send_byte()
应用接口层 提供更高级的API,比如字符串发送、格式化打印 uart_send_string(), uart_printf()

为什么要分层?你想想看,如果以后换了芯片,我只需要改最底层的HAL层,上面的代码基本不用动。这就是可移植性。

避坑指南:裸机开发最忌讳的就是“一把梭”。我曾经见过有人把所有代码都写在main函数里,寄存器地址直接写死。后来换了个芯片型号,整个项目几乎重写。记住,分层不是花架子,是让你少加班的。

1.3 环回测试原理:最简单的自检方法

环回测试,英文叫Loopback Test。就是把发送脚(TX)和接收脚(RX)短接起来。我发出去的数据,自己收回来。如果收到的和发出的一模一样,说明UART硬件通路是通的。

为什么需要环回测试?

  • 硬件验证:板子刚焊好,不确定UART引脚有没有虚焊。环回一下,快速确认。
  • 驱动调试:驱动写好了,但还没接外部设备。先环回,验证发送和接收逻辑是否正确。
  • 问题隔离:通信出问题了,到底是这边的问题,还是对方的问题?环回一下,先把自己这边搞干净。

环回测试有两种方式:

  • 硬件环回:用一根杜邦线,把TX和RX物理上连起来。简单粗暴,但有效。
  • 软件环回:在芯片内部,通过配置寄存器,让UART模块自己把发送数据回环到接收路径上。不需要外部连线。

我们这个项目,两种方式都会用到。先做软件环回,快速验证驱动;再做硬件环回,验证实际物理链路。

1.4 项目目标与开发环境介绍

这个项目的最终目标是什么?我们要从零开始,写一个完整的UART裸机驱动。然后通过环回测试,反复调试、优化,直到它稳定可靠。

具体来说,我们要完成这几件事:

  1. 编写UART初始化函数,配置波特率、数据位、停止位、校验位。
  2. 实现单字节发送和接收函数。
  3. 实现字符串发送和接收函数。
  4. 实现环回测试程序,自动发送预设数据并比对结果。
  5. 加入超时机制和错误处理,让驱动更健壮。
  6. 通过调试工具(逻辑分析仪、串口助手)验证波形和数据。

开发环境方面,我选的是:

工具/平台 说明
MCU STM32F103系列(Cortex-M3内核,UART外设典型)
IDE Keil MDK 或 STM32CubeIDE,二选一
调试器 J-Link 或 ST-Link
逻辑分析仪 Saleae 或 国产便宜款,用来抓UART波形
串口助手 SSCOM 或 Putty,用来和PC通信验证
我的建议:如果你手头没有STM32F103的板子,用其他MCU也行。UART的原理是通用的,寄存器名字不同,但思路一样。关键是理解流程,而不是死记硬背寄存器地址。