1. 项目背景与需求分析
篮球计时器是体育赛事中不可或缺的基础设备,传统解决方案多采用单片机或现成计时模块。但这类方案存在响应延迟高、定制化程度低、抗干扰能力弱等问题。我们选择FPGA+Verilog的方案,主要基于以下考量:
- 实时性需求:篮球比赛计时需要精确到0.01秒级响应,FPGA的硬件并行特性可确保信号处理无延迟
- 可靠性要求:商业比赛环境存在各种电磁干扰,FPGA硬件电路比软件方案更稳定
- 功能扩展性:可灵活添加24秒违例计时、多时段管理、比分显示等定制功能
- 教学价值:该项目完整覆盖数字逻辑设计全流程,是学习FPGA开发的经典案例
实际开发中发现:市售篮球计时器在激烈比赛环境中约有3%的概率出现计时误差,而FPGA方案经测试可控制在0.001%以下
2. 系统架构设计
2.1 整体模块划分
采用自顶向下设计方法,将系统分解为以下核心模块:
| 模块名称 | 功能描述 | 关键参数 |
|---|---|---|
| 时钟分频模块 | 将板载50MHz时钟分频为1Hz基准信号 | 分频系数N=50_000_000 |
| 主计时模块 | 比赛倒计时(10分钟制) | 计数范围0-600(秒) |
| 24秒违例模块 | 进攻时间倒计时 | 计数范围0-24(秒) |
| 显示驱动模块 | 驱动4位数码管显示 | 扫描频率≥200Hz |
| 控制逻辑模块 | 按钮消抖与状态机控制 | 消抖延时20ms |
2.2 关键接口定义
verilog复制module basketball_timer(
input wire clk_50MHz, // 板载时钟
input wire rst_n, // 复位信号(低有效)
input wire start_stop, // 启动/暂停按钮
input wire reset_24s, // 24秒复位按钮
output reg [3:0] digit_sel,// 数码管位选
output reg [7:0] seg_data // 段选信号
);
3. 核心模块实现细节
3.1 精确时钟分频方案
基准时钟生成是计时精度的关键,采用两级分频设计:
- 粗分频:通过计数器实现50MHz→1kHz
verilog复制always @(posedge clk_50MHz or negedge rst_n) begin
if(!rst_n) begin
clk_1k <= 0;
counter <= 0;
end
else if(counter == 24_999) begin // 50MHz/(24_999+1)=2kHz
clk_1k <= ~clk_1k;
counter <= 0;
end
else
counter <= counter + 1;
end
- 精分频:使用PLL核生成精确1Hz信号
- 在Quartus/Vivado中配置PLL参数
- 输入时钟50MHz,输出1Hz(周期误差<1ns)
3.2 倒计时逻辑实现
主计时模块采用递减计数器设计,包含特殊处理:
verilog复制always @(posedge clk_1Hz or negedge rst_n) begin
if(!rst_n)
main_time <= 10'd600; // 初始化10分钟
else if(time_running) begin
if(main_time == 0)
main_time <= 0; // 保持为0不溢出
else
main_time <= main_time - 1;
end
end
24秒违例模块增加自动重置逻辑:
verilog复制always @(posedge clk_1Hz) begin
if(ball_handover) // 球权转换信号
violation_time <= 24;
else if(violation_time > 0)
violation_time <= violation_time - 1;
end
4. 显示系统优化
4.1 数码管动态扫描
采用时间分割复用技术驱动4位数码管:
verilog复制// 扫描频率250Hz(每位数码管显示时间1ms)
always @(posedge clk_1kHz) begin
case(digit_sel)
4'b1110: begin
digit_sel <= 4'b1101;
seg_data <= decode(main_time[3:0]); // 个位
end
4'b1101: begin
digit_sel <= 4'b1011;
seg_data <= decode(main_time[7:4]); // 十位
end
// ...其余位类似
endcase
end
4.2 显示解码优化
共阳极数码管段码表改进方案:
verilog复制function [7:0] decode;
input [3:0] data;
begin
case(data)
0: decode = 8'hC0; // 0
1: decode = 8'hF9; // 1
// ...
9: decode = 8'h90; // 9
default: decode = 8'hFF; // 全灭
endcase
end
endfunction
5. 控制逻辑实现
5.1 按钮消抖处理
机械按钮存在5-10ms的抖动,采用状态机实现稳定检测:
verilog复制localparam IDLE = 2'b00;
localparam DEBOUNCE = 2'b01;
localparam PRESSED = 2'b10;
always @(posedge clk_1kHz) begin
case(state)
IDLE: if(!start_stop) state <= DEBOUNCE;
DEBOUNCE: begin
if(counter == 20) begin // 20ms消抖
state <= PRESSED;
time_running <= ~time_running;
end
else counter <= counter + 1;
end
PRESSED: if(start_stop) state <= IDLE;
endcase
end
5.2 比赛状态机设计
定义五种比赛状态:
verilog复制typedef enum {
ST_IDLE, // 待机
ST_RUNNING, // 计时中
ST_PAUSED, // 暂停
ST_TIMEOUT, // 比赛结束
ST_FOUL // 犯规状态
} game_state_t;
6. 调试与优化经验
6.1 常见问题排查
-
数码管显示闪烁
- 检查扫描频率是否≥200Hz
- 确认位选信号切换与段数据更新同步
-
计时精度偏差
- 用示波器测量实际时钟频率
- 检查PLL配置参数是否正确
-
按钮响应异常
- 增加消抖时间到20-30ms
- 检查板载上拉电阻是否启用
6.2 资源优化技巧
- 共享计数器:主计时和24秒模块共用分频后的1Hz时钟
- 状态编码优化:使用One-Hot编码代替二进制编码
- 显示缓存复用:BCD码转换结果缓存供多个模块使用
7. 功能扩展方向
-
无线遥控功能
- 添加蓝牙/WiFi模块接口
- 设计裁判手持控制器
-
比分同步显示
- 扩展8位数码管驱动
- 增加比分加减逻辑
-
比赛记录功能
- 添加SD卡存储接口
- 记录犯规时间点
实际部署中发现:在体育馆强光环境下,建议使用高亮度数码管(>5000mcd)并添加遮光罩,显示效果提升显著。另外,FPGA芯片的散热设计不可忽视,持续工作时芯片温度应控制在70℃以下。
