FPGA小白模块实战:UART串口通信模块,从原理到直接调用

## 写在前面

我相信很多刚学 FPGA 的朋友,第一次接触串口的时候都会有点懵。

一方面,UART 看起来很基础;另一方面,真正上手时问题特别多。比如仿真能跑、上板不通,或者串口助手一开全是乱码。网上 UART 代码确实很多,但真正适合小白直接拿来用的并不多。有些代码没有接口说明,有些参数不好改,还有些只能“演示一下”,一接到自己的工程里就很别扭。

所以这次我把自己项目里常用的一套 UART 模块整理出来,作为 BuildFPGA 的基础模块资源。这个系列就叫:**《FPGA小白模块实战系列》**。UART 是第一篇,后面我会继续整理 SPI、IIC、FIFO、PWM、OLED、VGA 这些高频模块,尽量做到拿来就能用,小白也能看明白。

## 这个 UART 模块适合谁?

如果你属于下面这几类人,这篇会很实用:

- 刚开始学 FPGA,想做串口通信实验的朋友
- 想用串口助手和 FPGA 通信的朋友
- 想给自己项目加一个调试口的朋友
- 想找一个接口清晰、能直接调用的 UART 模块的朋友
- 不想再被各种“能跑但不好接”的源码折腾的朋友

## UART 到底是干什么的?

你可以把 UART 理解成 FPGA 和电脑之间的一条“说话通道”。

电脑这边通常是 USB 转串口模块,FPGA 这边接 `RX/TX`。只要波特率和帧格式一致,FPGA 就能收电脑的数据;反过来 FPGA 也能把调试信息发回串口助手。

在很多项目里,UART 不只是“通信模块”,更是最实用的调试通道。

## FPGA 和电脑串口到底怎么接?

这部分一定要先搞对。很多小白第一次卡住,不是代码错了,而是线接错了。

电脑一般不是直接接 FPGA,而是通过 **USB 转串口模块** 连到 FPGA。

正确接线关系:

- USB转串口模块 `TXD` -> FPGA `RX`
- USB转串口模块 `RXD` -> FPGA `TX`
- USB转串口模块 `GND` -> FPGA `GND`

| USB转串口模块 | FPGA开发板 | 说明               |
| ------------- | ---------- | ------------------ |
| TXD           | RX         | 电脑发送,FPGA接收 |
| RXD           | TX         | FPGA发送,电脑接收 |
| GND           | GND        | 必须共地           |

这里重点强调 6 件事:

1. `TX` 和 `RX` 一定要交叉接,不是同名直连。
2. `GND` 一定要共地,不共地会非常不稳定。
3. 不要把 **RS232 电平** 直接接 FPGA IO。
4. FPGA IO 通常是 **3.3V TTL**,要确认 USB 转串口模块电平一致。
5. `TX/RX` 接反最常见现象就是“完全收不到数据”。
6. `GND` 没接常见现象是“偶尔能收、乱码、时好时坏”。

## UART 一帧数据到底长什么样?

很多教程一上来讲术语,小白更容易糊涂。你先记住这个画面:

UART 线在空闲时是高电平(`1`)。
真正开始发数据时,会先拉低 1 位,这就是起始位(`0`)。
然后发 8 位数据,而且是 **低位先发**。
最后再拉高 1 位,作为停止位(`1`)。

如果发送 `8'h55`(二进制 `0101_0101`),UART 发数据位时是从 `bit0` 开始,不是 `bit7`。

空闲位:`1`  
起始位:`0`  
数据位:`bit0 -> bit1 -> bit2 -> bit3 -> bit4 -> bit5 -> bit6 -> bit7`  
停止位:`1`

只要你把“低位先发 + 起始位先拉低”这两个点记住,后面看波形会轻松很多。

 

## 这个工程里面有什么?

`uart` 目录里不是只有一个版本,而是分成了几个常见使用场景:

- `uart_echo`:回环测试版本,电脑发什么 FPGA 回什么
- `uart_const_baud`:固定波特率基础收发模块(TX/RX 顶层封装)
- `uart_fifo`:带 FIFO 缓冲的版本,适合实际项目数据流
- `uart_sw_2ch`:双通道相关版本
- `uart_var`、`uart_var_limit`:可变波特率相关版本

如果你是第一次用,别一上来就啃所有文件。

建议先跑通 `uart_echo`,先确认链路和板子没问题;然后看 `uart_const_baud` 把收发接口吃透;最后再上 `uart_fifo`,把它接进你的实际工程。

## 小白建议先跑哪个版本?

我给你一个非常实用的顺序:

1. 先跑 `uart_echo`,看串口通不通  
   电脑发 `55 AA`,能稳定回显,说明硬件连接、波特率、基础时序都没大问题。

2. 再看 `uart_const_baud`,理解 TX/RX 怎么拆分  
   这个版本接口清楚,最适合当你后续工程里的 UART 基础 IP。

3. 最后看 `uart_fifo`,解决“项目化”问题  
   比如数据连续来、上层处理慢、发收节奏不一致,这时候 FIFO 版本就很有价值。

这个顺序跑下来,你不是“看懂了代码”,而是真的能把 UART 接进自己的工程。

## 模块接口怎么用?

这里不贴完整源码,只放几个关键片段,帮你先把“怎么接”跑通。

### 1) 顶层例化(参数配置)

```verilog
uart_const_baud #(
    .clock_freq(50_000_000),
    .baud_rate (115200)
) uart_inst (
    .clk(clk), .rst(rst),
    .rx (uart_rx), .tx(uart_tx),
    .rx_data(rx_data), .rx_rec_flag(rx_rec_flag),
    .tx_data(tx_data), .tx_start(tx_start),
    .tx_idle(tx_idle), .tx_done(tx_done)
);
```

### 2) 发送接口怎么驱动

```verilog
if (tx_idle && send_req) begin
    tx_data  <= send_byte;
    tx_start <= 1'b1;      // 拉高一个时钟启动发送
end else begin
    tx_start <= 1'b0;
end
```

### 3) 接收接口怎么取数

```verilog
if (rx_rec_flag) begin
    rx_byte_valid <= 1'b1;
    rx_byte_data  <= rx_data;
end
```

上面三个片段基本就是小白最常用的接法。完整工程代码我放在 BuildFPGA 资源包里,文章里只讲关键思路,避免把整套源码直接铺开。

posted @ 2026-05-26 17:38  FPGAmaster  阅读(113)  评论(0)    收藏  举报