数码管的动态显示(三)

1.原理

data_reg寄存,只寄存符号位和数据位不包含小数点位。

动态数码管每个显示1ms,所以计数到5*10^4-1

为了将sel和seg同步,把sel打了一拍。

6位都使用到了可以这么计算,6位都显示的是数据。或者最高位显示的是小数点,低5位是数据,

因为数码管是共阳数码管,低电平才能点亮。

2.代码

2.1 seg_dynamic.v

module seg_dynamic(
	input wire 			sys_clk		,
	input wire 			sys_rst_n	,
	input wire[19:0] 	data		,
	input wire[5:0]		point		,
	input wire			sign		,
	input wire 			seg_en		,
	
	output reg[7:0]		seg			,//因为一个数码管包括小数点位有8位
	output reg[5:0]		sel //因为总共有6个数码管需要显示
);

parameter CNT_MAX=16'd499_99;

wire [3:0] unit;
wire [3:0] ten;
wire [3:0] hun;
wire [3:0] tho;
wire [3:0] t_tho;
wire [3:0] h_hun; //999_999需要这6个位
reg [23:0] data_reg;  //6个数码管,每个数码管是BCD码表示,一共有4位,因为上面的ten是4位
reg [15:0] cnt_1ms;//因为计数1ms
reg flag_1ms;
reg [2:0] cnt_sel; //因为要计数6个数码管表示一次扫描周期的结束
reg [5:0] sel_reg; //这个是位选信号,控制哪个数码管亮
reg [3:0] data_disp; //这是上面的data_reg的每个位数的拆分,控制它显示十六进制码
reg dot_disp;


always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		data_reg<=24'd0;
	else if((h_hun)||(point[5]))
		data_reg<={h_hun,t_tho,tho,hun,ten,unit};
	else if(((t_tho)||(point[4]))&&(sign==1'b0)) //sign=0就是要使用符号位的意思
		data_reg<={4'd11,t_tho,tho,hun,ten,unit};
	else if(((t_tho)||(point[4]))&&(sign==1'b1))
		data_reg<={4'd10,t_tho,tho,hun,ten,unit};	
	else if(((tho)||(point[3]))&&(sign==1'b0))
		data_reg<={4'd11,4'd11,tho,hun,ten,unit};	
	else if(((tho)||(point[3]))&&(sign==1'b1))
    	data_reg<={4'd11,4'd10,tho,hun,ten,unit};
	else if(((hun)||(point[2]))&&(sign==1'b0))
		data_reg<={4'd11,4'd11,4'd11,hun,ten,unit};
	else if(((hun)||(point[2]))&&(sign==1'b1))	
		data_reg<={4'd11,4'd11,4'd10,hun,ten,unit};
	else if(((ten)||(point[1]))&&(sign==1'b0))
		data_reg<={4'd11,4'd11,4'd11,4'd11,ten,unit};	
	else if(((ten)||(point[1]))&&(sign==1'b1))		
		data_reg<={4'd11,4'd11,4'd11,4'd10,ten,unit};	
	else if(((unit)||(point[0]))&&(sign==1'b0))
		data_reg<={4'd11,4'd11,4'd11,4'd11,4'd11,unit};	
	else 			
		data_reg<={4'd11,4'd11,4'd11,4'd11,4'd10,unit};	
		
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		cnt_1ms<=16'd0;
	else if(cnt_1ms==CNT_MAX)
		cnt_1ms<=16'd0;
	else
		cnt_1ms<=cnt_1ms+1'b1;
		
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		flag_1ms<=1'b0;
	else if(cnt_1ms==CNT_MAX-1'b1)
		flag_1ms<=1'b1;
	else
		flag_1ms<=1'b0;

always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		cnt_sel<=3'd0;
	else if((flag_1ms==1'b1)&&(cnt_sel==3'd5))
		cnt_sel<=3'd0;
	else if(flag_1ms==1'b1)
		cnt_sel<=cnt_sel+1'b1;
	else
		cnt_sel<=cnt_sel;
		
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		sel_reg<=6'd0;
	else if ((cnt_sel==3'd0)&&(flag_1ms==1'b1))
		sel_reg<=6'b000_001;
	else if(flag_1ms==1'b1)
		sel_reg<=sel_reg<<1;
	else
		sel_reg<=sel_reg;
		

always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		data_disp<=4'd0;
	else if((seg_en==1'b1)&&(flag_1ms==1'b1))
		case(cnt_sel)
			3'd0: data_disp<=data_reg[3:0];
			3'd1: data_disp<=data_reg[7:4];
			3'd2: data_disp<=data_reg[11:8];
			3'd3: data_disp<=data_reg[15:12];
			3'd4: data_disp<=data_reg[19:16];
			3'd5: data_disp<=data_reg[23:20];
			default: data_disp<=4'b0;
		endcase
	else
		data_disp<=data_disp;
		
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		dot_disp<=1'b1;
	else if(flag_1ms==1'b1)
		dot_disp<=~point[cnt_sel];
	else 
		dot_disp<=dot_disp;

always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)	
		seg<=8'd0;
	else 
		case(data_disp)
			4'd0: seg<={dot_disp,7'b100_0000};
			4'd1: seg<={dot_disp,7'b111_1001};
			4'd2: seg<={dot_disp,7'b010_0100};
			4'd3: seg<={dot_disp,7'b011_0000};
			4'd4: seg<={dot_disp,7'b011_1001};
			4'd5: seg<={dot_disp,7'b001_0010};
			4'd6: seg<={dot_disp,7'b000_0010};
			4'd7: seg<={dot_disp,7'b111_1000};
			4'd8: seg<={dot_disp,7'b000_0000};
			4'd9: seg<={dot_disp,7'b001_0000};
			4'd10: seg<=8'b1011_1111;//10就是符号,只显示中间的那条杠,因此是
			4'd11: seg<=8'b1111_1111;//就是显示0
			default:seg<=8'b1100_0000;
		endcase

always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)	
		sel<=6'd0;
	else
		sel<=sel_reg;

					
bcd_8421 bcd_8421_inst(
	.sys_clk	(sys_clk	)		,
	.sys_rst_n	(sys_rst_n)	,
	.data		(data		)	,
				
	.unit		(unit		)	,
	.ten		(ten		)		,
	.hun		(hun		)		,
    .tho		(tho		)		,
	.t_tho		(t_tho		)	,
    .h_hun      (h_hun    )
);

endmodule




2.2 tb_seg_dynamic.v

module tb_seg_dynamic();

reg 		sys_clk		;
reg 		sys_rst_n   ;
reg[19:0]  data		;
reg[5:0]	point		;
reg		sign		;
reg 		seg_en		;
     
wire[7:0] 	seg;			
wire[5:0]    sel;

initial 
	begin
		sys_clk=1'b1;
		sys_rst_n<=1'b0;
		data<=20'd0;
		point<=6'b000_000;
		sign<=1'b0;
		seg_en<=1'b0;
		#30
		sys_rst_n<=1'b1;
		data<=20'd98_76;
        point<=6'b000_010;
        sign<=1'b1;
        seg_en<=1'b1;
	end
	
always #10 sys_clk=~sys_clk;
defparam seg_dynamic_inst.CNT_MAX=20'd5;

seg_dynamic seg_dynamic_inst(
	.sys_clk	(sys_clk	)	,
	.sys_rst_n	(sys_rst_n),
	.data		(data		),
	.point		(point		),
	.sign		(sign		),
	.seg_en		(seg_en		),
                 
	.seg		(seg		)	,
	.sel        (sel      )
);
endmodule

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-03-22 01:18:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-22 01:18:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-22 01:18:02       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-22 01:18:02       20 阅读

热门阅读

  1. MATLAB中的符号计算是什么?如何使用它?

    2024-03-22 01:18:02       17 阅读
  2. P1170 兔八哥与猎人 Python

    2024-03-22 01:18:02       16 阅读
  3. 蓝桥集训之山峰和山谷

    2024-03-22 01:18:02       22 阅读
  4. 客户端渲染与服务端渲染(1)

    2024-03-22 01:18:02       15 阅读
  5. # termux连接云服务器

    2024-03-22 01:18:02       19 阅读
  6. ES查询小技能

    2024-03-22 01:18:02       19 阅读
  7. Python之Flask框架~消息闪现

    2024-03-22 01:18:02       17 阅读
  8. 使用Pytesseract进行OCR

    2024-03-22 01:18:02       19 阅读
  9. Mysql2-sql语句

    2024-03-22 01:18:02       20 阅读