【数码管】— 静态显示
基础:
一、数码管类型:
共阴、共阳
以共阳极为例:
二、段选、位选
段选:显示什么内容
位选:哪几位亮
三、74hc595芯片
是什么:8位串行输入、并行输出的位移缓存器
使用目的:减少IO口的使用
由于需要控制6个8段的数码管,于是一共需要6+8=14个IO口连接到FPGA上,但是使用74hc595芯片只需要使用4个IO口连接到FPGA上,这样就减少了10 个IO口
分别是下面4个IO口连接到FPGA上:
DS:与FPGA相连,获取数据
SHCP:移位寄存器时钟,将DS上的数据串行移入8位寄存器中
STCP:存储寄存器时钟,将8位寄存器中的数据写入存储器中
OE:将存储器的数据通过8个端口输出,8个端口与数码管相连
四、顶层框图
实践:
一、设计文件
底层模块1:位选、段选驱动模块
module seg_01 ( input sys_clk, input sys_rst_n, output reg [5:0]wei, output reg[7:0]duan ); reg [25:0] cnt_wait ; //时钟分频计数器 reg [3:0] num ; //数码管显示的十六进制数 parameter CNT_WAIT_MAX = 26'd49_999_999; //计数器最大值(1s) parameter SEG_0 = 8'b1100_0000, SEG_1 = 8'b1111_1001, SEG_2 = 8'b1010_0100, SEG_3 = 8'b1011_0000, SEG_4 = 8'b1001_1001, SEG_5 = 8'b1001_0010, SEG_6 = 8'b1000_0010, SEG_7 = 8'b1111_1000, SEG_8 = 8'b1000_0000, SEG_9 = 8'b1001_0000, SEG_A = 8'b1000_1000, SEG_B = 8'b1000_0011, SEG_C = 8'b1100_0110, SEG_D = 8'b1010_0001, SEG_E = 8'b1000_0110, SEG_F = 8'b1000_1110; parameter IDLE = 8'b1111_1111; //不显示状态 // 共阳极数码管,位选需要让6位拉高,段选低电平有效 //wei:选中六个数码管 always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) wei <= 6'b000000; else wei <= 6'b111111; //显示什么 always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) duan <= IDLE; else case(num) 4'd0: duan <= SEG_0; 4'd1: duan <= SEG_1; 4'd2: duan <= SEG_2; 4'd3: duan <= SEG_3; 4'd4: duan <= SEG_4; 4'd5: duan <= SEG_5; 4'd6: duan <= SEG_6; 4'd7: duan <= SEG_7; 4'd8: duan <= SEG_8; 4'd9: duan <= SEG_9; 4'd10: duan <= SEG_A; 4'd11: duan <= SEG_B; 4'd12: duan <= SEG_C; 4'd13: duan <= SEG_D; 4'd14: duan <= SEG_E; 4'd15: duan <= SEG_F; default:duan <= IDLE ; //闲置状态,不显示 endcase
//cnt_wait:0.5秒计数 always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) cnt_wait <= 26'd0; else if(cnt_wait == CNT_WAIT_MAX) cnt_wait <= 26'd0; else cnt_wait <= cnt_wait + 1'b1; //num:从 4'h0 加到 4'hf 循环 always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) num <= 4'd0; else if(cnt_wait == CNT_WAIT_MAX - 1'b1) num <= num + 1'b1; else num <= num; endmodule
底层模块2:控制74HC595芯片
module seg_595 ( input clk , input rst_n , input [5:0] wei , input [7:0] duan , output reg ds , output reg shcp , output reg stcp , output oe ); wire [13:0] data ; reg [1:0] cnt_4 ; reg [3:0] cnt_bit_14 ; assign data = {duan[0],duan[1],duan[2],duan[3],duan[4],duan[5],duan[6],duan[7],wei}; assign oe = 1'b0; // 4分频计数器 always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) cnt_4 <= 2'b0 ; else if(cnt_4 == 2'd3) cnt_4 <= 2'b0 ; else cnt_4 <= cnt_4 + 2'b1 ; end // 传输14位计数器 always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) cnt_bit_14 <= 4'b0; else if(cnt_bit_14 == 4'd13 && cnt_4 == 2'd3) cnt_bit_14 <= 4'b0; else if(cnt_4 == 2'd3) cnt_bit_14 <= cnt_bit_14 + 4'b1; else cnt_bit_14 <= cnt_bit_14; end // -------------------- 输出信号 ---------------------------------- always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) shcp <= 1'b0; else if(cnt_4>=2'd2) shcp <= 1'b1; //else if(cnt_4 == 2'b0) // shcp <= 1'b0; //else // shcp <= shcp; else shcp <= 1'b0; end always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) stcp <= 1'b0; else if(cnt_bit_14 == 4'd0 && cnt_4 == 2'd0) stcp <= 1'b1; else stcp <= 1'b0; end always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) ds <= 1'b0; else if(cnt_4 == 1'b0) ds <= data[cnt_bit_14]; else ds <= ds; end endmodule
顶层模块
module seg ( input clk , input rst_n , output ds , output shcp , output stcp , output oe ); wire[5:0]wei; wire[7:0]duan; seg_01 # ( .CNT_WAIT_MAX(24'd24) // 减小仿真时间 ) a1 ( .sys_clk(clk), .sys_rst_n(rst_n), .wei(wei), .duan(duan) ); seg_595 a2 ( .clk(clk) , .rst_n(rst_n) , .wei(wei) , .duan(duan) , .ds(ds) , .shcp(shcp) , .stcp(stcp) , .oe(oe) ); endmodule
二、测试文件
`timescale 1ns/1ns module tb_seg; reg clk; reg rst_n; wire ds; wire shcp; wire stcp; wire oe; initial begin clk = 1'b0; rst_n = 1'b0; #30; rst_n = 1'b1; end always #10 clk = ~ clk; seg b1 ( .clk(clk) , .rst_n(rst_n) , .ds(ds) , .shcp(shcp) , .stcp(stcp) , .oe(oe) ); endmodule
三、波形图
注意此时有两个模块之间的信号传输
怎么看这个波形图:
1.看a1模块的段选和位选变化,此处在cnt_wait技术到24后就清零,下一个时钟上升沿段选信号改变,与此同时a2模块的段选信号也发生改变
2.将a1模块传到a2模块的段选、位选信号拼接得到data: {duan[0],duan[1],duan[2],duan[3],duan[4],duan[5],duan[6],duan[7],wei}
3.看a2模块的ds输出信号,当cnt_4计到3后,下一个时钟周期就将data[cnt_bit_14] 检索到的值给ds
四、RTL图
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)