1. 程式人生 > >FPGA動態掃描數碼管

FPGA動態掃描數碼管

功能:用兩個數碼管顯示0-99的數,每隔一秒加1。
由於數碼管的段選段是連在一起的,要想兩個數碼管顯示不一樣的值,就必須動態地掃描數碼管。因為人眼地時間解析度是20ms,只要掃描數碼管地的週期小於20ms,就可以使用殘影讓數碼管顯示數值,給人的感覺就是數碼管同時顯示了兩個數字。
使用到的模組:
1.查詢表,將數碼管要顯示的數值翻譯成數碼管的段選訊號,從低位到告位分別對應著hgfedcba
2.分頻模組,每隔1ms掃描一次數碼管,所以要一個1kHz的時鐘
3.用1kHz的訊號去掃描數碼管的位選端
4.獲取相應數碼管的顯示值
5.計數模組,產生0-99
頂層模組程式碼

module test_top(clk_50M,reset,select,seg);
	input clk_50M;
	input reset;
	output [1:0]select;
	output[7:0]seg;
	
	reg [7:0]datain;
	reg [25:0]cnt;//4999_9999計時1秒
	reg [3:0]gewei,shiwei;
	
	//產生datain
	
[email protected]
(posedge clk_50M,negedge reset) if(!reset)begin datain<=8'h00; gewei<=4'h0; shiwei<=4'h0; end else if(cnt==26'd4999_9999) begin if(shiwei>4'h9 && gewei>4'h9)begin gewei<=4'h0; shiwei<=4'h0; datain<={shiwei,gewei}; end else if( gewei>4'h9)begin gewei<=4'h0; shiwei<=shiwei+1'b1; datain<={shiwei,gewei}; end else begin gewei<=gewei+1'b1; shiwei<=shiwei; datain[3:0]<=gewei; end cnt<=26'd0; end else begin shiwei<=shiwei; gewei<=gewei; cnt<=cnt+1'b1; datain<=datain; end test0 u0( .clk_50M(clk_50M), .reset(reset), .datain(datain), .select(select), .seg(seg) ); endmodule

底層模組程式碼:

module test0(clk_50M,reset,datain,select,seg);
	input clk_50M,reset;
	input [7:0]datain;
	output [1:0]select;
	output reg [7:0]seg;
	reg [3:0]data_disp;
	
	//分頻時鐘,產生頻率為1k的時鐘
	reg [14:0]cnt;//24999
	reg clk_1k;
	[email protected](posedge clk_50M,negedge reset)
		if(!reset) begin
			cnt<=15'd0;
			clk_1k<=1'b0;
			end
		else if(cnt==24999) begin
			clk_1k<=~clk_1k;
			cnt<=0;
			end
		else begin
			clk_1k<=clk_1k;
			cnt<=cnt+1'b1;
			end
	//數碼管的位選
	reg [1:0]select_r;
	
[email protected]
(posedge clk_1k,negedge reset) if(!reset) begin select_r<=2'b10; end else begin case(select_r) 2'b10:select_r<=2'b01; 2'b01:select_r<=2'b10; default: select_r<=2'b10; endcase end assign select=select_r; //獲取相應數碼管的顯示值 [email protected](*) case(select_r) 2'b10:data_disp=datain[3:0]; 2'b01:data_disp=datain[7:4]; default:data_disp=4'h0; endcase //將顯示值通過查詢表翻譯成數碼管的段 [email protected](*) case(data_disp) 4'h0:seg=8'b11000000; 4'h1:seg=8'b11111001; 4'h2:seg=8'b10100100; 4'h3:seg=8'b10110000; 4'h4:seg=8'b10011001; 4'h5:seg=8'b10010010; 4'h6:seg=8'b10000010; 4'h7:seg=8'b11111000; 4'h8:seg=8'b10000000; 4'h9:seg=8'b10010000; default:seg=8'b11111111; endcase endmodule

這段程式碼還存在的問題:在0-10的顯示過程中,會執行兩輪0-9的顯示,才會顯示10,並且,在整十數顯示的時候,個位先不會有數字顯示,下一秒才顯示0,比如到了29,下一秒就應該顯示30,但是它是十位顯示3,個位不顯示,接下來的一秒,個位才顯示0,不知道是怎麼回事。我找到問題之後再來改正。