verilog數碼管驅動顯示
阿新 • • 發佈:2018-11-13
實現功能:讓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