嵌入式-手把手教你基于 FPGA 的 8×8×8 3D 光立方设计(光立方、数字电路) 本项目基于 Altera Cyclone EP1C3T144C8 FPGA 开发板,驱动一个 8×8×8 LED 光立方 ,实现多种动态显示效果。系统采用 Verilog HDL 描述,结构清晰,适合作为 FPGA 入门到综合实战的参考案例。
一、项目简介 3D 光立方是由 512 颗 LED 组成的三维点阵显示装置。通过控制每一层(排)、每一列、每一行的亮灭,可以在三维空间中显示文字、图案、动画等效果。
本设计特点:
主控芯片:EP1C3T144C8 FPGA
光立方规模:8×8×8,共 512 颗 LED
驱动方式:行/列锁存 + 排选通,配合 74HC573 锁存器与三极管扩流
交互方式:5 个按键切换 5 种显示模式
辅助显示:6 位数码管用于模式指示
二、系统架构
整个系统由以下几部分组成:
模块
功能说明
5V 电源适配器
为 FPGA 开发板和光立方驱动电路供电
EP1C3T144C8 FPGA
系统主控,负责按键检测、扫描时序、显示数据生成
按键电路
5 个独立按键,用于切换显示模式
硬件驱动电路
将 FPGA 输出信号转换为可驱动 LED 的电流/电压
行驱动电路(74HC573)
锁存行数据
列驱动电路(74HC573)
锁存列数据
排驱动电路(三极管放大)
功率放大,逐层选通
8×8×8 光立方
三维 LED 点阵显示终端
三、硬件设计要点 1. 主控 FPGA 采用 EP1C3T144C8 ,属于 Altera Cyclone 一代低成本 FPGA,逻辑资源充足,适合中小规模数字系统设计。板载 50MHz 有源晶振,为整个系统提供时钟。
2. 驱动电路
行/列驱动 :使用 74HC573 八位锁存器。FPGA 输出数据先送入锁存器,再通过锁存信号稳定输出,避免扫描过程中的闪烁。
排驱动 :由于 8 排 LED 同时点亮时电流较大,使用三极管进行功率放大,确保每排 LED 都能获得足够驱动电流。
扫描策略 :通过快速轮询每一排,利用人眼视觉暂留效应,实现三维图案的连续显示。
3. 按键与数码管
5 个独立按键连接到 FPGA GPIO,配合软件消抖实现模式切换。
6 位数码管用于辅助显示当前模式编号,方便调试与演示。
四、软件设计 项目采用模块化设计,主要包含以下 Verilog 模块:
模块名
文件
功能
rst_gen
rst_gen.v
上电复位,延时释放复位信号
key_xd
key_xd.v
按键消抖,输出单脉冲有效信号
key_xd_top
key_xd_top.v
顶层模块,扫描控制与显示数据生成
smg_drv
smg_drv.v
数码管驱动,显示 0~9 数字
1. 复位模块 rst_gen 上电后计数到 16'hffff 再释放复位信号,确保系统稳定启动。
module rst_gen( input clk, output reg rst_n ); reg [15 :0 ] cnt = 0 ; always @(posedge clk) begin if (cnt == 16'hffff ) ; else cnt <= cnt + 1 ; end always @(posedge clk) begin if (cnt == 16'hffff ) rst_n <= 1 ; else rst_n <= 0 ; end endmodule
2. 按键消抖模块 key_xd 采用状态机实现 20ms 延时消抖,检测到有效按键后输出一个高脉冲。
module key_xd( input rst_n, input key_in, input clk, output reg key_out ); parameter IDLE = 4'd0 ; parameter ST0 = 4'd1 ; parameter ST1 = 4'd2 ; parameter ST2 = 4'd3 ; parameter time_20ms = 1000000 ; reg [3 :0 ] curr_st; reg [19 :0 ] wait_cnt; reg key_in_ff1; reg key_in_ff2; always @(posedge clk) key_in_ff1 <= key_in; always @(posedge clk) key_in_ff2 <= key_in_ff1; always @(posedge clk or negedge rst_n) begin if (!rst_n) curr_st <= IDLE; else case (curr_st) IDLE: if (key_in_ff2 == 0 ) curr_st <= ST0; ST0: if (wait_cnt == time_20ms) curr_st <= ST1; ST1: curr_st <= ST2; ST2: if (key_in_ff2) curr_st <= IDLE; default : ; endcase end always @(posedge clk or negedge rst_n) begin if (!rst_n) wait_cnt <= 0 ; else if (curr_st == ST0) wait_cnt <= wait_cnt + 1 ; else wait_cnt <= 0 ; end always @(posedge clk or negedge rst_n) begin if (!rst_n) key_out <= 0 ; else if (curr_st == ST1) key_out <= ~key_in_ff2; else key_out <= 0 ; end endmodule
3. 数码管驱动 smg_drv 用于验证按键计数,每按一次键数码管显示数字加 1,循环显示 0~9。
module smg_drv( input clk, input rst_n, input key_in, output [7 :0 ] smg_seg, output [5 :0 ] smg_bit ); reg [3 :0 ] cnt; reg [7 :0 ] en_code; always @(posedge clk or negedge rst_n) begin if (!rst_n) cnt <= 0 ; else if (key_in && cnt == 9 ) cnt <= 0 ; else if (key_in) cnt <= cnt + 1 ; end always @(posedge clk or negedge rst_n) begin if (!rst_n) en_code <= 0 ; else case (cnt) 0 : en_code <= 8'hc0 ; 1 : en_code <= 8'hf9 ; 2 : en_code <= 8'ha4 ; 3 : en_code <= 8'hb0 ; 4 : en_code <= 8'h99 ; 5 : en_code <= 8'h92 ; 6 : en_code <= 8'h82 ; 7 : en_code <= 8'hf8 ; 8 : en_code <= 8'h80 ; 9 : en_code <= 8'h90 ; default : ; endcase end assign smg_seg = en_code; assign smg_bit = 6'h00 ; endmodule
4. 顶层模块 key_xd_top 顶层模块负责:
实例化复位、按键、数码管等子模块
根据按键切换 5 种显示模式
产生行/列/排扫描时序
输出对应 LED 点阵数据
module key_xd_top( input clk, input [4 :0 ] key_in, output reg [7 :0 ] row, output reg [7 :0 ] col, output reg [7 :0 ] line, output [7 :0 ] smg_seg, output [5 :0 ] smg_bit ); wire rst_n; rst_gen Urst_gen(.clk (clk), .rst_n (rst_n)); wire key1_signal, key2_signal, key3_signal, key4_signal, key5_signal; key_xd key_xd1(.rst_n (rst_n), .key_in (key_in[0 ]), .clk (clk), .key_out (key1_signal)); key_xd key_xd2(.rst_n (rst_n), .key_in (key_in[1 ]), .clk (clk), .key_out (key2_signal)); key_xd key_xd3(.rst_n (rst_n), .key_in (key_in[2 ]), .clk (clk), .key_out (key3_signal)); key_xd key_xd4(.rst_n (rst_n), .key_in (key_in[3 ]), .clk (clk), .key_out (key4_signal)); key_xd key_xd5(.rst_n (rst_n), .key_in (key_in[4 ]), .clk (clk), .key_out (key5_signal)); reg [31 :0 ] line_scan_counter; reg [7 :0 ] line_counter; reg [31 :0 ] col_scan_counter; reg [7 :0 ] col_counter; reg [31 :0 ] row_scan_counter; reg [7 :0 ] row_counter; reg [7 :0 ] row_data[31 :0 ]; reg [7 :0 ] col_data[31 :0 ]; reg [7 :0 ] line_data[31 :0 ]; reg [3 :0 ] show_mode; always @(posedge clk or negedge rst_n) begin if (!rst_n) show_mode <= 3'd0 ; else if (key3_signal) show_mode <= 3'd0 ; else if (key2_signal) show_mode <= 3'd1 ; else if (key1_signal) show_mode <= 3'd2 ; else if (key4_signal) show_mode <= 3'd3 ; else if (key5_signal) show_mode <= 3'd4 ; end always @(posedge clk or negedge rst_n) begin if (!rst_n) line_scan_counter <= 1'b0 ; else if (line_scan_counter == 32'd12_499_999 ) line_scan_counter <= 1'b0 ; else line_scan_counter <= line_scan_counter + 1'b1 ; end always @(posedge clk or negedge rst_n) begin if (!rst_n) line_counter <= 1'b0 ; else if (line_counter == 8'd32 ) line_counter <= 1'b0 ; else if (line_scan_counter == 32'd12_499_999 ) line_counter <= line_counter + 1'b1 ; end always @(posedge clk or negedge rst_n) begin if (!rst_n) begin row <= 1'b0 ; col <= 1'b0 ; line <= 1'b0 ; end else begin row <= row_data[row_counter]; col <= col_data[col_counter]; line <= line_data[line_counter]; end end smg_drv Usmg_drv( .clk (clk), .rst_n (rst_n), .key_in (key1_signal), .smg_seg (smg_seg), .smg_bit (smg_bit) ); endmodule
完整的数据数组部分较长,已随工程资料一起提供。每种模式通过预置 32 组行/列/排数据,实现不同的 3D 显示效果。
五、显示模式说明 通过 5 个按键可以切换以下 5 种显示模式:
模式
效果描述
模式 0
一面一面显示,类似流水灯效果
模式 1
整体闪烁
模式 2
按排闪烁
模式 3
按排闪烁(另一种图案)
模式 4
按排闪烁(第三种图案)
六、设计总结 本项目从硬件到软件完整地实现了一个基于 FPGA 的 3D 光立方控制系统。关键设计思路包括:
分层扫描 :利用视觉暂留效应,通过快速轮询每一排实现三维显示。
锁存器驱动 :使用 74HC573 稳定行/列数据,避免扫描干扰。
状态机消抖 :按键模块采用状态机实现可靠的 20ms 消抖。
模块化代码 :顶层 + 子模块的结构便于维护和功能扩展。
如果你想在此基础上扩展,可以尝试:
增加更多显示模式(如旋转立方体、文字滚动)
通过串口或 SPI 接收上位机发送的图案数据
改用 PWM 调光实现亮度分级
资料下载 工程包含 FPGA 源码、原理图 PDF、PCB PDF 以及 Gerber 文件,可用于复刻或二次开发。 通过网盘分享的文件:基于FPGA的3D光立方设计 链接: https://pan.baidu.com/s/1zFOKximZglFEJwcjK9mDkw?pwd=h4wq 提取码: h4wq