FPGA实战:从零构建UART串口通信环回系统
1. UART串口通信基础认知
第一次接触FPGA串口通信时,我盯着示波器上跳动的波形看了整整两天才明白:原来UART就像两个人在黑暗中用闪光灯打摩斯密码。发送方突然把手电筒熄灭一下(起始位),然后快速闪烁8次传递信息(数据位),最后亮起手电表示结束(停止位)。这种不需要时钟线同步的通信方式,正是异步串行的精髓所在。
UART帧结构远比想象中灵活。以最常用的8N1格式为例:
- 起始位:1位低电平(相当于说"喂,注意听")
- 数据位:5-9位(通常8位,就是我们发送的ASCII字符)
- 校验位:可选奇偶校验(老式设备的错误检查机制)
- 停止位:1-2位高电平(相当于说"我说完了")
实际项目中遇到过这样的坑:某型号传感器使用7位数据位+偶校验,而我的FPGA默认配置是8N1,结果接收的数据全是乱码。后来用下面这个波特率计算器才解决问题:
// 50MHz时钟生成9600波特率的计数器 parameter CLK_FREQ = 50_000_000; parameter BAUD_RATE = 9600; localparam BAUD_CNT = CLK_FREQ / BAUD_RATE; // 约5208个周期2. FPGA硬件架构设计
去年给某工业设备做通信模块时,我把整个UART系统拆解成三个核心部件,就像组装乐高积木:
2.1 接收模块设计要点
接收模块本质上是个状态机+精密定时器。在Altera Cyclone IV上实测时,发现如果不做信号同步处理,在长电缆传输时会出现随机误码。后来采用三级寄存器同步才稳定:
// 亚稳态处理黄金法则 always @(posedge clk) begin uart_rxd_dly <= {uart_rxd_dly[1:0], uart_rxd}; // 三级缓存 end关键状态转移逻辑:
- IDLE:监测起始位下降沿
- START:延时半周期避开起始位边沿
- DATA:在每个比特中间采样
- STOP:校验停止位有效性
2.2 发送模块优化技巧
发送模块最容易出现的问题是波特率偏差累积。在115200波特率下测试时,发现连续发送会导致停止位缩短。解决方案是提前1/16个波特周期结束发送:
// 提前结束发送的巧妙设计 if ((tx_cnt == 4'd9) && (clk_cnt == BPS_CNT - (BPS_CNT/16))) tx_flag <= 1'b0;3. 环回系统实现细节
3.1 数据流控制机制
环回模块的核心是握手机制。曾遇到接收数据丢失的情况,后来发现是发送忙信号检测不及时。改进后的状态机如下:
always @(posedge clk) begin case(state) WAIT_DATA: if(recv_done_flag) state <= PREP_SEND; PREP_SEND: if(!tx_busy) begin send_en <= 1'b1; state <= WAIT_DATA; end endcase end3.2 时钟域同步策略
当接收和发送使用不同时钟时(比如125MHz系统时钟和USB转串口的12MHz时钟),必须采用异步FIFO。Xilinx FPGA可以直接调用IP核,但在Altera平台需要手动实现格雷码转换:
// 二进制转格雷码 assign wr_ptr_gray = (wr_ptr >> 1) ^ wr_ptr;4. 调试实战经验
4.1 常见故障排查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 接收数据错位 | 波特率偏差超过3% | 重新计算分频系数 |
| 随机误码 | 信号地未共接 | 检查PCB接地回路 |
| 只能收不能发 | 流控信号被拉死 | 禁用硬件流控 |
4.2 在线调试技巧
推荐使用虚拟逻辑分析仪(如SignalTap),我通常这样配置触发条件:
- 触发深度:4K samples
- 触发位置:50% pre-trigger
- 关键信号:uart_rxd下降沿 + rx_flag上升沿
最近用DSLogic逻辑分析仪抓取的实测波形显示,在115200波特率下,每个bit持续8.68μs(50MHz时钟下434个周期)。这个数据对精确调整采样点非常关键。
5. 性能优化方向
5.1 波特率自适应算法
在多变环境中,可以借鉴Modem的波特率检测算法:通过测量起始位宽度自动校准。核心代码如下:
// 起始位宽度测量 always @(negedge uart_rxd) begin start_cnt <= 0; end always @(posedge clk) begin if(!uart_rxd) start_cnt <= start_cnt + 1; end5.2 硬件加速方案
对于高速应用(如1Mbps以上),建议:
- 使用过采样技术(16x oversampling)
- 添加硬件CRC校验
- 采用DMA传输减少CPU开销
在Xilinx Zynq平台上,配合PS端DMA控制器,实测传输速率可达3Mbps,比纯PL实现提升40%以上。