20180806 完成昨天的目标,把数码管弄好
昨天败在心态上了,虽然说鬼影现象很常见,玩单片机的时候玩过,要加一句消隐的代码就好了,当然,当时也没细想其中的原理。
从网上搜索资料以后,原因有:①扫描的频率不能太快,大概需要50Hz,②须保证数据准备好了再选通数码管。
因此,我的思路是,实现一个模块,专门用来显示:(图很粗略,反正给自己看的,不在意这些细节)
实现代码如下:
1 `timescale 1ns / 1ps 2 //数码管扫描显示 3 //相当于 分频器+多路选择器 4 module Scan_4( 5 input clk_in, 6 input [7:0] dat_in0, 7 input [7:0] dat_in1, 8 input [7:0] dat_in2, 9 input [7:0] dat_in3, 10 output reg [7:0] dat_out = 0, 11 output reg [3:0] seg 12 ); 13 14 //下面是分频器,得到50Hz的时钟,用于扫描(非常不准确) 15 parameter M = 100000; //1M 16 parameter W = 16; 17 18 reg [W:0] cnt = 0; 19 20 reg clk_50Hz = 0; 21 22 always@(posedge clk_in) begin 23 if(cnt == M)begin 24 cnt <= 0; 25 clk_50Hz = ~clk_50Hz; 26 end 27 else begin 28 cnt <= cnt + 1; 29 end 30 end 31 32 parameter [3:0] 33 S0 = 4'b0001, 34 S1 = 4'b0010, 35 S2 = 4'b0100, 36 S3 = 4'b1000, 37 SX = 4'b0000; 38 39 //下面是扫描部分与多路选择器部分 40 reg [3:0] _seg = S0; //内部计数器 41 42 always@(posedge clk_50Hz)begin 43 //采用阻塞模式 44 seg = SX; 45 case(_seg) 46 S0:begin 47 dat_out = dat_in0; 48 seg = _seg; 49 _seg = S1; 50 end 51 S1:begin 52 dat_out = dat_in1; 53 seg = _seg; 54 _seg = S2; 55 end 56 S2:begin 57 dat_out = dat_in2; 58 seg = _seg; 59 _seg = S3; 60 end 61 S3:begin 62 dat_out = dat_in3; 63 seg = _seg; 64 _seg = S0; 65 end 66 default://异常状况处理 67 begin 68 dat_out = dat_in0; 69 seg = _seg; 70 _seg = S0; 71 end 72 endcase 73 end 74 75 endmodule
效果如下:
不弄这块板子了,换个话题玩玩。一堆Warning看得我发慌。