久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

[博客大賽]按鍵消抖之終極解決方案

 鹿港小鎮(zhèn)1989 2014-05-05
1.按鍵消抖的原理

                 圖1.按鍵抖動(dòng)示意圖

我們平常所用的按鍵為機(jī)械彈性開關(guān),,由于觸點(diǎn)的彈性作用,按鍵在閉合時(shí)不會(huì)馬上穩(wěn)定的接通,,而是有一段時(shí)間的抖動(dòng),,在斷開時(shí)也不會(huì)立即斷開。抖動(dòng)時(shí)間由按鍵的機(jī)械特性所決定,,一般為5ms~10ms。所以我們?cè)谧霭存I檢測(cè)時(shí)都要加一個(gè)消抖的過(guò)程,。

按鍵消抖主要有兩種方案:

一是延時(shí)重采樣,;二是持續(xù)采樣。

從理論上來(lái)說(shuō),,延時(shí)(如10ms)重采樣的準(zhǔn)確率肯定低于持續(xù)采樣,。
2.按鍵消抖的方法
(1)延時(shí)重采樣
延時(shí)重采樣的意思是,當(dāng)?shù)谝淮螜z測(cè)到鍵值由'1'變?yōu)?0'時(shí),,再延時(shí)一段時(shí)間(如10ms),再次采樣,,確認(rèn)是否仍是'0';若是'0'則認(rèn)為此時(shí)鍵值為'0',否則,,重新執(zhí)行檢測(cè)過(guò)程,。
這個(gè)方案在特權(quán)同學(xué)的《深入淺出玩轉(zhuǎn)FPGA》的p191有例程;
該方案的缺陷:a.如果延時(shí)太短,,有可能兩次采樣時(shí)都處于抖動(dòng)時(shí)間,,因此可能引起誤判;
                         b.如果延時(shí)太長(zhǎng),,可能檢測(cè)不出按鍵變換
(2)持續(xù)采樣
持續(xù)采樣的原理是,,當(dāng)檢測(cè)到按鍵處于某電平(如'0')時(shí),在之后的N個(gè)時(shí)鐘周期內(nèi)連續(xù)檢測(cè)此按鍵的電平,,如果一直不變,,則讀出此按鍵的電平值(如'0')。
持續(xù)采樣的優(yōu)點(diǎn):a.樣本足夠多,,減少誤判的可能性,。
                            b.對(duì)于按鍵按下('1'->'0'),按鍵釋放('0'->'1')都可以檢測(cè),。
持續(xù)采樣的缺點(diǎn):持續(xù)檢測(cè)的時(shí)間太長(zhǎng)(大于按鍵按下和釋放的時(shí)間差),,則可能無(wú)法檢測(cè)按鍵的變換。
1)單個(gè)按鍵的檢測(cè)
按鍵檢測(cè)的輸出有兩種方式:1.電平輸出,,此時(shí)按鍵功能猶如撥碼開關(guān),。
                                              2.脈沖輸出,,此時(shí)每按下一次按鍵,輸出一個(gè)脈沖信號(hào),。
 
                     圖2.按鍵檢測(cè)輸出波形示意圖
如圖2所示,,Key_out1的輸出與Key_in的變換趨勢(shì)相同,只是濾除了抖動(dòng)成分,;
Key_out2則是每當(dāng)按鍵按下后輸出一個(gè)高電平脈沖,。在大多數(shù)的應(yīng)用中會(huì)用到Key_out2所示功能。
輸出為電平(用于電平判斷事件,,類似于開關(guān)選擇)
module key_scan
#(parameter DURATION = 1200)//the number of clk period
(
input wire clk, //120MHz
input wire rst_n,
input wire key_in,
output reg key_out
);
//key jitter filter
reg[11:0] low_cnt;
reg[11:0] high_cnt;
always @(posedge clk or negedge rst_n)
begin
 if(!rst_n)
  begin
       low_cnt <= 0;
       high_cnt <= 0;
  key_out <= 1'b1;
  end
 else
       begin
       if(key_in == 1'b0)
           begin
           high_cnt <= 0;
           if(low_cnt == DURATION)
               begin low_cnt <= low_cnt; key_out <= 1'b0; end
           else
               low_cnt <= low_cnt + 1'b1;
           end
       else //key_in == 1'b1
           begin
           low_cnt <= 0;
           if(high_cnt == DURATION)
               begin high_cnt <= high_cnt;key_out <= 1'b1; end
           else
               high_cnt <= high_cnt + 1'b1;
           end
       end
end
endmodule
輸出為脈沖(用于脈沖觸發(fā)事件)
module key_scan
#(parameter DURATION = 1200)//the number of clk period
(
input wire clk, //120MHz
input wire rst_n,
input wire key_in,
output wire key_out
);
//key jitter filter
reg[11:0] low_cnt;
always @(posedge clk or negedge rst_n)
begin
 if(!rst_n)
        low_cnt <= 0;
 else
        begin
        if(key_in == 1'b0)
            begin
            if(low_cnt == DURATION)
                low_cnt <= low_cnt;
            else
                low_cnt <= low_cnt + 1'b1;
            end
        else //key_in == 1'b1
            low_cnt <= 0;
        end
end
assign key_out = (low_cnt == DURATION -1)? 1'b1 : 1'b0;
endmodule
2)多個(gè)獨(dú)立按鍵的掃描(掃描得出鍵值)
功能:a.可以檢測(cè)出哪些鍵按下了,,甚至哪些鍵同時(shí)按下了。
           b.鍵值更新后,,輸出一個(gè)脈沖信號(hào),,提升更新完成;
           c.鍵值保持到下一次更新完成,。
module key_counter_scan
#(
 parameter KEY_WIDTH = 4
)
(
 //global clock
 input clk,
 input rst_n,
 //key interface
 input [KEY_WIDTH-1:0] key_data,
 //user interface
 output reg key_flag,
 output reg [KEY_WIDTH-1:0] key_value //H Valid
);
//-----------------------------------
//Register key_data for compare
reg [KEY_WIDTH-1:0] key_data_r;
always @(posedge clk or negedge rst_n)
begin
 if(!rst_n)
  key_data_r <= {KEY_WIDTH{1'b1}};
 else
  key_data_r <= key_data;
end
//-----------------------------------
//continue 20ms
localparam DELAY_TOP = 20'd1000_000;
//localparam DELAY_TOP = 20'd1000; //Just for test
reg [19:0] delay_cnt;
//-----------------------------------
//Key scan via counter detect.
always @(posedge clk or negedge rst_n)
begin
 if(!rst_n)
  delay_cnt <= 0;
 else
  begin
  if((key_data == key_data_r) && (key_data != {KEY_WIDTH{1'b1}})) //20ms counter jitter
   begin
   if(delay_cnt < DELAY_TOP)
    delay_cnt <= delay_cnt + 1'b1;
   else
    delay_cnt <= DELAY_TOP;
   end
  else
   delay_cnt <= 0;
  end
end
//-----------------------------------
//the complete of key_data capture
wire key_trigger = (delay_cnt == DELAY_TOP - 1'b1) ? 1'b1 : 1'b0;
//-----------------------------------
//output the valid key_value via key_trigger
always@(posedge clk or negedge rst_n)
begin
 if(!rst_n)
  key_value <= {KEY_WIDTH{1'b0}};
 else if(key_trigger)
  key_value <= ~key_data_r;
 else
  key_value <= key_value;
end
//---------------------------------
//Lag 1 clock for valid read enable
always@(posedge clk or negedge rst_n)
begin
 if(!rst_n)
  key_flag <= 0;
 else
  key_flag <= key_trigger;
end
endmodule

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多