【基于FPGA的圖像處理工程】邊緣檢測(cè)工程之按鍵捕捉模塊代碼解析
【基于FPGA的圖像處理工程】
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? —邊緣檢測(cè)工程:按鍵捕捉模塊代碼解析
本文為明德?lián)P原創(chuàng)文章,轉(zhuǎn)載請(qǐng)注明出處!
按鍵捕捉模塊的功能:可以達(dá)到按一次按鍵就可以得到一次識(shí)別的效果,并且需要對(duì)按鍵進(jìn)行消抖處理,消除按下按鍵時(shí)不穩(wěn)定、隨機(jī)的抖動(dòng)電壓信號(hào)。
一、設(shè)計(jì)架構(gòu)
有些同學(xué)看到按鍵消抖處理,就理所應(yīng)當(dāng)以為是將按鍵按下這一活動(dòng)的抖動(dòng)部分進(jìn)行消除,但其實(shí)按鍵的消抖只是一種比較正式的說(shuō)法,其本質(zhì)上是在抖動(dòng)的波形中,捕捉到比較穩(wěn)定的電壓。
我們通過(guò)實(shí)際情況來(lái)學(xué)習(xí)下。一般按鍵都是低電平有效,通常情況下按鍵信號(hào)為高電平,當(dāng)主動(dòng)按下按鍵時(shí)會(huì)變成低電平,這是按鍵的基本電平情況。前面我們有說(shuō)到,在按下的瞬間,穩(wěn)定狀態(tài)的信號(hào)前后都會(huì)產(chǎn)生抖動(dòng),這時(shí)即使按鍵信號(hào)等于0也無(wú)法表示按鍵被按下。
如下圖所示,按鍵持續(xù)為高電平,當(dāng)按下按鍵的時(shí)候會(huì)變?yōu)榈碗娖?,但是在此前后都?huì)產(chǎn)生一段高高低低的抖動(dòng)信號(hào)。按鍵捕捉的方法就是持續(xù)的檢測(cè)信號(hào)的進(jìn)度,比如到第一個(gè)低電平產(chǎn)生時(shí),開(kāi)始計(jì)時(shí),假設(shè)第一個(gè)出現(xiàn)的低電平持續(xù)時(shí)間為6ms,不滿足按鍵按下標(biāo)準(zhǔn);第二個(gè)低電平信號(hào)出現(xiàn)持續(xù)時(shí)間為8ms,不滿足按鍵按下標(biāo)準(zhǔn);到第四個(gè)低電平信號(hào),持續(xù)了10ms以上,滿足按下按鍵標(biāo)準(zhǔn),即可判斷這里有一次的按下按鍵操作;接著第五個(gè)低電平信號(hào),持續(xù)時(shí)間為6ms,不滿足按下按鍵標(biāo)準(zhǔn)。這種方法,就可以幫助我們很好的確判斷有效按鍵信號(hào)。

按鍵捕捉模塊使用一個(gè)計(jì)數(shù)器的架構(gòu),對(duì)按鍵信號(hào)長(zhǎng)度進(jìn)行計(jì)數(shù)。該計(jì)數(shù)器架構(gòu)為:

計(jì)數(shù)器cnt0:時(shí)鐘時(shí)鐘計(jì)數(shù)器。用于計(jì)數(shù)按鍵信號(hào)持續(xù)超過(guò)10ms的時(shí)間,10ms即是500000個(gè)時(shí)鐘,所以該計(jì)數(shù)器的計(jì)數(shù)周期為500000。
二、信號(hào)的意義

下面展出本模塊的設(shè)計(jì),歡迎進(jìn)一步交流,如果需要源代碼,歡迎與本人聯(lián)系。
module key_module(
? ? clk? ? ,
? ? rst_n??,
? ? key_in ,
? ? key_vld
);
parameter? ?? ?? ?? ?? ?? ?? ?? ???DATA_W? ?? ?? ???= 20? ?? ?? ? ;
parameter? ?? ?? ?? ?? ?? ?? ?? ???KEY_W? ?? ?? ???= 4? ?? ?? ???;
parameter? ?? ?? ?? ?? ?? ?? ???TIME_20MS = 500_000? ?;
input? ?? ?? ?? ?? ?? ?? ?? ?? ? clk? ?? ?? ?? ?? ?? ?? ?;
input? ?? ?? ?? ?? ?? ?? ?? ?? ?rst_n? ?? ?? ?? ?? ?? ? ;
input? ?? ?[KEY_W-1 :0]? ?? ?? ?? ?? ? key_in? ?? ?? ?? ?? ?? ?;
output? ???[KEY_W-1 :0]? ???key_vld? ?? ?? ?? ?? ???;
reg? ?? ???[KEY_W-1 :0]? ???key_vld? ?? ?? ?? ?? ???;
reg? ?? ???[DATA_W-1:0]? ???cnt? ?? ?? ?? ?? ?? ?? ?;
wire? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? add_cnt? ?? ?? ?? ?? ???;
wire? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? end_cnt? ?? ?? ?? ?? ???;
reg? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? flag_add? ?? ?? ?? ?? ?? ???;
reg? ???[KEY_W-1 :0]? ?? ???key_in_ff1? ?? ?? ?? ???;
reg? ???[KEY_W-1 :0]? ?? ???key_in_ff0? ?? ?? ?? ???;
always??@(posedge clk or negedge rst_n)begin
? ? if(rst_n==1'b0)begin
? ?? ???cnt <= 20'b0;
? ? end
? ? else if(add_cnt)begin
? ?? ???if(end_cnt)
? ?? ?? ?? ?cnt <= 20'b0;
? ?? ???else
? ?? ?? ?? ?cnt <= cnt + 1'b1;
? ? end
? ? else begin
? ?? ???cnt <= 0;
? ? end
end
assign add_cnt = flag_add==1'b0 && (key_in_ff1 != {KEY_W{1'b1}});
assign end_cnt = add_cnt && cnt == TIME_20MS - 1;
always??@(posedge clk or negedge rst_n)begin
? ? if(rst_n==1'b0)begin
? ?? ???flag _add<= 1'b0;
? ? end
? ? else if(end_cnt)begin
? ?? ???flag_add <= 1'b1;
? ? end
? ? else if(key_in_ff1 == {KEY_W{1'b1}})begin
? ?? ???flag_add <= 1'b0;
? ? end
end
always??@(posedge clk or negedge rst_n)begin
? ? if(rst_n==1'b0)begin
? ?? ???key_in_ff0 <= 0;
? ?? ???key_in_ff1 <= 0;
? ? end
? ? else begin
? ?? ???key_in_ff0 <= key_in? ? ;
? ?? ???key_in_ff1 <= key_in_ff0;
? ? end
end
always??@(posedge clk or negedge rst_n)begin
? ? if(rst_n==1'b0)begin
? ?? ???key_vld <= 0;
? ? end
? ? else if(end_cnt)begin
? ?? ???key_vld <= ~key_in_ff1;
? ? end
? ? else begin
? ?? ???key_vld <= 0;
? ? end
end
endmodule
復(fù)制代碼
明德?lián)P專注FPGA研究,我司正在連載兩本書(shū)籍:《基于FPGA至簡(jiǎn)設(shè)計(jì)法實(shí)現(xiàn)的圖像邊緣檢測(cè)系統(tǒng)》(http://www.fpgabbs.cn/forum.php?mod=viewthread&tid=691)、《ASIC和FPGA時(shí)序約束理論與應(yīng)用》(http://www.fpgabbs.cn/forum.php?mod=viewthread&tid=705),有興趣點(diǎn)擊觀看。