將數碼管各段發光元件的正極連在一起稱為共陽數碼管,且該共點擊鏈接電路電源的正極,而各段的負極連接驅動電路。它適用於低電平有效的驅動電路,當某段的驅動電平為低電平時,該段發亮;將數碼管各段發光元件的負極連在一起稱為共陰數碼管,且該電平連接電源的負極,而各段元件的正極驅動電路,它適用於高電平有效的驅動電路,當某段的驅動電平為高電平,該段發光。
1.數碼管的動態顯示 驅動多位數碼管需要動態掃描顯示,假如是8位數碼管顯示,則需要先設計一個計數器,8位計數器,不斷掃描。動態掃描顯示時刷新頻率最好大於50HZ,即顯示一輪的時間不要超過20ms,每個數碼管顯示時間不能太長也不能太短,時間太長會影響刷新頻率,導致整體出現閃爍的現象,時間太短發生二極管的電流導通時間也就短,會影響總體的顯示亮度。一般控制在1ms左右。
module seg(clk,wei,duan);//50MHZ時鍾輸入,duan:數碼管位嗎,wei:數碼管段碼,‘0’led亮 input clk; output [7:0]wei; output [7:0]duan; reg [7:0]wei; reg [7:0]duan; integer count;//分頻計數器,每計數到50000下clk_1k時鍾翻轉 reg clk_1k;//數碼管掃描時鍾2ms reg [2:0]wei_count;//位碼計數器 always @(posedge clk)//分頻進程 begin if(count==500000) begin count=0; clk_1k=~clk_1k; end else count=count+1; end always @(posedge clk_1k)//數碼管掃描進程 begin case(wei_count) 3'b000: begin wei=8'b11111110; duan=8'b0000_0000;wei_count=wei_count+1'b1;end 3'b001: begin wei=8'b11111101; duan=8'b0000_0000;wei_count=wei_count+1'b1;end 3'b010: begin wei=8'b11111011; duan=8'b0000_0000;wei_count=wei_count+1'b1;end 3'b011: begin wei=8'b11110111; duan=8'b0000_0000;wei_count=wei_count+1'b1;end 3'b100: begin wei=8'b11101111; duan=8'b0000_0000;wei_count=wei_count+1'b1;end 3'b101: begin wei=8'b11011111; duan=8'b0000_0000;wei_count=wei_count+1'b1;end 3'b110: begin wei=8'b10111111; duan=8'b0000_0000;wei_count=wei_count+1'b1;end 3'b111: begin wei=8'b01111111; duan=8'b0000_0000;wei_count=wei_count+1'b1;end endcase end endmodule
2.秒表數碼管顯示 :秒表的設計原理:首先通過分頻器產生一個頻率為1HZ的時鍾座位計數源,設置兩個寄存器分別用來存儲計數值,一個為寄存個位數,一個寄存十位數,同時同時產生一個數碼管位選時鍾,用來對數碼管的位選進行掃描。(0到60,秒表)
module second(clk,duan,wei);//clk:50MHZ時鍾輸入,duan:數碼管段碼,wei:數碼管位碼 input clk; output [7:0]duan; output [1:0]wei; reg [7:0]duan; reg [1:0]wei; integer count;//1HZ時鍾計數器 integer count2;//掃描時鍾計數器 reg clk_1hz;//1HZ時鍾信號 reg [3:0]ge;//數碼管個位數BCD碼 reg [2:0]shi;//數碼管十位BCD二進制碼 reg clk_scan;//數碼管掃描時鍾 reg select; always @(posedge clk)//1HZ時鍾進程 begin if(count==25000000) begin clk_1hz=~clk_1hz; count=0; end else count=count+1'b1; end always @(posedge clk_1hz)//秒表功能進程 begin if(ge==4'b1001) begin ge=4'b0000; if(shi==3'b101) shi=3'b000; else shi=shi+1'b1; end else ge=ge+1'b1; end always @(posedge clk)//數碼管掃描時鍾產生進程 begin if(count2==50000) begin count2=0; clk_scan=~clk_scan; end else count2=count2+1; end always @(posedge clk_scan) begin select=select+1'b1; end always @(ge or shi or select) begin if(select==1'b1) begin wei=2'b10;//秒表個位數顯示 case(ge) 4'b0000:begin duan=8'b1100_0000;end 4'b0001:begin duan=8'b1111_1001;end 4'b0010:begin duan=8'b1010_0100;end 4'b0011:begin duan=8'b1011_0000;end 4'b0100:begin duan=8'b1001_1001;end 4'b0101:begin duan=8'b1001_0010;end 4'b0110:begin duan=8'b1000_0011;end 4'b0111:begin duan=8'b1111_1000;end 4'b1000:begin duan=8'b1000_0000;end 4'b1001:begin duan=8'b1001_1000;end default duan=8'bx; endcase end else begin wei=2'b01;//秒表十位數顯示 case(shi) 3'b000:duan=8'b1100_0000; 3'b001:duan=8'b1111_1001; 3'b010:duan=8'b1010_0100; 3'b011:duan=8'b1011_0000; 3'b100:duan=8'b1001_1001; 3'b101:duan=8'b1001_0010; 3'b110:duan=8'b1000_0011; default duan=8'bx; endcase end end endmodule
3.時鍾數碼管顯示:首先通過分頻器產生一個頻率為1HZ的時鍾作為計數源,設置六個寄存器分別用來存儲豎直,時分秒各用兩個寄存器,一個為寄存個位數,另一個寄存十位數。當秒計數到達59時便向分進一,同時秒清零;當分計數達到59時,便向時進一,同時分清零;當時計數到達24時將時分秒計數寄存器同時清零。產生一個數碼管位選時鍾,用來對數碼管的位選進行掃描。
module time_clock(clk,duan,wei);//clk:50MHZ時鍾輸入,duan:數碼管段碼,wei:數碼管位碼 input clk; output [7:0]duan; output [5:0]wei; reg [7:0]duan; reg [5:0]wei; integer count;//1HZ時鍾計數器 integer count2;//掃描時鍾計數器 reg clk_1hz;//1HZ時鍾信號 reg [3:0]miao_ge;//秒個位數BCD碼 reg [2:0]miao_shi;//秒十位BCD二進制碼 reg [3:0]fen_ge;//分鍾個位數 reg [2:0]fen_shi;//分鍾十位數 reg [1:0]shi_ge;//時鍾個位數 reg [1:0]shi_shi;//時鍾十位數 reg clk_scan;//數碼管掃描時鍾 reg [2:0]select; //用於掃描時選擇顯示位碼 always @(posedge clk)//1HZ時鍾進程 begin if(count==25000000) begin clk_1hz<=~clk_1hz; count<=0; end else count<=count+1'b1; end always @(posedge clk_1hz)//秒分時各位累加功能進程 begin if(miao_ge==4'b1001) begin miao_ge<=4'b0000; if(miao_shi==3'b101) begin miao_shi<=3'b000; if(fen_ge==4'b1001) begin fen_ge<=4'b0000; if(fen_shi==3'b101) begin fen_shi<=3'b000; if(shi_ge==2'b11) begin shi_ge<=2'b00; if(shi_shi==2'b10) shi_shi<=2'b00; else shi_shi<=shi_shi+1'b1; end else shi_ge<=shi_ge+1'b1; end else fen_shi<=fen_shi+1'b1; end else fen_ge<=fen_ge+1'b1; end else miao_shi<=miao_shi+1'b1; end else miao_ge<=miao_ge+1'b1; end always @(posedge clk)//數碼管掃描時鍾產生進程 begin if(count2==10000) begin count2<=0; clk_scan<=~clk_scan; end else count2<=count2+1; end always @(posedge clk_scan) begin if(select==3'b110) select<=3'b000; else select<=select+1'b1; end always @(miao_ge or miao_shi or fen_ge or fen_shi or shi_ge or shi_shi or select)//敏感信號列表 begin if(select==3'b001) begin wei<=6'b111110;//秒個位數顯示 case(miao_ge) 4'b0000:begin duan<=8'b1100_0000;end 4'b0001:begin duan<=8'b1111_1001;end 4'b0010:begin duan<=8'b1010_0100;end 4'b0011:begin duan<=8'b1011_0000;end 4'b0100:begin duan<=8'b1001_1001;end 4'b0101:begin duan<=8'b1001_0010;end 4'b0110:begin duan<=8'b1000_0011;end 4'b0111:begin duan<=8'b1111_1000;end 4'b1000:begin duan<=8'b1000_0000;end 4'b1001:begin duan<=8'b1001_1000;end default duan<=8'bx; endcase end else if(select==3'b010) begin wei<=6'b111101;//秒十位數顯示 case(miao_shi) 3'b000:duan<=8'b1100_0000; 3'b001:duan<=8'b1111_1001; 3'b010:duan<=8'b1010_0100; 3'b011:duan<=8'b1011_0000; 3'b100:duan<=8'b1001_1001; 3'b101:duan<=8'b1001_0010; 3'b110:duan<=8'b1000_0011; default duan<=8'bx; endcase end else if(select==3'b011) begin wei<=6'b111011;//分鍾個位數顯示 case(fen_ge) 4'b0000:begin duan<=8'b1100_0000;end 4'b0001:begin duan<=8'b1111_1001;end 4'b0010:begin duan<=8'b1010_0100;end 4'b0011:begin duan<=8'b1011_0000;end 4'b0100:begin duan<=8'b1001_1001;end 4'b0101:begin duan<=8'b1001_0010;end 4'b0110:begin duan<=8'b1000_0011;end 4'b0111:begin duan<=8'b1111_1000;end 4'b1000:begin duan<=8'b1000_0000;end 4'b1001:begin duan<=8'b1001_1000;end default duan<=8'bx; endcase end else if(select==3'b100) begin wei<=6'b110111;//分鍾十位數顯示 case(fen_shi) 3'b000:duan<=8'b1100_0000; 3'b001:duan<=8'b1111_1001; 3'b010:duan<=8'b1010_0100; 3'b011:duan<=8'b1011_0000; 3'b100:duan<=8'b1001_1001; 3'b101:duan<=8'b1001_0010; 3'b110:duan<=8'b1000_0011; default duan<=8'bx; endcase end else if(select==3'b101) begin wei<=6'b101111;//時鍾個位數顯示 case(shi_ge) 4'b0000:begin duan<=8'b1100_0000;end 4'b0001:begin duan<=8'b1111_1001;end 4'b0010:begin duan<=8'b1010_0100;end 4'b0011:begin duan<=8'b1011_0000;end default duan<=8'bx; endcase end else begin wei<=6'b011111;//時鍾十位數顯示 case(shi_shi) 3'b000:duan<=8'b1100_0000; 3'b001:duan<=8'b1111_1001; 3'b010:duan<=8'b1010_0100; default duan<=8'bx; endcase end end endmodule