实验 03:数码管静态显示
🛒 开发板: EK301 GW5A FPGA 开发板
一、实验目的
- 理解共阴数码管的工作原理:段码高电平(亮)、公共阴极接 GND。
- 掌握 74LVC2G17 缓冲芯片 + 510R 限流电阻 + SS8050 位选驱动的硬件配合。
- 学习 BCD 码到 7 段码的译码逻辑,掌握
case语句实现组合逻辑译码器。 - 学会模块化设计:
seg_decoder译码子模块 +top顶层例化。
二、实验过程
2.1 硬件连接
| 信号 | 方向 | FPGA 引脚 | Bank | 说明 |
|---|---|---|---|---|
| F_SEG_A | 输出 | P12 | Bank 4 | 段码 A,经 74LVC2G17+510R |
| F_SEG_B | 输出 | T12 | Bank 4 | 段码 B |
| F_SEG_C | 输出 | P11 | Bank 4 | 段码 C |
| F_SEG_D | 输出 | R11 | Bank 4 | 段码 D |
| F_SEG_E | 输出 | N10 | Bank 4 | 段码 E |
| F_SEG_F | 输出 | R10 | Bank 4 | 段码 F |
| F_SEG_G | 输出 | G8 | Bank 0 | 段码 G |
| F_SEG_DOT | 输出 | T11 | Bank 4 | 小数点 DP |
| F_SEL1 | 输出 | U16 | Bank 4 | 位选1 (SS8050) |
| F_SEL2~6 | 输出 | V16/V15/U15/N9/V9 | Bank 4/5 | 位选2~6 |
2.2 共阳数码管原理
A
---
F | | B
| G |
---
E | | C
| D |
--- * DP
- 共阳:8 个 LED 的阳极全部连到 VCC(经 SS8050 控制)。
- 要点亮某一段 → 阴极(段码)输出低电平,阳极输出高电平。
- 段码值
0= 亮,1= 灭(与共阴相反)。
显示 "3" 时的段码:A=0, B=0, C=0, D=0, E=1, F=1, G=0, DP=1
→ seg = {1, 0, 1, 1, 0, 0, 0, 0} = 8'b1011_0000
2.3 模块设计
系统框图:
top.v (seg_static)
├─ seg_decoder.v ← BCD→段码译码
├─ seg[7:0] 输出 ← 段码
└─ sel[5:0] 输出 ← 位选 (固定=000001)
段码译码器 (seg_decoder.v):
| 输入 digit[3:0] | 输出 seg[7:0] | 显示 |
|---|---|---|
| 0 | 1100_0000 | "0" |
| 1 | 1111_1001 | "1" |
| 2 | 1010_0100 | "2" |
| ... | ... | ... |
| 9 | 1001_0000 | "9" |
| 10-15 | 1111_1111 | 全灭 |
顶层 (top.v):
- 输入
clk(本实验未使用,预留用于后续动态扫描) - 输出
seg[7:0]:段码(接 74LVC2G17 → 510R → 数码管段) - 输出
sel[5:0]:位选(1=选中,三极管驱动),固定6'b000001,仅第 1 位亮 DISP_DIGIT参数控制显示数字(0-9)
2.4 段码译码 Verilog 实现
always @(*) begin
case (digit)
4'd0: seg = 8'b1100_0000; // DP=1(灭),G=1,E=1,F=1, 其余0(亮)
4'd1: seg = 8'b1111_1001;
// ... 0-9
default: seg = 8'b1111_1111; // 非法值全灭
endcase
end
always @(*) 是纯组合逻辑,综合为 LUT 查找表。default 分支防止生成锁存器。
三、代码讲解
3.1 段码译码器 (seg_decoder.v)
always @(*) begin
case (digit)
4'd3: seg = 8'b1_0_1_1_0_0_0_0; // "3": A,B,C,D,G=0亮
digit=3(4'b0011) →seg={DP,G,F,E,D,C,B,A}={1,0,1,1,0,0,0,0}- A=0(亮), B=0(亮), C=0(亮), D=0(亮), E=1(灭), F=1(灭), G=0(亮)
- 最终效果:数码管显示 "3"
3.2 顶层 (top.v)
localparam DISP_DIGIT = 4'd3; // 固定显示"3"
assign sel = 6'b000001; // 仅第1位选中
seg_decoder u_seg (.digit(DISP_DIGIT), .seg(seg)); // 例化译码器
四、实验现象
| 操作 | 预期结果 |
|---|---|
| 上电 | 第 1 位数码管稳定显示数字 "3" |
| 其余 5 位 | 不亮(位选未使能) |
修改 DISP_DIGIT = 0 | 重新下载后显示 "0" |
修改 DISP_DIGIT = 8 | 重新下载后显示 "8"(全部段亮) |
验证要点:
- ✅ 显示 "3" 时,A/B/C/D/G 段亮,E/F 段灭。
- ✅ 显示 "8" 时,全部 7 段亮(不含 DP)。
- ✅ 亮度均匀,无闪烁。
- ✅ 段码译码表 0-9 全部正确。
五、掌握知识点
| 知识点 | 说明 | 体现 |
|---|---|---|
| 共阳数码管 | 阳极 VCC,段码低有效 | seg 中 0=亮 1=灭 |
| 7 段码 | 7 段 LED 组成数字显示 | A-G 7 段 + DP |
| case 语句 | 多路选择组合逻辑 | case(digit) 9 个分支 |
| 模块例化 | 子模块复用 | seg_decoder u_seg(...) |
| SS8050 驱动 | NPN 三极管共阳位选 | sel=1 → 三级管导通 → VCC |
附录:源码
top.v
// =============================================================================
// EK301 实验03: 数码管静态显示 (共阴数码管)
// 芯片: GW5A-LV25UG324C1/I0 | 时钟: 50MHz (T9)
// 功能: 6位共阴数码管中第1位固定显示数字"3"
// 段码经74LVC2G17缓冲+510R限流, 位选SS8050驱动
// 共阴: 段码=1亮, 位选=1选中(三极管驱动)
// =============================================================================
module seg_static (
input wire clk, // 50MHz (T9)
output wire [7:0] seg, // 段码 {DP,G,F,E,D,C,B,A}, 1=亮
output wire [5:0] sel // 位选 [5:0], 1=选中(三极管驱动)
);
// ---- 固定显示数字 (可修改此参数切换显示) ----
localparam DISP_DIGIT = 4'd3; // 显示"3", 修改0-9切换
// ---- 仅选择第1位数码管 (共阴: 0=选中) ----
assign sel = 6'b000001; // SEL1=1选中(三极管导通), 其余5位=0不选
// ---- 例化段码译码器 (共阴版) ----
seg_decoder u_seg (
.digit(DISP_DIGIT),
.seg (seg)
);
endmodule
seg_decoder.v
// =============================================================================
// EK301 实验05: 数码管静态显示 — 段码译码器 (共阴数码管)
// 功能: 4-bit BCD码 → 8位段码 (1=亮, 0=灭)
// 段码位序: {DP, G, F, E, D, C, B, A}
// 共阴: 公共阴极接GND,段码高电平有效(亮)
// =============================================================================
module seg_decoder (
input wire [3:0] digit, // BCD码 (0-9有效, 10-15全灭)
output reg [7:0] seg // 段码 {DP,G,F,E,D,C,B,A}, 1=亮
);
always @(*) begin
case (digit)
// DP G F E D C B A
4'd0: seg = 8'b0_0_1_1_1_1_1_1; // 0: A,B,C,D,E,F亮
4'd1: seg = 8'b0_0_0_0_0_1_1_0; // 1: B,C亮
4'd2: seg = 8'b0_1_0_1_1_0_1_1; // 2: A,B,D,E,G亮
4'd3: seg = 8'b0_1_0_0_1_1_1_1; // 3: A,B,C,D,G亮
4'd4: seg = 8'b0_1_1_0_0_1_1_0; // 4: B,C,F,G亮
4'd5: seg = 8'b0_1_1_0_1_1_0_1; // 5: A,C,D,F,G亮
4'd6: seg = 8'b0_1_1_1_1_1_0_1; // 6: A,C,D,E,F,G亮
4'd7: seg = 8'b0_0_0_0_0_1_1_1; // 7: A,B,C亮
4'd8: seg = 8'b0_1_1_1_1_1_1_1; // 8: 全部亮
4'd9: seg = 8'b0_1_1_0_0_1_1_1; // 9: A,B,C,D,F,G亮
default: seg = 8'b0_0_0_0_0_0_0_0; // 全灭 (非法输入)
endcase
end
endmodule