軟件:Vivado 2022.2
硬件:BASYS 3
設(shè)計(jì)描述:通過開發(fā)板上的四個(gè)按鍵,按下一次記數(shù)加一,分別由四個(gè)數(shù)碼管從左到右分別顯示四個(gè)按鍵記數(shù)情況。
例:
1.初始值為0000,意為無(wú)記數(shù)
2.當(dāng)按下第一個(gè)按鍵,記數(shù)加一,數(shù)碼管顯示1000
3.再次按下一第一個(gè)按鍵,記數(shù)加一,數(shù)碼管顯示2000
4.按下第二個(gè)按鍵9次,數(shù)碼管顯示2900,第二位記滿
5.當(dāng)再次按下第二個(gè)按鍵后,數(shù)碼管顯示2000
應(yīng)用原理:
1.按鍵去抖動(dòng):
????????通常的按鍵所用開關(guān)為機(jī)械彈性開關(guān),當(dāng)機(jī)械觸點(diǎn)斷開、閉合時(shí), 由于機(jī)械觸點(diǎn)的彈性作用,一個(gè)按鍵開關(guān)在閉合時(shí)不會(huì)馬上穩(wěn)定地接通,在斷開時(shí)也不會(huì)一下子斷開。因而在閉合及斷開的瞬間均伴隨有一連串的抖動(dòng) 。抖動(dòng)時(shí)間的長(zhǎng)短由按鍵的機(jī)械特性決定,一般為5ms~20ms。這是一個(gè) 很重要的時(shí)間參數(shù),在很多場(chǎng)合都要用到。按鍵穩(wěn)定閉合時(shí)間的長(zhǎng)短則是由操作人員的按鍵動(dòng)作決定的,一般為零點(diǎn)幾秒至數(shù)秒。鍵抖動(dòng)會(huì)引起一次按鍵被誤讀多次。為確保對(duì)按鍵的一次閉合僅作一次處理,必須去除鍵抖動(dòng)。????????
?
2.數(shù)碼管顯示:
????????共陽(yáng)極數(shù)碼管 :
????????共陽(yáng)極數(shù)碼管的8個(gè)發(fā)光二極管的陽(yáng)極(二極管正端)連接在一起。通常,公共陽(yáng)極接高電平(一般接電源),其它管腳接段驅(qū)動(dòng)電路輸出端。當(dāng)某段驅(qū)動(dòng)電路的輸出端為低電平時(shí),則該端所連接的字段導(dǎo)通并點(diǎn)亮。
????????共陰極數(shù)碼管:
????????通常,公共陰極接低電平(一般接地),其它管腳接段驅(qū)動(dòng)電路輸出端。當(dāng)某段驅(qū)動(dòng)電路的輸出端為高電平時(shí),則該端所連接的字段導(dǎo)通并點(diǎn)亮。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
設(shè)計(jì)思路:
按鍵掃描消抖延時(shí):
????????BASYS 3開發(fā)板W5引腳的時(shí)鐘為100MHZ,設(shè)計(jì)采用10ms的按鍵消抖,100MHz(0101_1111_0101_1110_0001_0000_0000)分頻記數(shù)得100Hz(1111_0100_0010_0100_0000)
????????即為10ms延時(shí)
數(shù)碼管顯示:
????????BASYS 3 數(shù)碼管的是共陽(yáng)極,所以引腳輸出為0時(shí)亮起。 按鍵記數(shù)每一位從0到9顯示,記滿9次歸零。
????????????????????????????????????????? ? ? ?共陽(yáng)極數(shù)碼管顯示(七位和八位)
共陽(yáng) | 七位(不包括小數(shù)點(diǎn)) | 八位 |
0 | 1000000 | 11000000 |
1 | 1111001 | 11111001 |
2 | 0100100 | 10100100 |
3 | 0110000 | 10110000 |
4 | 0011001 | 10011001 |
5 | 0010010 | 10010010 |
6 | 0000010 | 10000010 |
7 | 1111000 | 11111000 |
8 | 0000000 | 10000000 |
9 | 0010000 | 10010000 |
代碼示例:
按鍵消抖模塊:
module delay(clk,key,key_delay);
input clk;//100MHz
input key;//按鍵輸入
output key_delay;//按鍵消抖判斷輸出
reg key_delay;
reg[19:0] cnt1;//10ms延時(shí)20位記數(shù)
always@(posedge clk)//100Mhz
begin
if(key) //假如按鍵按下,按鍵按下為高電平
begin
if( cnt1==20'b1111_0100_0010_0100_0000 && key) //10ms
key_delay<=1; //延時(shí)后,如果key仍然為1,則key_delay輸出1,確認(rèn)按鍵按下
else begin
cnt1<= cnt1+1;key_delay<=0; // 否則輸出0,
end
end
else begin
cnt1<= 0 ; key_delay<= 0 ; //當(dāng)key不為1 時(shí),計(jì)數(shù)器清零,輸出0
end
end
endmodule
記數(shù)模塊:
module cnt_delay(key_delay,cnt);
input key_delay;
output reg [3:0]cnt;
always@(posedge key_delay ) //以按鍵作為時(shí)鐘信號(hào),實(shí)現(xiàn)計(jì)數(shù)
begin
if(cnt==4'b1001)
cnt<=0;
else
cnt<=cnt+1;
end
endmodule
主模塊:
module but_delay_cnt_4(clk,key1,key2,key3,key4,dig,seg);
input clk; //clk是Basys3板上時(shí)鐘100 MHz
input key1,key2,key3,key4;//按鈕1,2,3,4
output dig;
output seg;
reg[3:0] dig;//位選數(shù)碼管
reg[6:0] seg;//段選數(shù)碼管
wire key4_delay,key1_delay,key2_delay,key3_delay;//按鈕消抖按下輸出
reg [19:0] cnt;//延時(shí)計(jì)數(shù)器,100MHz/3KHz,
reg [15:0] seg_count;//按鍵掃描計(jì)數(shù)器
reg clk_ttt;//數(shù)碼管位選動(dòng)態(tài)掃描頻率,3KHz
reg [1:0]selcnt;//數(shù)碼管位選標(biāo)志位,0,1,2,3
reg [1:0]ain;//位選0123對(duì)應(yīng)的段選標(biāo)志位
wire [3:0]cnt1,cnt2,cnt3,cnt4;//段選轉(zhuǎn)換標(biāo)志位,0-9
//按鍵消抖,判斷按鍵按下
delay U1(.clk(clk),.key(key1),.key_delay(key1_delay));
delay U2(.clk(clk),.key(key2),.key_delay(key2_delay));
delay U3(.clk(clk),.key(key3),.key_delay(key3_delay));
delay U4(.clk(clk),.key(key4),.key_delay(key4_delay));
//判斷按鍵上調(diào)變,即為按鍵按下,記數(shù)加一
cnt_delay K1(.key_delay(key1_delay),.cnt(cnt1));
cnt_delay K2(.key_delay(key2_delay),.cnt(cnt2));
cnt_delay K3(.key_delay(key3_delay),.cnt(cnt3));
cnt_delay K4(.key_delay(key4_delay),.cnt(cnt4));
always @(posedge clk) //100MHz
begin
seg_count <= seg_count + 1;
if(seg_count==16'b1000_0010_0011_0101)//100MHz/33333Hz
begin
seg_count <=0;//清零
clk_ttt <= ~clk_ttt;//3KHz的動(dòng)態(tài)掃描頻率
end
end
always @(posedge clk_ttt)//位選標(biāo)志位隨3KHz頻率從0-3輪換
begin
selcnt <= selcnt + 1;//標(biāo)志位+1,11記滿后加一回到00
end
always @(selcnt) //位選信號(hào)控制
begin
case (selcnt)
2'b00: begin dig <= 4'b0111;ain <= 2'b00;end //1號(hào)數(shù)碼管顯示ain對(duì)應(yīng)的段碼
2'b01: begin dig <= 4'b1011;ain <= 2'b01;end
2'b10: begin dig <= 4'b1101;ain <= 2'b10;end
2'b11: begin dig <= 4'b1110;ain <= 2'b11;end
default: dig<=4'b1111;
endcase
end
always @(ain or cnt1 or cnt2 or cnt3 or cnt4)
begin
if (ain==2'b00)begin //1號(hào)數(shù)碼管
case({ain,cnt1})
6'b000000:seg <= 7'b1000000;
6'b000001:seg <= 7'b1111001;
6'b000010:seg <= 7'b0100100;
6'b000011:seg <= 7'b0110000;
6'b000100:seg <= 7'b0011001;
6'b000101:seg <= 7'b0010010;
6'b000110:seg <= 7'b0000010;
6'b000111:seg <= 7'b1111000;
6'b001000:seg <= 7'b0000000;
6'b001001:seg <= 7'b0010000;
default :seg <= 7'b1100000;
endcase
end
if (ain==2'b01)begin //2號(hào)數(shù)碼管
case({ain,cnt2})
6'b010000:seg <= 7'b1000000;
6'b010001:seg <= 7'b1111001;
6'b010010:seg <= 7'b0100100;
6'b010011:seg <= 7'b0110000;
6'b010100:seg <= 7'b0011001;
6'b010101:seg <= 7'b0010010;
6'b010110:seg <= 7'b0000010;
6'b010111:seg <= 7'b1111000;
6'b011000:seg <= 7'b0000000;
6'b011001:seg <= 7'b0010000;
default :seg <= 7'b1010000;
endcase
end
if (ain==2'b10)begin //3號(hào)數(shù)碼管
case({ain,cnt3})
6'b100000:seg <= 7'b1000000;
6'b100001:seg <= 7'b1111001;
6'b100010:seg <= 7'b0100100;
6'b100011:seg <= 7'b0110000;
6'b100100:seg <= 7'b0011001;
6'b100101:seg <= 7'b0010010;
6'b100110:seg <= 7'b0000010;
6'b100111:seg <= 7'b1111000;
6'b101000:seg <= 7'b0000000;
6'b101001:seg <= 7'b0010000;
default :seg <= 7'b1001000;
endcase
end
if (ain==2'b11)begin //4號(hào)數(shù)碼管
case({ain,cnt4})
6'b110000:seg <= 7'b1000000;
6'b110001:seg <= 7'b1111001;
6'b110010:seg <= 7'b0100100;
6'b110011:seg <= 7'b0110000;
6'b110100:seg <= 7'b0011001;
6'b110101:seg <= 7'b0010010;
6'b110110:seg <= 7'b0000010;
6'b110111:seg <= 7'b1111000;
6'b111000:seg <= 7'b0000000;
6'b111001:seg <= 7'b0010000;
default :seg <= 7'b1000000;
endcase
end
end
endmodule
創(chuàng)建工程:
調(diào)用四個(gè)按鍵消抖模塊和四個(gè)記數(shù)模塊
?引腳定義:
?數(shù)碼管位選
數(shù)碼管段選
?100MHz輸入,四個(gè)按鍵
?
綜合出的電路:
?????????可以看到八個(gè)我們調(diào)用的模塊
設(shè)計(jì)障礙以及解決方法:
錯(cuò)誤代碼示例:
????????這里與主模塊的代碼做一個(gè)比較,這個(gè)always模塊下的思路是ain位選到數(shù)碼管,然后通過cntx選擇對(duì)應(yīng)的段選,以為真正記數(shù)的時(shí)候是0-9,
????????但cntx記數(shù)是0-15(1111),為了避cntx跳到10-15(1010-1111)非法范圍,所以在case語(yǔ)句中加如default語(yǔ)句,使其歸零
????????但此處就會(huì)遇到一個(gè)綜合問題,因?yàn)閧ain,cntx}中的ain值在同一時(shí)間只有一種情況,但是cntx有cnt1,cnt2,cnt3,cnt4,不論四個(gè)一位計(jì)數(shù)器是否跳變,seg就會(huì)被四個(gè)case語(yǔ)句賦值,并由于“<="且是同時(shí)賦值。這里就會(huì)產(chǎn)生競(jìng)爭(zhēng)。
always @(ain or cnt1 or cnt2 or cnt3 or cnt4)
begin
//1號(hào)數(shù)碼管
case({ain,cnt1})
6'b000000:seg <= 7'b1000000;
6'b000001:seg <= 7'b1111001;
6'b000010:seg <= 7'b0100100;
6'b000011:seg <= 7'b0110000;
6'b000100:seg <= 7'b0011001;
6'b000101:seg <= 7'b0010010;
6'b000110:seg <= 7'b0000010;
6'b000111:seg <= 7'b1111000;
6'b001000:seg <= 7'b0000000;
6'b001001:seg <= 7'b0010000;
default :seg <= 7'b1000000;
endcase
//2號(hào)數(shù)碼管
case({ain,cnt2})
6'b010000:seg <= 7'b1000000;
6'b010001:seg <= 7'b1111001;
6'b010010:seg <= 7'b0100100;
6'b010011:seg <= 7'b0110000;
6'b010100:seg <= 7'b0011001;
6'b010101:seg <= 7'b0010010;
6'b010110:seg <= 7'b0000010;
6'b010111:seg <= 7'b1111000;
6'b011000:seg <= 7'b0000000;
6'b011001:seg <= 7'b0010000;
default :seg <= 7'b1000000;
endcase
//3號(hào)數(shù)碼管
case({ain,cnt3})
6'b100000:seg <= 7'b1000000;
6'b100001:seg <= 7'b1111001;
6'b100010:seg <= 7'b0100100;
6'b100011:seg <= 7'b0110000;
6'b100100:seg <= 7'b0011001;
6'b100101:seg <= 7'b0010010;
6'b100110:seg <= 7'b0000010;
6'b100111:seg <= 7'b1111000;
6'b101000:seg <= 7'b0000000;
6'b101001:seg <= 7'b0010000;
default :seg <= 7'b1000000;
endcase
//4號(hào)數(shù)碼管
case({ain,cnt4})
6'b110000:seg <= 7'b1000000;
6'b110001:seg <= 7'b1111001;
6'b110010:seg <= 7'b0100100;
6'b110011:seg <= 7'b0110000;
6'b110100:seg <= 7'b0011001;
6'b110101:seg <= 7'b0010010;
6'b110110:seg <= 7'b0000010;
6'b110111:seg <= 7'b1111000;
6'b111000:seg <= 7'b0000000;
6'b111001:seg <= 7'b0010000;
default :seg <= 7'b1000000;
endcase
end
硬件綜合故障演示:
?????????可以看到,四個(gè)位數(shù),只能綜合處一個(gè)按鍵記數(shù),另外三個(gè)key1,key2,key3,沒有連接。
解決方法:
????????所以我們需要判斷,ain的情況,在同一時(shí)間,seg只由一個(gè){ain,cntx}六位組合值case語(yǔ)句賦值。
故這里加了四個(gè)if判斷ain約束進(jìn)入哪個(gè)case語(yǔ)句。
always @(ain or cnt1 or cnt2 or cnt3 or cnt4)
begin
if (ain==2'b00)begin //1號(hào)數(shù)碼管
case({ain,cnt1})
6'b000000:seg <= 7'b1000000;
6'b000001:seg <= 7'b1111001;
6'b000010:seg <= 7'b0100100;
6'b000011:seg <= 7'b0110000;
6'b000100:seg <= 7'b0011001;
6'b000101:seg <= 7'b0010010;
6'b000110:seg <= 7'b0000010;
6'b000111:seg <= 7'b1111000;
6'b001000:seg <= 7'b0000000;
6'b001001:seg <= 7'b0010000;
default :seg <= 7'b1000000;
endcase
end
if (ain==2'b01)begin //2號(hào)數(shù)碼管
case({ain,cnt2})
6'b010000:seg <= 7'b1000000;
6'b010001:seg <= 7'b1111001;
6'b010010:seg <= 7'b0100100;
6'b010011:seg <= 7'b0110000;
6'b010100:seg <= 7'b0011001;
6'b010101:seg <= 7'b0010010;
6'b010110:seg <= 7'b0000010;
6'b010111:seg <= 7'b1111000;
6'b011000:seg <= 7'b0000000;
6'b011001:seg <= 7'b0010000;
default :seg <= 7'b1000000;
endcase
end
if (ain==2'b10)begin //3號(hào)數(shù)碼管
case({ain,cnt3})
6'b100000:seg <= 7'b1000000;
6'b100001:seg <= 7'b1111001;
6'b100010:seg <= 7'b0100100;
6'b100011:seg <= 7'b0110000;
6'b100100:seg <= 7'b0011001;
6'b100101:seg <= 7'b0010010;
6'b100110:seg <= 7'b0000010;
6'b100111:seg <= 7'b1111000;
6'b101000:seg <= 7'b0000000;
6'b101001:seg <= 7'b0010000;
default :seg <= 7'b1000000;
endcase
end
if (ain==2'b11)begin //4號(hào)數(shù)碼管
case({ain,cnt4})
6'b110000:seg <= 7'b1000000;
6'b110001:seg <= 7'b1111001;
6'b110010:seg <= 7'b0100100;
6'b110011:seg <= 7'b0110000;
6'b110100:seg <= 7'b0011001;
6'b110101:seg <= 7'b0010010;
6'b110110:seg <= 7'b0000010;
6'b110111:seg <= 7'b1111000;
6'b111000:seg <= 7'b0000000;
6'b111001:seg <= 7'b0010000;
default :seg <= 7'b1000000;
endcase
end
end
設(shè)計(jì)總結(jié):
????????BASYS 3開發(fā)板設(shè)計(jì)的四位記數(shù)器可以實(shí)現(xiàn)從0到9999的數(shù)字計(jì)數(shù)功能。這種設(shè)計(jì)可以在許多數(shù)字電路應(yīng)用中使用,例如測(cè)量?jī)x器、時(shí)鐘和鬧鐘等。
????????這里只采用了四個(gè)一位記數(shù),后期可以改成多位記數(shù),但是掌握了一位記數(shù),就可以
????????通過設(shè)計(jì)這個(gè)計(jì)數(shù)器,我獲得了以下收獲:文章來源:http://www.zghlxwxcb.cn/news/detail-476923.html
- 深入了解數(shù)字電路的工作原理和設(shè)計(jì)方法。
- 掌握計(jì)數(shù)器的原理和實(shí)現(xiàn)方式,以及如何將其集成到更大的數(shù)字系統(tǒng)中。
- 學(xué)習(xí)如何使用Verilog硬件描述語(yǔ)言來編寫數(shù)字電路設(shè)計(jì)。
- 加強(qiáng)了對(duì)硬件設(shè)計(jì)工具(Vivado)的運(yùn)用能力。
????????總之,BASYS 3開發(fā)板設(shè)計(jì)的四位記數(shù)器是一項(xiàng)有意義的項(xiàng)目,它幫助我進(jìn)一步深化對(duì)數(shù)字電路設(shè)計(jì)的理解,并提高我的技能水平。文章來源地址http://www.zghlxwxcb.cn/news/detail-476923.html
到了這里,關(guān)于基于FPGA的四位數(shù)碼管顯示按鍵計(jì)數(shù)器設(shè)計(jì)(verilog編程)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!