一个数码管有八个引脚,控制八段二极管的亮灭,用以显示需要的数字。
当有N个数码管时,一个一个控制的话需要N x 8 个引脚,消耗资源较多。
因此可以利用动态显示的方案通过人眼的视觉暂留特性达到静态显示的效果(动态显示周期<20ms),只需N+8个引脚。节省了大量资源。(动态静显)
数码管动态显示的逻辑电路如下:
文章来源:https://www.toymoban.com/news/detail-444423.html
Verilog设计代码如下:文章来源地址https://www.toymoban.com/news/detail-444423.html
module digital_tube(//八个数码管显示 clk, reset, disp_num_all, dg_tube, tube_part ); input clk ; input reset ; input [31:0]disp_num_all ; output [7:0]dg_tube ; output [7:0]tube_part ; parameter one_dis_t = 25'd1_000_000 ;//每个晶体管显示时间(计数) reg [16:0]counter1 ; reg [2:0] counter2 ; always @ ( posedge clk or negedge reset )//分频 begin if (! reset ) counter1 <= 17'd0 ; else if ( (one_dis_t-1) <= counter1 ) counter1 <= 17'd0 ; else counter1 <= counter1 +1'b1 ; end always @ ( posedge clk or negedge reset )//循环 begin if (! reset ) counter2 <= 3'd0 ; else if ( (one_dis_t-1) <= counter1 ) counter2 <= counter2 +1'b1 ; end wire [3:0]disp_num_one ; //3-8译码器 控制哪个数码管显示 decoder_3_8 tube_select(//控制 .a(counter2[2] ), .b(counter2[1]), .c(counter2[0]), .out(dg_tube) ); //需要一个八选一选通器,对应哪个数码管显示什么内容 mux8 tube_display(//选通 .sel(counter2), .data(disp_num_all), .out(disp_num_one) ); //真值表对应显示数字 LUT_truth translator(//控制 .num(disp_num_one), .out(tube_part) ); endmodule
module decoder_3_8( a, b, c, out ); input a; input b; input c; output reg [7:0]out; always@(*)begin//等价于always({a,b,c})a是高位,c是低位 case({a,b,c}) 3'b000:out=8'b0000_0001; 3'b001:out=8'b0000_0010; 3'b010:out=8'b0000_0100; 3'b011:out=8'b0000_1000; 3'b100:out=8'b0001_0000; 3'b101:out=8'b0010_0000; 3'b110:out=8'b0100_0000; 3'b111:out=8'b1000_0000; endcase end endmodule
module mux8( sel, data, out ); input [2:0]sel ; input [31:0]data ; output reg [3:0]out ; always@(*) begin case(sel) 3'b000 : out = data[3:0] ; 3'b001 : out = data[7:4] ; 3'b010 : out = data[11:8] ; 3'b011 : out = data[15:12] ; 3'b100 : out = data[19:16] ; 3'b101 : out = data[23:20] ; 3'b110 : out = data[27:24] ; 3'b111 : out = data[31:28] ; endcase end endmodule
module LUT_truth( num, out ); input [3:0]num ; output reg [7:0]out ; always@(num) begin case(num) 4'h0 : out = 8'hc0 ; 4'h1 : out = 8'hf9 ; 4'h2 : out = 8'ha4 ; 4'h3 : out = 8'hb0 ; 4'h4 : out = 8'h99 ; 4'h5 : out = 8'h92 ; 4'h6 : out = 8'h82 ; 4'h7 : out = 8'hf8 ; 4'h8 : out = 8'h80 ; 4'h9 : out = 8'h90 ; 4'ha : out = 8'h88 ; 4'hb : out = 8'h83 ; 4'hc : out = 8'hc6 ; 4'hd : out = 8'ha1 ; 4'he : out = 8'h86 ; 4'hf : out = 8'h8e ; endcase end endmodule
`timescale 1ns / 1ns module digital_tube_tb(); reg clk ; reg reset ; reg [31:0]disp_num_all; wire [7:0]dg_tube ; wire [7:0]tube_part ; digital_tube #( .one_dis_t( 100 ) ) digital_tube_im(//八个数码管显示 clk, reset, disp_num_all, dg_tube, tube_part ); initial clk = 1 ; always #10 clk = ! clk ; initial begin reset = 0 ; disp_num_all = 32'd0 ; #201 ; reset = 1 ; #200 ; disp_num_all = 32'habb02525 ; #20000; disp_num_all = 32'h52520bba ; #30000; $stop; end endmodule
到了这里,关于数码管动态显示Verilog实现(参考小梅哥教程)(视觉暂留)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!