1. 程式人生 > >verilog數碼管驅動顯示

verilog數碼管驅動顯示

實現功能:讓4個數碼管每隔1s不斷遞增計數顯示,計數範圍為0-F(十六進位制)。

片選訊號:本例中是將公共端接到FPGA的I/O引腳上,這是數碼管片選訊號,如果這個I/O引腳輸出低電平0,那麼這個數碼管就能夠顯示數字,輸出高電平1時,關閉。

每個數碼管段選訊號:為了便於編寫7個用於段選(不包括小數點,所以7個)的發光二極體顯示不同字元,對應表如下。

數字/字元

0

1

2

3

4

5

6

7

編碼(十六進位制)

3f

06

5b

4f

66

6d

7d

07

數字/字元

8

9

A

B

C

D

E

F

編碼(十六進位制)

7f

6f

77

7c

39

5e

79

71

實現原理:首先使用一個24位 的計數器產生1s的週期定時,4位的十六進位制顯示資料沒秒遞增。數碼管的4位片選訊號分時選中,在單獨選中某個位時,它所對應的顯示資料將進行譯碼後送往seg_db段選輸出訊號。雖然是分時分別選中4個數碼管位,但是由於人眼的視覺暫留效果,實際上看上去好像是同時點亮所顯示的4位資料。

邏輯功能設計框圖:

實現verilog程式碼如下:

module ex5(
	clk,rst_n,
	seg_db,seg_cs
);
input clk;
input rst_n;
output reg[7:0] seg_db;
output reg[3:0] seg_cs;
//------------------------------------//

reg[24:0] cnt;

[email protected](posedge clk or negedge rst_n)
	if(!rst_n) cnt<=25'd0;
	else if(cnt>=25'd25_000_000) cnt<=25'd0;
	else cnt<=cnt+1'b1;

wire timer_1s=(cnt==25'd25_000_000);           //1s定時標誌位,高電平有效一個時鐘週期

//---------------------------------------//
reg[15:0] dis_db;							//顯示到數碼管的4個十六進位制資料
[email protected]
(posedge clk or negedge rst_n) if(!rst_n) dis_db<=16'd0; else if(timer_1s) dis_db<=dis_db+1'b1; else; //-------------------------------------------// //------分時分別選中4個數碼管位,但是由於人眼的視覺暫留效果, //實際上看上去好像是同時點亮所顯示的4位資料-------// reg[3:0] cur_dis_db; //4位暫存器,用以快取當前數碼管的片選位對應的1個十六進位制資料。 [email protected](posedge clk or negedge rst_n) if(!rst_n) cur_dis_db<=4'd0; else begin case(cnt[7:6]) 2'b00:begin seg_cs<=4'b1110; cur_dis_db<=dis_db[3:0]; end 2'b01:begin seg_cs<=4'b1101; cur_dis_db<=dis_db[7:4]; end 2'b10:begin seg_cs<=4'b1011; cur_dis_db<=dis_db[11:8]; end 2'b11:begin seg_cs<=4'b0111; cur_dis_db<=dis_db[15:12]; end endcase end //-----------------------------------------------------// parameter SEG_NUM0=8'h3f, //c0 SEG_NUM1=8'h06, //f9 SEG_NUM2=8'h5b, //a4 SEG_NUM3=8'h4f, //b0 SEG_NUM4=8'h66, //99 SEG_NUM5=8'h6d, //92 SEG_NUM6=8'h7d, //82 SEG_NUM7=8'h07, //f8 SEG_NUM8=8'h7f, //80 SEG_NUM9=8'h6f, //90 SEG_NUMA=8'h77, //88 SEG_NUMB=8'h7c, //83 SEG_NUMC=8'h39, //c6 SEG_NUMD=8'h5e, //a1 SEG_NUME=8'h79, //86 SEG_NUMF=8'h71; //8e [email protected](cur_dis_db)begin //將數碼管的十六進位制資料譯碼成數碼管的實際段選值 case(cur_dis_db) 4'h0:seg_db<=SEG_NUM0; 4'h1:seg_db<=SEG_NUM1; 4'h2:seg_db<=SEG_NUM2; 4'h3:seg_db<=SEG_NUM3; 4'h4:seg_db<=SEG_NUM4; 4'h5:seg_db<=SEG_NUM5; 4'h6:seg_db<=SEG_NUM6; 4'h7:seg_db<=SEG_NUM7; 4'h8:seg_db<=SEG_NUM8; 4'h9:seg_db<=SEG_NUM9; 4'ha:seg_db<=SEG_NUMA; 4'hb:seg_db<=SEG_NUMB; 4'hc:seg_db<=SEG_NUMC; 4'hd:seg_db<=SEG_NUMD; 4'he:seg_db<=SEG_NUME; 4'hf:seg_db<=SEG_NUMF; default:; endcase end endmodule