EGO1开发板实战:FPGA串口通信与交互式显示系统设计
1. 项目概述与硬件准备
在嵌入式系统开发中,串口通信是最基础也最实用的通信方式之一。EGO1开发板搭载Xilinx Artix-7 FPGA芯片,为初学者提供了理想的硬件平台来探索数字系统设计。本项目将实现一个完整的交互式系统:通过拨码开关设置数据,按键触发发送,数码管实时显示,同时支持接收外部串口数据并可视化。
硬件清单:
- EGO1开发板(XC7A35T-1CSG324C FPGA)
- USB转串口模块(如CH340)
- 7段数码管(开发板已集成)
- 8位拨码开关(开发板已集成)
- 5个独立按键(开发板已集成)
注意:确保开发板供电稳定,USB数据线连接可靠。建议使用官方提供的12V电源适配器而非仅依赖USB供电,特别是在同时使用多个外设时。
2. Vivado工程搭建与环境配置
2.1 创建新工程
启动Vivado 2022.1,按照以下步骤创建项目:
- 选择"Create Project"向导
- 指定工程名称和存储路径(避免中文路径)
- 选择"RTL Project"类型
- 添加现有HDL文件或创建新文件
- 在"Default Part"中选择:xc7a35tcsg324-1
# 示例Tcl命令创建工程 create_project uart_demo ./uart_demo -part xc7a35tcsg324-1 set_property board_part digilentinc.com:arty-a7-35:part0:1.0 [current_project]2.2 时钟配置
EGO1板载50MHz晶振,我们需要分频得到UART通信所需的时钟:
| 时钟信号 | 频率 | 用途 | 分频系数 |
|---|---|---|---|
| clk | 50MHz | 系统主时钟 | - |
| clk_1ms | 1kHz | 按键消抖 | 50,000 |
| clk_x | 9.6kHz | 发送波特率 | 5,208 |
| clk_16x | 153.6kHz | 接收采样 | 326 |
// 分频模块核心代码 always @(posedge clk) begin if(cnt1 == 26'd50000) begin clk_1ms <= ~clk_1ms; cnt1 <= 0; end else cnt1 <= cnt1 + 1; end3. 系统架构设计与关键模块
3.1 顶层模块设计
系统采用模块化设计,主要功能单元包括:
- 时钟分频模块:生成各单元所需时钟信号
- 按键消抖模块:消除机械按键抖动
- 数码管驱动模块:动态扫描显示
- UART发送模块:串行数据发送
- UART接收模块:串行数据接收
module v_uart( input clk, input [7:0] sw, // 拨码开关输入 input [4:0] btn, // 按键输入 output [7:0] seg, // 段码输出 output [7:0] an, // 位选输出 output txd, // 串口发送 input rxd // 串口接收 ); // 各模块实例化 divclk u_div (.*); // 时钟分频 v_smg u_disp (.*); // 数码管显示 v_ajxd u_btn (.*); // 按键消抖 uart_tx u_tx (.*); // 发送模块 uart_rx u_rx (.*); // 接收模块 endmodule3.2 数码管显示驱动
采用动态扫描方式驱动4位数码管,主要技术要点:
- 扫描频率:约200Hz(每位数码管点亮时间约1.25ms)
- 显示编码:共阴极数码管段码表
- 数据缓冲:双缓冲设计避免显示闪烁
// 数码管段码表(0-F) parameter [7:0] SEG_TABLE [0:15] = { 8'hfc, 8'h60, 8'hda, 8'hf2, // 0-3 8'h66, 8'hb6, 8'hbe, 8'he0, // 4-7 8'hfe, 8'hf6, 8'hee, 8'h3e, // 8-B 8'h9c, 8'h7a, 8'h9e, 8'h8e // C-F };4. UART通信实现细节
4.1 发送模块设计
UART发送状态机包含以下状态:
- IDLE:等待发送触发
- START:发送起始位(0)
- DATA0-DATA7:依次发送8位数据
- STOP:发送停止位(1)
关键参数:
- 波特率:9600bps
- 数据格式:8位数据,无校验,1位停止位
- 发送时钟:精确的9.6kHz
// 发送状态机核心片段 always @(posedge clk_x) begin case(state) IDLE: if(btn_press) begin txd <= 1'b0; // 起始位 state <= DATA0; end DATA0: begin txd <= data[0]; state <= DATA1; end // ... 其他数据位 STOP: begin txd <= 1'b1; state <= IDLE; end endcase end4.2 接收模块设计
接收模块采用16倍过采样技术,提高抗干扰能力:
- 起始位检测:下降沿触发
- 数据采样:在每个数据位中点采样(第7、23、39...个采样点)
- 校验处理:可选奇偶校验
- 帧结束检测:停止位验证
提示:实际项目中建议添加超时机制,防止因干扰导致状态机卡死。
5. 调试技巧与常见问题
5.1 信号完整性检查
调试UART通信时,建议按照以下顺序验证:
- 时钟信号:用示波器测量各分频时钟频率
- 发送信号:确认TX引脚波形符合UART时序
- 按键响应:检查消抖后的按键信号
- 数码管扫描:观察位选信号切换频率
5.2 典型问题排查
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 发送数据错误 | 波特率不匹配 | 检查时钟分频系数 |
| 接收不稳定 | 采样点偏移 | 调整过采样位置 |
| 数码管闪烁 | 扫描频率过低 | 提高刷新率至200Hz以上 |
| 按键响应迟钝 | 消抖时间过长 | 优化消抖参数 |
# 使用minicom测试串口(Linux) minicom -D /dev/ttyUSB0 -b 96006. 功能扩展与进阶应用
完成基础功能后,可以考虑以下增强功能:
- 协议封装:在UART基础上实现自定义应用层协议
- 数据缓冲:添加FIFO缓冲提高通信可靠性
- 多设备通信:通过板载PMOD接口扩展多个UART设备
- 无线传输:结合蓝牙/WiFi模块实现无线串口
性能优化方向:
- 使用FPGA内置的OSERDES实现高速串行通信
- 采用DMA方式减轻CPU负担
- 实现硬件流控(RTS/CTS)
// FIFO缓冲示例代码 module uart_fifo #(parameter WIDTH=8, DEPTH=16) ( input clk, rst, input wr_en, rd_en, input [WIDTH-1:0] din, output [WIDTH-1:0] dout, output full, empty ); reg [WIDTH-1:0] mem [0:DEPTH-1]; reg [4:0] wptr, rptr; // ... FIFO控制逻辑 endmodule7. 实际应用案例
在工业控制领域,类似的UART通信系统可用于:
- 设备监控:采集传感器数据并通过串口上传
- 人机交互:通过拨码开关设置参数,数码管显示状态
- 固件升级:通过串口实现现场程序更新
- 调试接口:输出系统运行日志和调试信息
一个典型的应用场景是温控系统:拨码开关设置目标温度,数码管显示当前温度,通过串口与上位机通信记录温度曲线。这种设计既保留了传统硬件接口的直观性,又具备了现代通信能力。