本系列將帶來FPGA的系統(tǒng)性學(xué)習(xí),從最基本的數(shù)字電路基礎(chǔ)開始,最詳細(xì)操作步驟,最直白的言語描述,手把手的“傻瓜式”講解,讓電子、信息、通信類專業(yè)學(xué)生、初入職場小白及打算進(jìn)階提升的職業(yè)開發(fā)者都可以有系統(tǒng)性學(xué)習(xí)的機(jī)會。
系統(tǒng)性的掌握技術(shù)開發(fā)以及相關(guān)要求,對個(gè)人就業(yè)以及職業(yè)發(fā)展都有著潛在的幫助,希望對大家有所幫助。后續(xù)會陸續(xù)更新 Xilinx 的 Vivado、ISE 及相關(guān)操作軟件的開發(fā)的相關(guān)內(nèi)容,學(xué)習(xí)FPGA設(shè)計(jì)方法及設(shè)計(jì)思想的同時(shí),實(shí)操結(jié)合各類操作軟件,會讓你在技術(shù)學(xué)習(xí)道路上無比的順暢,告別技術(shù)學(xué)習(xí)小BUG卡破腦殼,告別目前忽悠性的培訓(xùn)誘導(dǎo),真正的去學(xué)習(xí)去實(shí)戰(zhàn)應(yīng)用,這種快樂試試你就會懂的。話不多說,上貨。
按鍵控制LED
利用按鍵控制LED的要求為:按一下按鍵,改變一下LED的狀態(tài)。按鍵按一次,LED由熄滅變?yōu)辄c(diǎn)亮,按鍵再按一次,LED由點(diǎn)亮變?yōu)橄纭?/p>
硬件介紹
開發(fā)板上面有四個(gè)按鍵,當(dāng)按鍵按下時(shí),將對應(yīng)的網(wǎng)絡(luò)置成低電平;當(dāng)按鍵釋放時(shí),將對應(yīng)的網(wǎng)絡(luò)置成高電平。
開發(fā)板上面有四個(gè)LED發(fā)光二極管,F(xiàn)PGA輸出高電平時(shí),LED點(diǎn)亮;FPGA輸出低電平時(shí),LED熄滅。
設(shè)計(jì)原理
通常的按鍵所用開關(guān)為機(jī)械彈性開關(guān),當(dāng)機(jī)械觸點(diǎn)斷開、閉合時(shí),由于機(jī)械觸點(diǎn)的彈性作用,一個(gè)按鍵開關(guān)在閉合時(shí)不會馬上穩(wěn)定地接通,在斷開時(shí)也不會一下子斷開。因而在閉合及斷開的瞬間均伴隨有一連串的抖動(dòng)。
按鍵抖動(dòng)會引起一次按鍵被誤讀多次。為確保CPU對鍵的一次閉合僅作一次處理,必須去除鍵抖動(dòng)。在鍵閉合穩(wěn)定時(shí)讀取鍵的狀態(tài),并且必須判別到鍵釋放穩(wěn)定后再作處理。
抖動(dòng)時(shí)間的長短由按鍵的機(jī)械特性決定,一般為5ms~10ms。這是一個(gè)很重要的時(shí)間參數(shù),在很多場合都要用到。按鍵穩(wěn)定閉合時(shí)間的長短則是由操作人員的按鍵動(dòng)作決定的,一般為零點(diǎn)幾秒至數(shù)秒。
我們可以在按鍵和主控設(shè)備之間加入消抖電路(消抖芯片、電容等),此種方法會增大PCB面積和花費(fèi)一定的物料費(fèi)用。大多數(shù)的板子直接將按鍵和主控設(shè)備相連接,將帶有抖動(dòng)的波形輸入到主控設(shè)備內(nèi)部,由內(nèi)部進(jìn)行消抖處理。
單片機(jī)一般采用延遲重采樣的方式進(jìn)行消抖。當(dāng)檢測到信號為低時(shí),延遲一段時(shí)間(一般為20ms),再次檢測信號是否為低,如果為低,則證明按鍵按下,否則認(rèn)為按鍵沒有按下,繼續(xù)下一次檢查。
在FPGA設(shè)計(jì)時(shí),筆者推薦另外一種方式:持續(xù)采樣。當(dāng)檢測到信號持續(xù)為低10ms,認(rèn)為按鍵按下;當(dāng)檢測到信號持續(xù)為高10ms,認(rèn)為按鍵釋放。
在設(shè)計(jì)時(shí),需要考慮到外部的按鍵信號為異步信號,需要進(jìn)行同步處理。具體請參考附錄2 FPGA中的同步信號、異步信號和亞穩(wěn)態(tài)。
每次按鍵按下的時(shí)間的長短不一,經(jīng)過消抖后,低電平的持續(xù)長度長短也不一樣。此長度遠(yuǎn)遠(yuǎn)大于一個(gè)時(shí)鐘周期的長度。要求每次按下只能夠切換一次LED的狀態(tài),所以不能夠直接用此電平當(dāng)做輸出翻轉(zhuǎn)的使能。
經(jīng)過消抖的波形,每次按下只有一個(gè)下降沿(按鍵按下時(shí))、只有一個(gè)上升沿(按鍵釋放時(shí))。所以通過檢測下降沿(上升沿)的變化,產(chǎn)生一個(gè)新的信號------脈沖(一個(gè)時(shí)鐘周期的脈沖),利用此脈沖作為翻轉(zhuǎn)的使能即可。利用檢測到下降沿的脈沖翻轉(zhuǎn)時(shí),LED的狀態(tài)會在按下時(shí)就會改變;利用檢測到上升沿的脈沖翻轉(zhuǎn)時(shí),LED的狀態(tài)會在釋放時(shí)發(fā)生改變。本設(shè)計(jì)中采用檢測到下降沿的脈沖進(jìn)行翻轉(zhuǎn)。
設(shè)計(jì)架構(gòu)和信號說明
本設(shè)計(jì)模塊命名為key_led。
在設(shè)計(jì)中,共分為三個(gè)模塊。
key_filter(按鍵消抖模塊):將外部輸入的帶有抖動(dòng)的波形進(jìn)行消抖。
edge_check(邊沿檢測模塊):將消抖后的波形進(jìn)行下降沿檢測,并產(chǎn)生對應(yīng)的脈沖。
led_ctrl(led控制模塊):利用脈沖,翻轉(zhuǎn)led的輸出狀態(tài)。
key_filter設(shè)計(jì)實(shí)現(xiàn)
本設(shè)計(jì)采用狀態(tài)機(jī)實(shí)現(xiàn),狀態(tài)機(jī)的具體原理請參看附錄3。
對key_n信號為異步信號,需要進(jìn)行同步兩拍,命名為key_n_r和key_n_rr。狀態(tài)機(jī)的判斷信號為key_n_rr信號。
本設(shè)計(jì)共分為四個(gè)狀態(tài),KEY_OFF(按鍵釋放狀態(tài)),SHAKE_ON(按鍵按下時(shí)抖動(dòng)判斷狀態(tài)),KEY_ON(按鍵按下狀態(tài)),SHAKE_OFF(按鍵釋放時(shí)抖動(dòng)判斷狀態(tài))。
按鍵沒有按下時(shí),一直KEY_OFF狀態(tài),當(dāng)按鍵信號變?yōu)榈碗娖綍r(shí),就轉(zhuǎn)入SHAKE_ON狀態(tài),檢測低電平的持續(xù)時(shí)間。如果持續(xù)時(shí)間沒有達(dá)到T_10ms就變?yōu)楦唠娖?,則清零計(jì)數(shù)器并返回KEY_OFF狀態(tài);如果持續(xù)時(shí)間沒有達(dá)到T_10ms并且也一直為低電平,則繼續(xù)在SHAKE_ON狀態(tài)計(jì)數(shù);如果持續(xù)時(shí)間達(dá)到T_10ms并且為低電平,則清零計(jì)數(shù)器并進(jìn)入KEY_ON狀態(tài)。在KEY_ON狀態(tài),外部輸入為低電平時(shí),則繼續(xù)在KEY_ON狀態(tài);如果外部輸出為高電平,則轉(zhuǎn)入SHAKE_OFF狀態(tài)。在SHAKE_OFF狀態(tài),如果持續(xù)時(shí)間沒有到達(dá)T_10ms就變?yōu)榈碗娖?,則清零計(jì)數(shù)器并返回KEY_ON狀態(tài);如果持續(xù)時(shí)間沒有達(dá)到T_10ms并且一直為高電平,則繼續(xù)在SHAKE_OFF狀態(tài)計(jì)數(shù);如果持續(xù)時(shí)間達(dá)到T_10ms并且一直為高電平,則清零計(jì)數(shù)器并轉(zhuǎn)入KEY_OFF狀態(tài)。
在KEY_OFF和SHAKE_ON狀態(tài),認(rèn)為按鍵沒有按下;在KEY_ON和SHAKE_OFF狀態(tài),認(rèn)為按鍵為按下。
狀態(tài)轉(zhuǎn)移圖如下:
設(shè)計(jì)代碼為:
localparam可以定義參數(shù),與parameter的區(qū)別在于,parameter定義的參數(shù)可以在例化時(shí)進(jìn)行參數(shù)修改,而localparam定義的參數(shù)在例化時(shí)則不能夠修改。定義狀態(tài)機(jī)狀態(tài)時(shí),一般采用localparam的定義方式。在不希望別人修改參數(shù)時(shí),也可以定義為localparam。
edge_check設(shè)計(jì)實(shí)現(xiàn)
在一個(gè)波形中,如果當(dāng)前時(shí)刻為低電平,上一個(gè)時(shí)刻為高電平,則認(rèn)為波形中有一個(gè)下降沿;如果當(dāng)前時(shí)刻為高電平,上一個(gè)時(shí)刻為低電平,則認(rèn)為波形中有一個(gè)上升沿。
在數(shù)字電路設(shè)計(jì)時(shí),可以采用寄存器來存儲上一個(gè)時(shí)刻的值。
在寄存器電路中,Q的值,永遠(yuǎn)是上一個(gè)CLK的有效邊沿所采樣的D值。因此Q為上一時(shí)刻值,而D為當(dāng)前時(shí)刻的值。
設(shè)計(jì)代碼為:
在設(shè)計(jì)中,注釋掉的兩行代碼和其下方的一行代碼的功能是相同的。例:對于上升沿脈沖來說,現(xiàn)在為1,過去為0即為上升沿。由于寄存器每個(gè)時(shí)鐘周期都刷新,滿足這個(gè)要求的只會存在一個(gè)時(shí)鐘周期,所以flag_pos為一個(gè)時(shí)鐘周期的脈沖。
led_ctrl設(shè)計(jì)實(shí)現(xiàn)
本模塊中,利用脈沖進(jìn)行l(wèi)ed狀態(tài)的翻轉(zhuǎn)即可。
設(shè)計(jì)代碼為:
key_led設(shè)計(jì)實(shí)現(xiàn)
本模塊只是負(fù)責(zé)將上述的三個(gè)模塊按照架構(gòu)圖的方式進(jìn)行連接,形成最終的設(shè)計(jì)。
設(shè)計(jì)代碼為:
在設(shè)計(jì)中,采用了按鍵按下時(shí)的脈沖(檢測到下降沿的脈沖),按鍵按下時(shí)led的狀態(tài)即可進(jìn)行翻轉(zhuǎn)。
功能仿真
在仿真時(shí),將按鍵消抖中的T_10ms的參數(shù)修改為20,即持續(xù)時(shí)間不超過400ns都不認(rèn)為是有效按下或者抬起。
仿真代碼如下:
將okey_n、flag信號添加出來。
通過RTL仿真圖,可以清晰的看到okey_n信號將key_n的抖動(dòng)濾除掉;flag信號為okey_n信號的下降沿時(shí)所產(chǎn)生的脈沖;led在flag信號為高時(shí),反正翻轉(zhuǎn)。
分配管腳、下板測試之前,應(yīng)該將按鍵消抖里面的T_10ms參數(shù)重新改為500_000,否則下板后可能會達(dá)不到消抖的效果。
下板成功后,可以修改在設(shè)計(jì)中使用上升沿的脈沖,得到的現(xiàn)象應(yīng)該是按鍵釋放時(shí),LED的狀態(tài)發(fā)生反轉(zhuǎn)。
切記:每次修改代碼,一定要進(jìn)行重新編譯,否則更改將不會生效。
更多熱點(diǎn)文章閱讀
-
電子技術(shù)
+關(guān)注
關(guān)注
18文章
912瀏覽量
56204 -
電子發(fā)燒友論壇
+關(guān)注
關(guān)注
4文章
197瀏覽量
1125
原文標(biāo)題:【教程分享】 FPGA零基礎(chǔ)學(xué)習(xí):按鍵控制LED
文章出處:【微信號:gh_9b9470648b3c,微信公眾號:電子發(fā)燒友論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論