設計背景:
數碼管是一種半導體發光器件,其基本單元是發光二極管。數碼管在我們的許多設計中都又用到,數碼管的顯示原理簡單和顯示效果清晰在我們的工業中的到了廣泛的應用。
數碼管的應用很廣泛,涉及眾多領域,我們就拿數顯儀表這個領域來講,數顯儀表是數字式顯示儀表的簡稱,顯示器常用的有LED、LCD為顯示元件。
設計原理:
本次的設計是設計一個數碼管的顯示模,其設計原理圖如下:
數碼管顯示分為的動態和靜態顯示,為了讓人眼可以看清數碼管的顯示,我們一般驅動數碼管的頻率為1K - 10K 之間。
顧名思義,七段數碼管就是使用七段點亮的線段來拼成常見的數字和某些字母,這種顯示方式我們在數字電路中非常容易見到。再加上右下角顯示的小數點,實際上一個顯示單元包括了8根信號線。根據電路設計的不同,這些信號線可能高有效也可能低有效。我們通過FPGA控制這些線段的亮滅,達到顯示效果。
對于多個數碼管的顯示模塊,將每一個都連接到FPGA的管腳會耗用大量FPGA的管腳資源。因此我們同樣引入一種類似矩陣鍵盤的掃描方式。任何時刻我們只使用8根信號點亮一個數碼管,但是8個數碼管是隨著時鐘步調交替點亮的,只要時鐘的速度夠快,我們觀察到數碼管就好像幾個同時點亮一樣。
我們的開發板使用的動態顯示來循環掃描顯示。其原理圖如下所示:
如圖所示,我們的開發板使用的是六位共陽極數碼管,六個PNP型三極管分別作為六組數碼管電源的輸入開關,也就是我們常說的位選信號,PNP三極管為低電平導通,所以我們的位選信號低有效。在這里,為了節約FPGA的IO資源,我們把六個位選信號連接到了三八譯碼器74HC138D。
從我們的板子硬件原理圖上我們可以看清,我們的數碼管是紅陽極,就是是給一個低電平就是點亮數碼管的一個段,那么8段全部給8’b0000000那么數碼管顯示的就是8這個數字了,我們用的是循環顯示,是通過sel引腳來選擇哪一個數碼管亮,也就是說我們的sel的三位為3’b000的時候也就是選擇第一個數碼亮,3’b001第二個數碼管亮依次類推。
設計架構圖:
設計代碼:
頂層模塊
0moduleseg_x(clk,rst_n,sel,seg7);//頂層端口
1 inputclk; //輸入
2 inputrst_n;
3 output[2:0]sel; //輸出
4 output[7:0]seg7;
5
6 wire[23:0]num;
7
8 num_in num_in( //例化輸入模塊
9 .clk(clk),
10 .rst_n(rst_n),
11 .num(num)
12 );
13
14 seg seg( //例化數碼管模塊
15 .clk(clk),
16 .rst_n(rst_n),
17 .sel(sel),
18 .seg7(seg7),
19 .data_in(num)
20 );
21endmodule
設計模塊
0moduleseg(clk,rst_n,sel,seg7,data_in);//端口定義
1
2 inputclk;
3 inputrst_n;
4 input[23:0]data_in;//輸入6個燈的數據
5
6 outputreg[2:0]sel;
7 outputreg[7:0]seg7;
8
9 parameters0 =3'b000;
10 parameters1 =3'b001;
11 parameters2 =3'b010;
12 parameters3 =3'b011;
13 parameters4 =3'b100;
14 parameters5 =3'b101;
15
16 `defineT1ms 50_000 //定義1k的計數值
17 //`define T1ms 5
18 reg[15:0]count;
19 wireflag;
20 always@(posedgeclk ornegedgerst_n)
21 if(!rst_n)
22 begin
23 count <=15'b0;
24 end
25 else
26 if(count ==`T1ms-1)//計數到1MS
27 begin
28 count <=15'b0;
29 end
30 else
31 begin
32 count <=count +1'b1;
33 end
34
35 assignflag =(count ==`T1ms-1)?1'b1:1'b0;//標志位賦值
36
37 reg[2:0]state;
38 reg[3:0]num;
39 always@(posedgeclk ornegedgerst_n)
40 if(!rst_n)
41 begin
42 sel <=3'b0;
43 state <=3'b0;
44 num <=4'b0;
45 end
46 else
47 begin
48 case(state)
49 s0:begin
50 if(flag)
51 state <=s1;//亮第一個燈,給24位數據的 4位
52 else
53 begin
54 sel <=3'b000;
55 num <=data_in[23:20];
56 end
57 end
58 s1:begin
59 if(flag) ////亮第2個燈,給24位數據 的4位
60 state <=s2;
61 else
62 begin
63 sel <=3'b001;
64 num <=data_in[19:16];
65 end
66 end
67 s2:begin
68 if(flag) //亮第3個燈,給24位數據的 4位
69 state <=s3;
70 else
71 begin
72 sel <=3'b010;
73 num <=data_in[15:12];
74 end
75 end
76 s3:begin
77 if(flag) //亮第4個燈,給24位數據的4位
78 state <=s4;
79 else
80 begin
81 sel <=3'b011;
82 num <=data_in[11:8];
83 end
84 end
85 s4:begin
86 if(flag) //亮第5個燈,給24位數據的4位
87 state <=s5;
88 else
89 begin
90 sel <=3'b100;
91 num <=data_in[7:4];
92 end
93 end
94 s5:begin
95 if(flag) //亮第6個燈,給24位數據的4位
96 state <=s0;
97 else
98 begin
99 sel <=3'b101;
100 num <=data_in[3:0];
101 end
102 end
103 default:state <=s0;
104 endcase
105 end
106
107 always@(*) //數碼管的譯碼模塊
108 begin
109 case(num)
110 0:seg7 =8'b1100_0000;
111 1:seg7 =8'b1111_1001;
112 2:seg7 =8'b1010_0100;
113 3:seg7 =8'b1011_0000;
114 4:seg7 =8'b1001_1001;
115 5:seg7 =8'b1001_0010;
116 6:seg7 =8'b1000_0010;
117 7:seg7 =8'b1111_1000;
118 8:seg7 =8'b1000_0000;
119 9:seg7 =8'b1001_0000;
120 10:seg7 =8'b1000_1000;
121 11:seg7 =8'b1000_0011;
122 12:seg7 =8'b1100_0110;
123 13:seg7 =8'b1010_0001;
124 14:seg7 =8'b1000_0110;
125 15:seg7 =8'b1000_1110;
126 default:;
127 endcase
128 end
129endmodule
輸入模塊
0modulenum_in(clk,rst_n,num);//端口定義
1 inputclk;
2 inputrst_n;
3
4
5 output[23:0]num;
6
7 assignnum =24'h123456;//給輸入一個值,便于下次直接調用
8
9
10
11endmodule
測試模塊
0`timescale1ns/1ps//時間精度
1
2moduleseg_tb;
3 regclk; //端口定義
4 regrst_n;
5
6
7 wire[2:0]sel;
8 wire[7:0]seg7;
9
10 initialbegin
11 clk =1'b1;
12 rst_n =1'b0;
13
14 #100.1rst_n =1'b1;
15
16 #200000
17 $stop;
18
19 end
20 always#10clk =~clk;//模擬時鐘
21
22 seg_x seg_x_dut( //例化頂層模塊
23 .clk(clk),
24 .rst_n(rst_n),
25 .sel(sel),
26 .seg7(seg7)
27 );
28endmodule
仿真圖:
在仿真中我們可以看到我們的設計是正確的,第一個燈亮的是f9,也就是也就是對應數碼管顯示的是1,a4就是2,和我們的輸入是正確的。
-
FPGA
+關注
關注
1629文章
21748瀏覽量
603975 -
數碼管
+關注
關注
32文章
1882瀏覽量
91189
發布評論請先 登錄
相關推薦
評論