FPGA開發(八)----------數碼管顯示實驗3-數字前0的消除

         上一篇文章我們使用模塊的方式實現了計數器,但是我們看到在計數器前的零全部顯示,這在我們的日常生活中是不太符合邏輯的,因爲我們通常沒有這些0。本次實驗我們將這些0不顯示。

         首先,我們來思考,消除這些0我們需要在顯示模塊中設置一個標誌位,如果標誌位爲1,那麼我們就顯示0,如果標誌位爲0,那麼我們不顯示即可。關於標誌位的判斷,按照我們的常識,當這一位是0時,如果該位之前的位不全部爲0,那麼我們需要顯示該0,這一位之前全部都是0,那麼我們不顯示該0。如果該位不爲0,正常顯示即可。按照上述邏輯,我們做出以下修改。

        1.將顯示模塊num_show增加一個輸入zero_en 參數,在0顯示是檢測該標誌位是否爲1,判斷是否顯示。

        2.將計數模塊num_cnt增加一個輸入參數zero_en1,一個輸出參數zero_en2。zero_en1用來連接高位輸出的zero_en2,同時將本模塊的zero_en2,連接至和本模塊連接的num_show模塊的zero_en參數。在num_cnt模塊中判斷如何本模塊的數據不是0,那麼輸出標誌位zero_en2=1,如果當前位是0,檢測上一位傳入的標誌位zero_en1是否爲1,如果是1 ,那麼zero_en2=1,否則zero_en2=0。即可。

         計數器模塊num_cn的代碼如下

/*
	Author:Alawyssun
	Time:2020/03/25
	實現功能:完成一個計數器模塊 
	計數器輸入: 1 進位脈衝
					2 時鐘信號和復位信號 
	計數器輸出:1 當前計數值
				  2 當前是否有進位信號
	
*/

module num_cnt(
	input rst,//復位信號
	input clk,//時鐘信號
	input en,//使能信號 每使能一次計數加一
	input zero_en1,
	output reg zero_en2,
	output reg pulse,//輸出進位信號 傳給下一個計數器
	output reg[3:0] data//當前保存的數據

);

always@(posedge clk)
begin
	if(data!=0)
	begin
		zero_en2<=1;
	end
	else
	begin
		if(zero_en1!=0)
		begin
			zero_en2<=1;
		end
		else
		begin
			zero_en2<=0;
		end
	end
end

always@(posedge clk) 
begin  
	if(rst==0)//按下復位鍵 
	begin
		data<=4'd0;//計數器和輸出全爲0
		pulse<=1'd0;
	end
	if(en)//如果有進位輸入
	begin 
		if(data==4'd9)//如果此時計數值已經達到9,那麼將進位標誌位設置爲1 同時數據清零
		begin
			pulse<=1'b1;
			data<=4'd0;
		end		
		else //如果計數值不是9 那麼計數值自己加一 同時進位標誌位爲0 
		begin
			pulse<=1'b0;
			data<=data+4'd1;
		end
	end
	else
	begin
		pulse<=1'b0;
	end 
end

endmodule

        顯示模塊的代碼如下

/*
	Author:Alawyssun
	Time:2020/03/25
	實現功能:輸入一個數字轉換成對應的數碼管編碼
	輸入:data 輸入的參數
	輸出:seg_data輸出對應的數碼管的編碼
*/

module num_show(
	input[3:0]data,
	input zero_en,
	output reg[7:0]seg_data
	
);
/*
		4'ha:seg_data <= 8'b1000_1000;
		4'hb:seg_data <= 8'b1000_0011;
		4'hc:seg_data <= 8'b1100_0110;
		4'hd:seg_data <= 8'b1010_0001;
		4'he:seg_data <= 8'b1000_0110;
		4'hf:seg_data <= 8'b1000_1110;
*/
always@(*)
begin
	case(data)
		4'd0:
			if(zero_en)
			begin
				seg_data <= 8'b1100_0000;
			end
			else
			begin
				seg_data <= 8'b1111_1111;
			end	
		4'd1:seg_data <= 8'b1111_1001;
		4'd2:seg_data <= 8'b1010_0100;
		4'd3:seg_data <= 8'b1011_0000;
		4'd4:seg_data <= 8'b1001_1001;
		4'd5:seg_data <= 8'b1001_0010;
		4'd6:seg_data <= 8'b1000_0010;
		4'd7:seg_data <= 8'b1111_1000;
		4'd8:seg_data <= 8'b1000_0000;
		4'd9:seg_data <= 8'b1001_0000;
		default:seg_data <= 8'b1111_1111;
	endcase
end

endmodule

         掃描模塊的代碼如下

/*
	Author:Alawyssun
	Time:2020/03/25
	程序功能:實現數碼管的掃描顯示
	輸入:六個數碼管的輸出編碼數據
	輸出:掃描之後的數碼管段選和片選信號
*/
module num_scan(
	input clk,
	input rst,
	input[7:0] seg_data_scan_0,
	input[7:0] seg_data_scan_1,
	input[7:0] seg_data_scan_2,
	input[7:0] seg_data_scan_3,
	input[7:0] seg_data_scan_4,
	input[7:0] seg_data_scan_5,
	output reg[7:0] seg_data_scan,
	output reg[5:0] seg_sel
);
parameter SCAN_FREQ = 200;     //掃描的頻率
parameter CLK_FREQ = 50000000; //時鐘頻率
parameter SCAN_COUNT = CLK_FREQ /(SCAN_FREQ*7) - 1;//掃描一次 需要時鐘計數的個數

reg[31:0]time_cnt2;//時間計數器2 用作刷新數碼管的時鐘
reg[7:0] wei_cnt_clk;//判斷輸出哪一個數碼管

//數碼管刷新時間 計數
always@(posedge clk or negedge rst)
begin 
	if(rst==1'b0)
	begin
		time_cnt2<=32'd0;
	end
	else if(time_cnt2==SCAN_COUNT)
	begin
		time_cnt2<=32'd0;
		if(wei_cnt_clk==8'd7)
		begin
			wei_cnt_clk<=0;
		end
		else
		begin
			wei_cnt_clk<=wei_cnt_clk+1;
		end
	end
	else
	begin
		time_cnt2<=time_cnt2+32'd1;
	end
end

//數碼管顯示
always@(posedge clk or negedge rst)
begin 	
	if(rst == 1'b0)
	begin
		seg_sel <= 6'b000000;
		seg_data_scan <= 8'hff;
	end
	else
	begin
		case(wei_cnt_clk)//如果計時爲0 刷新第一個數碼管
		8'd0:
		begin
			seg_data_scan<=seg_data_scan_0;
			seg_sel=6'b01_1111;
		end
		8'd1:
		begin
			seg_data_scan<=seg_data_scan_1;
			seg_sel=6'b10_1111;
		end
		8'd2:
		begin
			seg_data_scan<=seg_data_scan_2;
			seg_sel=6'b11_0111;
		end
		8'd3:
		begin
			seg_data_scan<=seg_data_scan_3;
			seg_sel=6'b11_1011;
		end
		8'd4:
		begin
			seg_data_scan<=seg_data_scan_4;
			seg_sel=6'b11_1101;
		end
		8'd5:
		begin
			seg_sel <= 6'b11_1110;
			seg_data_scan <= seg_data_scan_5;
		end
		8'd6://消影
		begin
			seg_sel <= 6'b00_0000;
			seg_data_scan <= 8'hff;
		end
		endcase
	end
end


endmodule

        總體模塊的代碼如下

/*
	Author:Alawyssun
	Time:2020/03/25
	實現功能:利用模塊化的方法,實現六個數碼管顯示一個數字的功能
	該數字在時鐘的作用下,按一定的頻率自動加一  同時將數字之前的0消去
*/
`timescale 1n/1ps
module seg_test(
	input clk,
	input rst,
	output [5:0] seg_pi,//片選
	output [7:0] seg_data//數據位
);
reg[31:0] time_cnt;
reg one_hz;

parameter CLK_FREQ = 50_000_000; //時鐘頻率
parameter CNT_SECOND = 1;     //計數器加一需要的時間 比如1秒 就寫10  0.5秒就寫5
parameter CNT_NUMBER = CNT_SECOND*CLK_FREQ;     //計數器加一需要的時間

always@(posedge clk or negedge rst)
begin
	if(rst==1'b0)
	begin
		time_cnt<=32'd0;
	end
	else 
	begin
		if(time_cnt==32'd49_999_999)
		begin
			time_cnt<=32'd0;
			one_hz<=1'b1;
		end
		else
		begin
			time_cnt<=time_cnt+32'd1;	
			one_hz<=1'b0;
		end
	end
end

wire[3:0] count0;
wire t0;
wire[7:0] seg_data_0;
wire zero_my0,zero_my1,zero_my2,zero_my3,zero_my4,zero_my5;
num_cnt num_cnt0_my(
	 .rst  (rst),
    .clk    (clk),
    .en     (one_hz),
	 .zero_en1 (zero_my1),
	 .zero_en2 (zero_my0),
	 .pulse      (t0),
    .data   (count0)    
 );
num_show num_show0_my(
	.data (count0),
	.zero_en(zero_my0),
	.seg_data (seg_data_0)
);
 
wire[3:0] count1;
wire t1;
wire[7:0] seg_data_1;
num_cnt num_cnt1_my(
	 .rst  (rst),
    .clk    (clk),
    .en     (t0),
	 .zero_en1 (zero_my2),
	 .zero_en2 (zero_my1),
	 .pulse      (t1),
    .data   (count1)    
 );
num_show num_show1_my(
	.data (count1),
	.zero_en(zero_my1),
	.seg_data (seg_data_1)
);
 
wire[3:0] count2;
wire[7:0] seg_data_2;
wire t2;
num_cnt num_cnt2_my(
	 .rst  (rst),
    .clk    (clk),
    .en     (t1),
	 .zero_en1 (zero_my3),
	 .zero_en2 (zero_my2),
	 .pulse      (t2),
    .data   (count2)    
 );
num_show num_show2_my(
	.data (count2),
	.zero_en(zero_my2),
	.seg_data (seg_data_2)
);
 
wire[3:0] count3;
wire[7:0] seg_data_3;
wire t3;
num_cnt num_cnt3_my(
	 .rst  (rst),
    .clk    (clk),
    .en     (t2),
	 .zero_en1 (zero_my4),
	 .zero_en2 (zero_my3),
	 .pulse      (t3),
    .data   (count3)    
 );
num_show num_show3_my(
	.data (count3),
	.zero_en(zero_my3),
	.seg_data (seg_data_3)
);
 
wire[7:0] seg_data_4;
wire[3:0] count4;
wire t4;
num_cnt num_cnt4_my(
	 .rst  (rst),
    .clk    (clk),
    .en     (t3),
	 .zero_en1 (zero_my5),
	 .zero_en2 (zero_my4),
	 .pulse      (t4),
    .data   (count4)    
 );
num_show num_show4_my(
	.data (count4),
	.zero_en(zero_my4),
	.seg_data (seg_data_4)
);
 
wire[7:0] seg_data_5;
wire[3:0] count5;
wire t5;
num_cnt num_cnt5_my(
	 .rst  (rst),
    .clk    (clk),
    .en     (t4),
	 .zero_en1 (0),
	 .zero_en2 (zero_my5),
	 .pulse      (t5),
    .data   (count5)    
 );
num_show num_show5_my(
	.data (count5),
	.zero_en(zero_my5),
	.seg_data (seg_data_5)
);

num_scan num_scan_my(
	.clk (clk),
	.rst (rst),
	.seg_data_scan_0 (seg_data_0),
	.seg_data_scan_1 (seg_data_1),
	.seg_data_scan_2 (seg_data_2),
	.seg_data_scan_3 (seg_data_3),
	.seg_data_scan_4 (seg_data_4),
	.seg_data_scan_5 (seg_data_5),
	.seg_data_scan (seg_data),
	.seg_sel (seg_pi)
);
endmodule

        本次實驗結果如下,可以看到數字之前的0全部沒有顯示

        本次實驗的工程下載地址爲: https://download.csdn.net/download/qq_34020487/12270483

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章