一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

小編科普幾種按鍵消抖電路的設(shè)計(jì)方案

Matin88 ? 來源:人工智能科學(xué)與技術(shù) ? 2023-02-10 11:06 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

數(shù)字電路中,開關(guān)用于用于產(chǎn)生高、低電平,按鍵用于產(chǎn)生單次脈沖。由于開關(guān)和按鍵為機(jī)械部件,每次按下或者釋放時(shí),由于簧片的彈性會(huì)產(chǎn)生短暫的抖動(dòng),然后才能穩(wěn)定接通或者斷開。

抖動(dòng)現(xiàn)象會(huì)導(dǎo)致按鍵電路的輸出產(chǎn)生毛刺,如圖1所示,從而可能導(dǎo)致系統(tǒng)產(chǎn)生誤動(dòng)作。

開關(guān)和按鍵的抖動(dòng)時(shí)間一般在20ms以內(nèi)。為了防止因按鍵抖動(dòng)引起的系統(tǒng)誤動(dòng)作,必須對(duì)按鍵電路進(jìn)行消抖,只在按鍵閉合或者斷開穩(wěn)定后才允許輸出。

940bd1ac-a8db-11ed-bfe3-dac502259ad0.png

圖1按鍵抖動(dòng)現(xiàn)象

按鍵消抖有軟件消抖和硬件消抖兩類方法。軟件消抖是在嵌入式系統(tǒng)中,檢測(cè)到按鍵按下時(shí),應(yīng)用軟件延時(shí)20ms后再次檢測(cè)按鍵的狀態(tài),如果兩次狀態(tài)相同,則確認(rèn)按鍵已經(jīng)按下。

這種處理方式雖然簡單,但是會(huì)浪費(fèi)CPU資源。

硬件消抖有多種方法。第一種方法是應(yīng)用施密特電路的回差特性配合積分電路實(shí)現(xiàn)按鍵消抖,應(yīng)用電路如圖2所示。

9425e3e4-a8db-11ed-bfe3-dac502259ad0.png

圖2應(yīng)用積分電路實(shí)現(xiàn)按鍵消抖

第二種方法是應(yīng)用鎖存器的保持功能實(shí)現(xiàn)開關(guān)消抖,應(yīng)用電路如圖3所示。

94476258-a8db-11ed-bfe3-dac502259ad0.png

圖3應(yīng)用鎖存器實(shí)現(xiàn)開關(guān)消抖

除了上述兩種按鍵消抖方法外,在基于FPGA的數(shù)字系統(tǒng)設(shè)計(jì)中,也可以應(yīng)用狀態(tài)機(jī)設(shè)計(jì)按鍵消抖電路,在FPGA內(nèi)部實(shí)現(xiàn)。

基于狀態(tài)機(jī)設(shè)計(jì)按鍵消抖電路時(shí),需要將按鍵的一次動(dòng)作分解為:按下前、按下時(shí)、穩(wěn)定期和釋放時(shí)4個(gè)狀態(tài),如圖1中所示,分別用KEY_IDLE、KEY_PRESSED、KEY_ACTIVE和KEY_RELEASE表示。

設(shè)按鍵輸入用key_in表示,低電平有效,設(shè)計(jì)消抖時(shí)間為20ms,則按鍵消抖狀態(tài)機(jī)的狀態(tài)轉(zhuǎn)換關(guān)系如圖4所示。

9456a9ca-a8db-11ed-bfe3-dac502259ad0.png

圖4按鍵消抖狀態(tài)機(jī)

根據(jù)上述狀態(tài)轉(zhuǎn)換關(guān)系,描述按鍵消抖模塊的Verilog HDL代碼參考如下:

module KEY_debounce #(parameter DEBOUNCE_TIME = 1000_000 )( 
  // 50MHz時(shí)鐘時(shí),對(duì)應(yīng)消抖時(shí)間為20ms
input clk_50,                         // 50MHz時(shí)鐘,周期為20ns
      input rst_n,                          // 復(fù)位信號(hào)
      input key_in,                         // 按鍵輸入
      output reg key_out  // 消抖后輸出
      );
      // 內(nèi)部狀態(tài)定義,循環(huán)編碼方式
      localparam KEY_IDLE    = 2'b00,     // 按下前
                   KEY_PRESSED = 2'b01,    // 按下時(shí)
                   KEY_ACTIVE  = 2'b11,    // 穩(wěn)定期
                   KEY_RELEASE = 2'b10;    // 釋放時(shí)
      // 內(nèi)部變量定義          
      reg [19:0] debounce_cnt;                // 消抖計(jì)數(shù)變量
      reg [1:0]  current_state,next_state;  // 現(xiàn)態(tài)和次態(tài)
      reg [0:1]  keytmp;                        // 同步寄存器
      // 內(nèi)部線網(wǎng)定義 
      wire cnt_en,cnt_end;                     // 計(jì)數(shù)允許和停止計(jì)數(shù)標(biāo)志
      wire cnt_flag;                            // 消抖計(jì)數(shù)標(biāo)志
      wire release_flag;                       // 按鍵釋放標(biāo)志
      // 允許消抖計(jì)數(shù)邏輯:按鍵按下時(shí)或者釋放時(shí),cnt_en有效。
assign cnt_en = current_state == KEY_PRESSED 
|| current_state == KEY_RELEASE;
      // 停止計(jì)數(shù)標(biāo)志:cnt_en有效并且debounce_cnt達(dá)到最大值,則cnt_end有效。
       assign cnt_end = cnt_en && ( debounce_cnt == DEBOUNCE_TIME - 1 );
      // 正在計(jì)數(shù)標(biāo)志:cnt_en有效并且debounce_cnt未達(dá)到最大值,則cnt_flag有效。
      assign cnt_flag = cnt_en && ( debounce_cnt < DEBOUNCE_TIME );
      // 按鍵已釋放標(biāo)志: cnt_end有效,并且keytmp[1]為高電平,則release_flag有效。
      assign release_flag = cnt_end && keytmp[1];
      // 按鍵輸入兩級(jí)同步寄存過程,以消除亞穩(wěn)態(tài)。
      always @(posedge clk_50 or negedge rst_n)
         if ( !rst_n ) 
            keytmp <= 2'b00;                         // 清零
         else 
            keytmp[0:1] <= {key_in,keytmp[0]};   // 右移  
      // 時(shí)序邏輯過程,描述狀態(tài)轉(zhuǎn)換
      always @(posedge clk_50 or negedge rst_n) 
         if ( !rst_n )
             current_state <= KEY_IDLE;
         else 
             current_state <= next_state;
      // 組合邏輯過程,定義次態(tài) 
      always @(*)  begin
         case ( current_state )
             KEY_IDLE: if ( !keytmp[1] ) // 按鍵按下時(shí),進(jìn)入KEY_PRESSED
                            next_state = KEY_PRESSED;
                          else                // 否則,保持KEY_IDLE
                            next_state = current_state; 
             KEY_PRESSED: if ( cnt_end && !keytmp[1] ) 
// 消抖時(shí)間到且keytmp[1]為0,確認(rèn)按下有效
                                 next_state = KEY_ACTIVE;
                             else if ( cnt_flag && keytmp[1] ) 
// 正在計(jì)數(shù),但keytmp[1]為1,則為抖動(dòng)
                                       next_state = KEY_IDLE;
else  // 否則狀態(tài)保持
                                       next_state = current_state; 
             KEY_ACTIVE: if ( keytmp[1] ) // keytmp[1]跳變?yōu)?則進(jìn)入釋放狀態(tài)
                               next_state = KEY_RELEASE;
                            else 
                               next_state = current_state; // 否則狀態(tài)保持
             KEY_RELEASE: if ( release_flag ) // 按鍵已釋放,返回
                                next_state = KEY_IDLE;  
                             else if ( cnt_flag && !keytmp[1] )
                                      // 正在計(jì)數(shù),但keytmp[1]為0,則為抖動(dòng)
                                      next_state = KEY_ACTIVE;  
                                   else  // 否則狀態(tài)保持
                                      next_state = current_state;
                 default:  next_state = KEY_IDLE;
         endcase
      end
      // 時(shí)序邏輯過程,消抖計(jì)時(shí)
      always @( posedge clk_50 or negedge rst_n ) 
         if ( !rst_n )
             debounce_cnt <= 20'b0;
         else if ( cnt_en )       // 計(jì)數(shù)允許信號(hào)有效
                  if ( cnt_end )    // 消抖時(shí)間到
                     debounce_cnt <= 20'b0;
                  else             // 消抖時(shí)間未到
                     debounce_cnt <= debounce_cnt + 1'b1;
                else                // 計(jì)數(shù)允許信號(hào)無效
                   debounce_cnt <= 20'b0;
// 時(shí)序邏輯過程,按鍵消抖后輸出
      always @( posedge clk_50 or negedge rst_n ) 
         if ( !rst_n )
             key_out <= 1'b1;   
         else 
             case ( current_state )
                KEY_IDLE   :     key_out <= 1'b1;
KEY_PRESSED:   key_out <= 1'b1;
KEY_ACTIVE :    key_out <= 1'b0; 
KEY_RELEASE:   key_out <= 1'b0;
default:  key_out <= 1'b1;
             endcase
endmodule

對(duì)上述代碼進(jìn)行仿真驗(yàn)證時(shí),需要建立testbench文件,應(yīng)用系統(tǒng)函數(shù)$random產(chǎn)生隨機(jī)數(shù),以模擬不規(guī)則的抖動(dòng)脈沖間隔。

應(yīng)用系統(tǒng)函數(shù)$random產(chǎn)生隨機(jī)整數(shù)的語法格式為

num = $random%b
其中b為十進(jìn)制整數(shù),num為-(b-1) ~ (b-1)范圍內(nèi)的隨機(jī)整數(shù)。 應(yīng)用系統(tǒng)函數(shù)$random產(chǎn)生隨機(jī)正整數(shù)的語法格式為
num ={$random}%b
其中b為十進(jìn)制整數(shù),num為0 ~ (b-1)范圍內(nèi)的隨機(jī)整數(shù)。 測(cè)試按鍵消抖模塊功能的testbench代碼參考如下:
`timescale 1ns/1ps
module KEY_debounce_vlg_tst();
     reg  clk;
     reg  rst_n;
     reg  key_in;
     wire key_out;
     // 模塊參數(shù)重定義,減少計(jì)數(shù)容量,以縮短仿真時(shí)間
     defparam KEY_debounce.DEBOUNCE_TIME = 50000;
// 內(nèi)部變量定義
     reg [15:0] rand_num;
     // 仿真參數(shù)定義
     parameter RESET_TIME = 2, STEP = 5;
     // 按鍵消抖模塊例化 
     KEY_debounce i1
        ( .clk      (clk),
          .rst_n    (rst_n),
          .key_in   (key_in),
          .key_out (key_out));
     // 設(shè)置復(fù)位信號(hào)波形 
   initial begin
        rst_n = 1;
        #1;
        rst_n = 0;
        #(STEP * RESET_TIME);
        rst_n = 1;
     end
     // 設(shè)置按鍵輸入 
     initial begin
        #1; key_in = 1;                  //按下前
        #(STEP * 10); press_key;       // 第1次按鍵過程
        #10_000;       press_key;       // 第2次按鍵過程
     end
     // 設(shè)置時(shí)鐘信號(hào)  
     initial clk_50 = 0;
     always  #(STEP/2) clk_50 = ~clk_50;
     // 監(jiān)測(cè)任務(wù)
         initial                             
        $monitor($time,"clk_50=%b rst_n=%b key_in=%b key_out=%b",
clk_50,rst_n,key_in,key_out); 
     // 按鍵任務(wù)定義 
     task press_key;
        begin
          repeat (20) begin // 模擬前沿抖動(dòng)過程
            rand_num = {$random}%5000;
            #rand_num key_in = ~key_in;
            end
          key_in = 0;
          #300_000;
          repeat (20) begin  // 模擬后沿抖動(dòng)過程
            rand_num = {$random}%5000;
            #rand_num key_in = ~key_in;
            end
          key_in = 1;
          #300_000;
       end
     endtask
 endmodule

上述代碼中使用了defparam語句用于對(duì)KEY_debounce模塊中的DEBOUNCE_TIME參數(shù)進(jìn)行重定義,在確保功能驗(yàn)證的前提下縮短消抖時(shí)間。啟動(dòng)modelsim進(jìn)行仿真,結(jié)果如圖5所示。

947c8636-a8db-11ed-bfe3-dac502259ad0.png

圖5按鍵消抖模塊仿真波形

從波形圖中可以看出,消抖電路對(duì)按鍵按下和釋放產(chǎn)生的4次抖動(dòng)都能實(shí)現(xiàn)有效消抖,因此驗(yàn)證基于狀態(tài)機(jī)設(shè)計(jì)的按鍵消抖模塊功能正確。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • FPGA
    +關(guān)注

    關(guān)注

    1645

    文章

    22033

    瀏覽量

    617774
  • 鎖存器
    +關(guān)注

    關(guān)注

    8

    文章

    925

    瀏覽量

    42324
  • 數(shù)字電路
    +關(guān)注

    關(guān)注

    193

    文章

    1639

    瀏覽量

    81853
  • 狀態(tài)機(jī)
    +關(guān)注

    關(guān)注

    2

    文章

    493

    瀏覽量

    28211
  • 按鍵消抖
    +關(guān)注

    關(guān)注

    2

    文章

    28

    瀏覽量

    10656

原文標(biāo)題:按鍵消抖電路的幾種設(shè)計(jì)方案

文章出處:【微信號(hào):LowHuangMakerSpace,微信公眾號(hào):LowHuangMakerSpace】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    按鍵的硬件電路原理詳解

    按鍵通常的按鍵所用開關(guān)為機(jī)械彈性開關(guān),當(dāng)機(jī)械觸點(diǎn)斷開、閉合時(shí),由于機(jī)械觸點(diǎn)的彈性作用,一個(gè)按鍵開關(guān)在閉合時(shí)不會(huì)馬上穩(wěn)定地接通,在斷開時(shí)也
    的頭像 發(fā)表于 02-02 09:42 ?1.1w次閱讀
    <b class='flag-5'>按鍵</b>的硬件<b class='flag-5'>消</b><b class='flag-5'>抖</b><b class='flag-5'>電路</b>原理詳解

    單片機(jī)的按鍵幾種按鍵電路

    按鍵電路 一、 硬件按鍵電路控制
    的頭像 發(fā)表于 12-17 07:45 ?10.7w次閱讀
    單片機(jī)的<b class='flag-5'>按鍵</b><b class='flag-5'>消</b><b class='flag-5'>抖</b>與<b class='flag-5'>幾種</b><b class='flag-5'>按鍵</b><b class='flag-5'>電路</b>

    按鍵電路的實(shí)現(xiàn)方式

    按鍵通常的按鍵所用開關(guān)為機(jī)械彈性開關(guān),當(dāng)機(jī)械觸點(diǎn)斷開、閉合時(shí),由于機(jī)械觸點(diǎn)的彈性作用,一個(gè)按鍵開關(guān)在閉合時(shí)不會(huì)馬上穩(wěn)定地接通,在斷開時(shí)也
    的頭像 發(fā)表于 08-29 11:25 ?5120次閱讀

    按鍵

    請(qǐng)問大家的按鍵是用什么方法解決的,如普通的按鍵如何。
    發(fā)表于 09-26 22:17

    技術(shù)分享:明德?lián)P按鍵的原理和基于fpga的設(shè)計(jì)

    本帖最后由 明德?lián)P吳老師 于 2017-8-2 11:45 編輯 按鍵1功能概述按鍵開關(guān)是各種電子設(shè)備不可或缺的人機(jī)接口,如電腦的鍵盤等。實(shí)際應(yīng)用中,
    發(fā)表于 08-02 10:38

    請(qǐng)問怎樣去設(shè)計(jì)一種按鍵電路?

    按鍵電路結(jié)構(gòu)與電路模型按鍵
    發(fā)表于 04-29 06:13

    按鍵代碼方法有哪幾種

    按鍵原理一、首先來回顧一下按鍵延時(shí)按鍵由于是
    發(fā)表于 07-14 06:21

    如何去消除K1-K3的按鍵問題?有哪幾種方法?

    按鍵的實(shí)驗(yàn)原理是什么?如何去消除K1-K3的按鍵問題?有哪幾種
    發(fā)表于 07-14 06:35

    MCU按鍵問題

    按鍵問題機(jī)械按鍵是必須的,1、延時(shí)
    發(fā)表于 11-04 06:37

    STM32單片機(jī)按鍵和FPGA按鍵的相關(guān)資料分享

    寫在前面:STM32單片機(jī)按鍵和FPGA按鍵大全按鍵
    發(fā)表于 01-18 06:39

    基于FPGA的按鍵電路設(shè)計(jì)

    采用了VHDL語言編程的設(shè)計(jì)方法,通過FPGA來實(shí)現(xiàn)按鍵的硬件電路。論述了基于計(jì)數(shù)器、RS觸發(fā)器和狀態(tài)機(jī)3種方法來實(shí)現(xiàn)按鍵
    發(fā)表于 12-05 14:13 ?224次下載

    VHDL—按鍵

    按鍵檢測(cè)需要,一般有硬件和軟件兩種方式。硬件就是加去抖動(dòng)電路,這樣從根本上解決按鍵抖動(dòng)問題。除了用專用
    發(fā)表于 11-11 17:17 ?2次下載

    51單片機(jī)的獨(dú)立按鍵按鍵及矩陣按鍵電路與程序免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是51單片機(jī)的獨(dú)立按鍵按鍵及矩陣按鍵電路與程序免費(fèi)下載。
    發(fā)表于 07-26 17:36 ?29次下載
    51單片機(jī)的獨(dú)立<b class='flag-5'>按鍵</b>和<b class='flag-5'>按鍵</b><b class='flag-5'>消</b><b class='flag-5'>抖</b>及矩陣<b class='flag-5'>按鍵</b>的<b class='flag-5'>電路</b>與程序免費(fèi)下載

    為什么要進(jìn)行按鍵

    按鍵通常的按鍵所用開關(guān)為機(jī)械彈性開關(guān),當(dāng)機(jī)械觸點(diǎn)斷開、閉合時(shí),由于機(jī)械觸點(diǎn)的彈性作用,一個(gè)按鍵開關(guān)在閉合時(shí)不會(huì)馬上穩(wěn)定地接通,在斷開時(shí)也
    的頭像 發(fā)表于 04-19 14:55 ?1.1w次閱讀

    按鍵的軟件和硬件方法

    采用鍋?zhàn)衅?b class='flag-5'>按鍵測(cè)量波形。按鍵按下與抬起的部分都出現(xiàn)抖動(dòng),大致時(shí)間10ms左右。為了防止按鍵誤按或者重復(fù)識(shí)別,必須要按鍵
    的頭像 發(fā)表于 03-01 10:53 ?1.5w次閱讀
    <b class='flag-5'>按鍵</b><b class='flag-5'>消</b><b class='flag-5'>抖</b>的軟件和硬件方法