数字电子技术实验——数码管七段译码器、动态扫描显示、ModelSim仿真

在实验中,时常需要在数码管上显示数字。

此时,需要使用译码器将输入的信号进行转换,使得数码管能显示对应数字。

一、数码管七段译码器

数码管上每一位都可以显示一位数字,数字可以通过如图的(A、B、C、D、E、F、G)七段显示出来。

如要显示数字1,则使B、C段亮即可。

由于输入的信号是一位数字,所以需要将其译码为数码管需要的二进制段选信号。

七段译码器:将输入的四位二进制信号Data(0~9),译成数码管的七位段选信号codeout。

codeout[6]=a,codeout[5]=b......,codeout[0]=g。

module Test(codeout,Data);
	input[3:0] Data;    //4位输入信号
	output[6:0] codeout;//7位输出信号
	reg[6:0] codeout;   //输出变量数据类型为寄存器型
	always @(Data)      //用always块语句描述逻辑
	begin
		case(Data)//case多分支条件语句,按输入显示对应输出
			4'd0 : codeout = 7'b1111110;
			4'd1 : codeout = 7'b0110000;
			4'd2 : codeout = 7'b1101101;
			4'd3 : codeout = 7'b1111001;
			4'd4 : codeout = 7'b0110011;
			4'd5 : codeout = 7'b1011011;
			4'd6 : codeout = 7'b1011111;
			4'd7 : codeout = 7'b1110000;
			4'd8 : codeout = 7'b1111111;
			4'd9 : codeout = 7'b1111011;
			default : codeout = 7'bx;//其他输入情况
		endcase
	end
endmodule

通过改变Data的值,可以改变数码管显示的值。

二、数码管动态扫描

一、设计思路

有时候需要数码管在不同位显示不同的数字。

选择只在指定位置显示对应数字,一次显示一位数字,通过循环显示对应的几位数字,利用人眼的视觉暂留效应达到显示出多位不同数字。

此处举显示三位数字的例子。

当计数器值为0时,只在数码管第一位显示第一位数字;

当计数器值为1时,只在数码管第二位显示第二位数字;

当计数器值为2时,只在数码管第三位显示第三位数字;

计数器的值不断循环重复,数码管显示出三位数字。

需要增加位选信号[7:0]SEG,控制数码管亮的位置;模三计数器,循环计数k。

代码使用层次化设计,同时增加了前置分频器,将50MHz的时钟信号分成1000Hz的信号。

二、代码实现

顶层文件

module Test(en,clk,CLK,SEG,codeout,Data,k);
	input clk;				//50MHz时钟信号
	input en;				//使能信号
	output CLK;				//分频后信号
	output [7:0]SEG;		//位选信号
	output [6:0]codeout;	//数码管信号
	output [3:0]Data;		//显示数字
	output [1:0]k;			//计数器
	
	Test_1 t1(clk,CLK);	    //分频器50MHz->1000Hz(clk->CLK)
	
	Test_2 t2(CLK,k,en);	//模三计数器(由CLK控制k的值)
	
	Test_3 t3(k,Data);	    //数据选择器(由k控制Data的值)
	
	Test_4 t4(k,SEG);		//位选译码器(由k控制SEG的值)
	
	Test_5 t5(codeout,Data);	//接入七段译码器(将Data译码)
endmodule

模块1:分频器(也可以不要分频器,删除模块1和clk,直接将输入信号接入到CLK上也可)

module Test_1(clk,CLK);	//分频器
	input clk;	//50MHz输入
	output reg CLK = 1'd0;    //分频后CLK信号
	integer tmp = 0;    //计数
	
	always@(negedge clk)	//clk信号下降沿触发
	begin
		tmp <= tmp + 1;
		if(tmp >= 24999)	//每25000次取反一次
			begin
				CLK <= ~CLK;	//输出取反
				tmp <= 0;
			end
	end
endmodule

模块2:模三计数器

module Test_2(CLK,k,en);	//模3计数器
	input CLK,en;	//1000Hz,使能信号
	output reg [1:0]k = 2'b00;	//计数器值k
	
	always@(posedge CLK)
	begin
		if(en==1)	//en为1时才能正常显示	
		begin				//k取值为0,1,2
			if(k <= 2'd1)
				k <= k + 2'd1;		//小于2加一
			else
				k <= 2'd0;			//等于2取0
		end
	end
endmodule

模块三:数据选择器

module Test_3(k,Data);	//数据选择器
	input [1:0]k;	//计数器值k
	output reg[3:0]Data = 4'b0000;	//显示数字Data
	
	always@(k)
	begin
		case(k)	//显示123
			2'd0:Data<=4'd1;
			2'd1:Data<=4'd2;
			2'd2:Data<=4'd3;
		    default:Data<=4'bx;
		endcase
	end
endmodule

模块四:位选译码器

module Test_4(k,SEG);	//位选译码器
	input [1:0]k;	//计数器值k
	output reg[7:0]SEG = 8'b00000000;	//位选信号
	
	always@(k)
	begin
		case(k)
			2'd0:SEG<=8'b10000000;	//第一位亮
			2'd1:SEG<=8'b01000000;	//第二位亮
			2'd2:SEG<=8'b00100000;	//第三位亮
			default:SEG<=8'bx;
		endcase
	end
endmodule

模块五:七段译码器

module Test_5(codeout,Data);	//七段译码器
	input[3:0] Data;//4位输入信号
	output reg[6:0]codeout = 7'b1111110;	//7位输出信号
	
	always @(Data)//用always块语句描述逻辑
	begin
		case(Data)//case多分支条件语句,按输入显示对应输出
			4'd0 : codeout = 7'b1111110;
			4'd1 : codeout = 7'b0110000;
			4'd2 : codeout = 7'b1101101;
			4'd3 : codeout = 7'b1111001;
			4'd4 : codeout = 7'b0110011;
			4'd5 : codeout = 7'b1011011;
			4'd6 : codeout = 7'b1011111;
			4'd7 : codeout = 7'b1110000;
			4'd8 : codeout = 7'b1111111;
			4'd9 : codeout = 7'b1111011;
			default : codeout = 7'bx;//其他输入情况
		endcase
	end
endmodule

三、ModelSim仿真

使用ModelSim进行仿真。

注意:在程序文件中,对于reg型变量需要赋予初值,否则在波形图中可能会出现红色波(值未定)。

Test Bench文件

`timescale 1 ns/ 1 ns
module Test_vlg_tst();
reg clk;
reg en;
                                               
wire CLK;
wire [3:0]  Data;
wire [7:0]  SEG;
wire [6:0]  codeout;
wire [1:0]  k;
                          
Test i1 (   
	.CLK(CLK),
	.Data(Data),
	.SEG(SEG),
	.clk(clk),
	.codeout(codeout),
	.en(en),
	.k(k)
);
initial                                                
begin                                                  
	clk = 0;
	en = 1;
	#4000000    //延迟4ms关闭使能信号en 1ms,而后en=1
	en = 0;
	#1000000
	en = 1;
$display("Running testbench");                       
end                                                    
always#10 clk = ~clk;    //每10个时间单位翻转一次(即周期为20ns,频率50MHz)                                                                                         
endmodule

波形图

在CLK信号下:

k值在00,01,10中循环;

对应Data值为0001,0010,0011;

位选信号SEG分别表示第一位亮,第二位亮,第三位亮。

当en为1时,数码管正常显示三位数字;当en为0时,数码管只显示一位数字。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值