FPGA 实现 UART 串口通信
UART 串口通信是 FPGA 入门阶段最经典、最实用的异步通信案例,无论是 FPGA 与单片机、电脑的交互,还是项目中的简单数据传输,UART 都能发挥作用。本文将从核心原理、关键参数(重点讲波特率)、Verilog 完整代码,到仿真/硬件验证,一步步拆解。
UART 串口通信核心原理
UART(通用异步收发传输器),核心关键词是'异步'——无需专门的时钟同步线,收发双方只需约定好相同的通信参数,就能实现数据的可靠传输。不同于 SPI、I2C 的同步通信,UART 的优势是接线简单(仅需 TX 发送线、RX 接收线,共地即可),成本低、实用性强。
核心通信参数
UART 的通信稳定性,完全依赖于收发双方参数一致,其中最关键的 5 个参数如下:
- 波特率:下文重点详解,核心是'每秒传输的二进制位数',决定通信速度;
- 数据位:通常设为 8 位,即每次传输 1 个字节(0~255 的数值);
- 停止位:通常设为 1 位,用于标识一个字节的数据传输结束;
- 校验位:建议设为'无校验',简化设计(校验位用于检测传输错误,实际项目可根据需求添加);
- 帧结构:一个完整的 UART 数据帧 = 1 位起始位(低电平 0) + 8 位数据位(低位先行) + 1 位停止位(高电平 1),共 10 位/字节。
波特率详解
很多新手第一次接触 UART,都会被'波特率'搞懵,其实一句话就能看懂,结合实例拆解更易理解:
波特率的核心定义
波特率(Baud Rate)的本质是:串口通信中每秒传输的二进制位数(bit/s),单位是 bps(bits per second)。简单来说,它就是串口传输'0'和'1'这些电信号的'速度',和我们下载文件的'1MB/s'逻辑一致,只是单位不同(一个是 bit,一个是 Byte)。
直观实例
结合我们常用的波特率和 UART 帧结构(10 位/字节),举两个最常见的例子:
- 波特率=9600 → 每秒传输 9600 个二进制位 → 每秒可传输 9600÷10=960 个字节;
- 波特率=115200 → 每秒传输 115200 个二进制位 → 每秒可传输 115200÷10=11520 个字节;
很明显,波特率越高,通信速度越快,但同时对 FPGA 的时钟精度、硬件接线的抗干扰能力要求也越高。建议从 9600 波特率开始,稳定性较好。
波特率的核心作用:保证收发同步
前面说过,UART 是'异步通信',没有专门的时钟线来同步收发双方的节奏,那怎么保证接收端能正确识别发送端的数据呢?答案就是'约定波特率'。
- 发送端:按照约定的波特率,每发送 1 个 bit,就等待固定的时间(比如 9600 波特率下,每个 bit 占用 1÷9600≈104μs);
- 接收端:同样按照约定的波特率,每隔固定时间去采样一次接收引脚的电平(高电平=1,低电平=0),从而解析出正确的数据。
重点提醒:收发两端的波特率必须完全一致,否则会出现'采样错位',最终解析出错误的数据。比如发送端用 9600 波特率,接收端用 4800 波特率,接收端采样的时间会越来越偏,传过来的'0101'可能会被解析成'0011',导致通信失败。
FPGA 中波特率的具体实现
FPGA 的系统时钟通常是固定的(比如 50MHz、100MHz),而波特率是我们约定的(比如 9600),如何用 FPGA 的高频时钟,模拟出波特率对应的'bit 时间'?核心就是'时钟分频'。
分频系数计算公式:分频系数 = 系统时钟频率 ÷ 波特率
举例(后续代码用的就是这个配置):系统时钟=50MHz,波特率=9600,那么分频系数=50_000_000 ÷ 9600≈5208。也就是说,FPGA 每计数 5208 个系统时钟脉冲,就对应 UART 的 1 个 bit 位,这样就能精准匹配波特率的速度。
工程常用波特率
波特率是标准化的参数,实际项目中不要随意自定义(比如设为 10000),否则容易出现兼容性问题,常用的标准化波特率如下:
| 常用波特率 | 每个 bit 的时间(近似值) |
|---|

