在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            Altera MAX10: 按鍵消抖

            作者: 時(shí)間:2023-11-08 來(lái)源:電子森林 收藏

            在之前的實(shí)驗(yàn)中我們學(xué)習(xí)了如何用按鍵作為的輸入控制,在本實(shí)驗(yàn)中將學(xué)習(xí)如何進(jìn)行按鍵,用按鍵完成更多的功能。

            本文引用地址:http://www.biyoush.com/article/202311/452612.htm

            按鍵是一種常用的電子開(kāi)關(guān),電子設(shè)計(jì)中不可缺少的輸入設(shè)備。當(dāng)按下時(shí)使開(kāi)關(guān)導(dǎo)通,松開(kāi)時(shí)則開(kāi)關(guān)斷開(kāi),內(nèi)部結(jié)構(gòu)是靠金屬?gòu)椘瑏?lái)實(shí)現(xiàn)通斷。
            按鍵抖動(dòng)的原理

            抖動(dòng)原理

            • 抖動(dòng)的產(chǎn)生 :通常的按鍵所用的開(kāi)關(guān)為機(jī)械彈性開(kāi)關(guān),當(dāng)機(jī)械觸點(diǎn)斷開(kāi)、閉合時(shí),由于機(jī)械觸點(diǎn)的彈性作用,一個(gè)按鍵開(kāi)關(guān)在閉合時(shí)不會(huì)馬上穩(wěn)定地接通,在斷開(kāi)時(shí)也不會(huì)一下子斷開(kāi)。因而在閉合及斷開(kāi)的瞬間均伴隨有一連串的抖動(dòng),為了不產(chǎn)生這種現(xiàn)象而作的措施就是按鍵
            • 消除抖動(dòng)的措施:一般我們采用軟件方法消抖。即檢測(cè)到按鍵按下動(dòng)作之后進(jìn)行10ms~20ms左右的延時(shí),當(dāng)前沿的抖動(dòng)消失之后再一次檢測(cè)按鍵的狀態(tài)。如果仍然是按下的電平狀態(tài),則認(rèn)為這是一次真正的按鍵按下;同樣檢測(cè)到按鍵釋放,也要做10ms~20ms延時(shí),檢測(cè)到后沿抖動(dòng)消失后認(rèn)為是一個(gè)完整的按鍵彈起過(guò)程。
            • 消抖的好處:執(zhí)行按鍵消抖有兩個(gè)好處,
              • 消除誤觸發(fā):我們想通過(guò)按鍵來(lái)翻轉(zhuǎn)信號(hào)(例如按下一次led亮,在按一次led滅),如果沒(méi)有進(jìn)行消抖,則會(huì)產(chǎn)生很多誤觸發(fā)造成不必要的翻轉(zhuǎn)。
              • 記錄按鍵次數(shù):執(zhí)行按鍵消抖可以讓我們記錄按鍵動(dòng)作的次數(shù),在很多應(yīng)用里這非常有用。

            在點(diǎn)亮LED實(shí)驗(yàn)中我們知道了板子上按鍵的設(shè)計(jì),當(dāng)按鍵未被按下時(shí),連接到管腳認(rèn)為是高電平;當(dāng)按鍵被按下時(shí),連接到管腳認(rèn)為是低電平。

            要消除按鍵的抖動(dòng),我們需要去掃描按鍵,也就是不斷的去采集按鍵的狀態(tài)。軟件消抖時(shí)我們一般只考慮按鍵按下時(shí)的抖動(dòng),而放棄對(duì)釋放時(shí)抖動(dòng)的消除。用系統(tǒng)時(shí)鐘(頻率較高)去采集按鍵狀態(tài),當(dāng)檢測(cè)到按下時(shí)用計(jì)數(shù)器延時(shí)20ms,再去檢測(cè)按鍵狀態(tài),如果這時(shí)仍為按下?tīng)顟B(tài),確認(rèn)是一次按下動(dòng)作,否側(cè)的話認(rèn)為無(wú)按鍵按下。如何檢測(cè)按鍵狀態(tài)變化就需要用到脈沖邊沿檢測(cè)的方法。

            脈沖邊沿檢測(cè)

            檢測(cè)按鍵按下時(shí)要用到脈沖邊沿檢測(cè)的方法,捕捉信號(hào)的突變、捕捉時(shí)鐘的上升下降沿等經(jīng)常會(huì)用到這種方法。簡(jiǎn)單地說(shuō)就是用一個(gè)頻率更高的時(shí)鐘去觸發(fā)要檢測(cè)的信號(hào),用兩個(gè)寄存器去儲(chǔ)存相鄰兩個(gè)時(shí)鐘采集到的值,然后進(jìn)行異或運(yùn)算,如果不為零,代表發(fā)生了上升沿或者下降沿。

            在按鍵消抖的過(guò)程中,同樣運(yùn)用了脈沖邊沿檢測(cè)。用兩個(gè)寄存器儲(chǔ)存相鄰時(shí)鐘采集的值(例如datapre,data),然后將data取反與前一個(gè)值相與(state=datapre&(~data)),如果為1,則判斷有下降沿既按鍵按下由高到低;否則無(wú)變化。
            將一個(gè)信號(hào)由連續(xù)時(shí)鐘采集,相鄰兩個(gè)鐘觸發(fā)的值存入兩個(gè)寄存器。理解verilog實(shí)現(xiàn)這個(gè)過(guò)程要充分了解其中的非阻塞賦值。

            本實(shí)驗(yàn)主要通過(guò)按鍵來(lái)控制led的翻轉(zhuǎn),當(dāng)按下一次led變亮,再按下一次led變暗。首先我們做個(gè)試驗(yàn),對(duì)按鍵不做處理通過(guò)按鍵來(lái)控制led翻轉(zhuǎn)。

            // ********************************************************************
            // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
            // ********************************************************************
            // File name    : top.v
            // Module name  : top
            // Author       : STEP
            // Description  : control led through the button
            // 
            // --------------------------------------------------------------------
            // Code Revision History : 
            // --------------------------------------------------------------------
            // Version: |Mod. Date:   |Changes Made:
            // V1.0     |2017/03/02   |Initial ver
            // --------------------------------------------------------------------
            // Module Function:按鍵控制led翻轉(zhuǎn),未做消抖 
            module top(
            		key,          //按鍵輸入
            		rst,          //復(fù)位輸入
            		led           //led輸出
            		); 	input key,rst;
            	output reg led; 	always @(key or rst)
            		if (!rst)             //復(fù)位時(shí)led熄滅
            			led = 1;
            		else if(key == 0)     
            			led = ~led;   //按鍵按下時(shí)led翻轉(zhuǎn)
            		else
            			led = led;
            			endmodule

            未經(jīng)過(guò)消抖的程序下載到上會(huì)發(fā)現(xiàn)按鍵有時(shí)不能夠控制led翻轉(zhuǎn),這是因?yàn)榘存I的抖動(dòng)造成了led狀態(tài)變化不可控,所以我們必須將抖動(dòng)消除。下面是一種延時(shí)去抖的程序

            // ********************************************************************
            // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
            // ********************************************************************
            // File name    : debounce.v
            // Module name  : debounce
            // Author       : STEP
            // Description  : 
            // 
            // --------------------------------------------------------------------
            // Code Revision History : 
            // --------------------------------------------------------------------
            // Version: |Mod. Date:   |Changes Made:
            // V1.0     |2017/03/02   |Initial ver
            // --------------------------------------------------------------------
            // Module Function:按鍵消抖 
            module debounce (clk,rst,key,key_pulse);         
            parameter       N  =  1;                      //要消除的按鍵的數(shù)量 	
            input             clk;
                    input             rst;
                    input 	[N-1:0]   key;                        //輸入的按鍵					
            	output  [N-1:0]   key_pulse;                  //按鍵動(dòng)作產(chǎn)生的脈沖	         
            	reg     [N-1:0]   key_rst_pre;                //定義一個(gè)寄存器型變量存儲(chǔ)上一個(gè)觸發(fā)時(shí)的按鍵值
                    reg     [N-1:0]   key_rst;                    //定義一個(gè)寄存器變量?jī)?chǔ)存儲(chǔ)當(dāng)前時(shí)刻觸發(fā)的按鍵值         
                    wire    [N-1:0]   key_edge;                   //檢測(cè)到按鍵由高到低變化是產(chǎn)生一個(gè)高脈沖         
                    //利用非阻塞賦值特點(diǎn),將兩個(gè)時(shí)鐘觸發(fā)時(shí)按鍵狀態(tài)存儲(chǔ)在兩個(gè)寄存器變量中
                    always @(posedge clk  or  negedge rst)
                      begin
                         if (!rst) begin
                             key_rst <= {N{1'b1}};                //初始化時(shí)給key_rst賦值全為1,{}中表示N個(gè)1
                             key_rst_pre <= {N{1'b1}};
                         end
                         else begin
                             key_rst <= key;                     
                             //第一個(gè)時(shí)鐘上升沿觸發(fā)之后key的值賦給key_rst,同時(shí)key_rst的值賦給key_rst_pre
                             key_rst_pre <= key_rst;             
                             //非阻塞賦值。相當(dāng)于經(jīng)過(guò)兩個(gè)時(shí)鐘觸發(fā),key_rst存儲(chǔ)的是當(dāng)前時(shí)刻key的值,key_rst_pre存儲(chǔ)的是前一個(gè)時(shí)鐘的key的值
                         end    
                       end         
                       assign  key_edge = key_rst_pre & (~key_rst);
                       //脈沖邊沿檢測(cè)。當(dāng)key檢測(cè)到下降沿時(shí),key_edge產(chǎn)生一個(gè)時(shí)鐘周期的高電平         
                       reg	[17:0]	  cnt;                       
                       //產(chǎn)生延時(shí)所用的計(jì)數(shù)器,系統(tǒng)時(shí)鐘12MHz,要延時(shí)20ms左右時(shí)間,至少需要18位計(jì)數(shù)器              
                       //產(chǎn)生20ms延時(shí),當(dāng)檢測(cè)到key_edge有效是計(jì)數(shù)器清零開(kāi)始計(jì)數(shù)
                    always @(posedge clk or negedge rst)
                       begin
                         if(!rst)
                            cnt <= 18'h0;
                         else if(key_edge)
                            cnt <= 18'h0;
                         else
                            cnt <= cnt + 1'h1;
                         end           reg     [N-1:0]   key_sec_pre;                //延時(shí)后檢測(cè)電平寄存器變量
                    reg     [N-1:0]   key_sec;                     
                     //延時(shí)后檢測(cè)key,如果按鍵狀態(tài)變低產(chǎn)生一個(gè)時(shí)鐘的高脈沖。如果按鍵狀態(tài)是高的話說(shuō)明按鍵無(wú)效
                    always @(posedge clk  or  negedge rst)
                      begin
                         if (!rst) 
                             key_sec <= {N{1'b1}};                
                         else if (cnt==18'h3ffff)
                             key_sec <= key;  
                      end
                   always @(posedge clk  or  negedge rst)
                      begin
                         if (!rst)
                             key_sec_pre <= {N{1'b1}};
                         else                   
                             key_sec_pre <= key_sec;             
                     end      
                   assign  key_pulse = key_sec_pre & (~key_sec);      
                   endmodule

            以上就是一個(gè)N位按鍵的消抖程序,如果有按鍵按下會(huì)輸出一個(gè)時(shí)鐘周期的高脈沖。下面我們可以試試用這個(gè)按鍵消抖的輸出來(lái)觸發(fā)LED的顯示,既按鍵一次LED翻轉(zhuǎn)。你也可以不加按鍵消抖試試用按鍵來(lái)控制LED(按一次變亮,再按一次滅掉)。

            下面的程序是例化調(diào)用debounce模塊來(lái)控制LED

            // ********************************************************************
            // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
            // ********************************************************************
            // File name    : top.v
            // Module name  : top
            // Author       : STEP
            // Description  : 
            // 
            // --------------------------------------------------------------------
            // Code Revision History : 
            // --------------------------------------------------------------------
            // Version: |Mod. Date:   |Changes Made:
            // V1.0     |2017/03/02   |Initial ver
            // --------------------------------------------------------------------
            // Module Function:進(jìn)過(guò)按鍵消抖后控制led顯示翻轉(zhuǎn) 
            module top (clk,rst,key,led);         
            input             clk;
                    input             rst;
                    input 	          key;                      				
            	output   reg      led;                 
            	wire              key_pulse;         //當(dāng)按鍵按下時(shí)產(chǎn)生一個(gè)高脈沖,翻轉(zhuǎn)一次led
                    always @(posedge clk  or  negedge rst)
                       begin
                         if (!rst) 
            		led <= 1'b1;
            	     else if (key_pulse)
            		led <= ~led;
            	     else
                            led <= led;
            	   end    
                     //例化消抖module,這里沒(méi)有傳遞參數(shù)N,采用了默認(rèn)的N=1     
                     debounce  u1 (                               
                                   .clk (clk),
                                   .rst (rst),
                                   .key (key),
                                   .key_pulse (key_pulse)
                                   );
             endmodule

            設(shè)置好復(fù)位鍵可消抖的按鍵,編譯完成后下載,通過(guò)按鍵就可以翻轉(zhuǎn)LED。你也可以定義多個(gè)按鍵控制多個(gè)LED,還可以比較不加按鍵消抖情況下實(shí)際的效果對(duì)比如何。

            信號(hào)引腳
            clkJ5
            rstJ9
            keyK14
            ledN15

            在本實(shí)驗(yàn)學(xué)習(xí)了如何進(jìn)行按鍵的消抖。在很多應(yīng)用情況下我們必須采取消抖才能更好地控制邏輯。在下一個(gè)實(shí)驗(yàn)計(jì)時(shí)控制中我們將學(xué)習(xí)計(jì)時(shí)的顯示和控制,在這里我們要用到按鍵的消抖以及數(shù)碼管,我們甚至可以用做一個(gè)計(jì)時(shí)器甚至電子表。



            關(guān)鍵詞: 消抖 FPGA Lattice Diamond 小腳丫

            評(píng)論


            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉