原創 秦紅凱 明德揚FPGA科教 今天
一、項目背景概述
隨著生活質量的不斷提高,加強家庭防盜安全變得非常重要,但傳統機械鎖的構造過于簡單,很容易被打開,從而降低了安全性。數字密碼鎖因為它的保密性很高,安全系數也非常高,再加上其不需要攜帶避免了丟失的可能,省去了因鑰匙丟失而需要換鎖的麻煩,受到了越來越多的人的歡迎。隨看人們對高科技產品也越來越推崇,在當今社會科技的高度集中和創新,人們對日常生活中保護自身及財產安全的物品非常追捧,對其安全性的要求也非常的高。
為了達到人們對鎖具安全性的高要求,加強鎖具的安全保密性,用密碼鎖來取代傳統機械鎖的鎖具是必然趨勢。數字密碼鎖比傳統機械鎖具更加的安全 。
在本案例的設計過程中,應用了至簡設計法、狀態機模板應用等,在經過逐步改進、調試等一系列工作之后,最終達到了設計目標。
基于明德揚至簡設計法和明德揚設計規范,設計一個基于FPGA的密碼鎖、并將數值顯示在數碼管上,然后根據輸入的鍵值判斷密碼是否正確。
二、項目設計要求
1、通過矩陣鍵盤采樣輸入密碼;
2、數碼管顯示輸入的密碼
3、密碼正確,指示燈給出指示,不正確蜂鳴器給出報警
三、頂層接收設計
根據所有的功能要求,我們先對其進行結構劃分如下:
Key_in:開始模塊
Key_scan :按鍵掃描模塊
Code_detect:密碼比較模塊
Control:控制信號模塊
Dis_play:數碼管顯示模塊
Key_in |
比較按鍵輸入 |
Key_scan |
按鍵掃描,密碼檢測 |
Code_detect |
負責密碼的比較 |
Dis_play |
數碼管顯示 |
control |
負責輸出LED,BEEP控制 |
如果按鍵不多的話,我們可以直接按鍵與FPGA相連接,但是如果按鍵比較多的時候,如何還繼續使用直接按鍵與FPGA相連接的話,所會大量增加FPGA端口的消耗,為了減少FPGA端口的消耗,我們可以把按鍵設計成矩陣的形式,就如下圖所示:
信號名稱 |
I/O |
功能描述 |
clk |
I |
模塊時鐘 |
rst_n |
I |
模塊復位 |
key_col[3:0] |
I |
列信號 |
key_row[3:0] |
O |
行信號 |
Key_num |
O |
鍵值 |
Key_vld |
O |
按鍵有效 |
由上圖可以知道,矩陣鍵盤的行row(行)與col(列)的交點,都是通過一個按鍵來相連接。傳統的一個按鍵一個端口的方法,若要實現16個按鍵,則需要16個端口,而現在這個矩陣鍵盤的設計,16個按鍵,僅僅需要8個端口,如果使用16個端口來做矩陣鍵盤的話,可以識別64個按鍵,端口的利用率遠遠比傳統的設計好的多,所以如果需要的按鍵少的話,可以選擇傳統的按鍵設計,如果需要的按鍵比較多的話,可以采用這種矩陣鍵盤的設計。
而我們現在就以掃描法為例來介紹矩陣鍵盤的工作原理。
在進行鍵盤掃描時,應內部對信號進行按鍵消抖處理。
詳細內容可以參考明德揚另一篇文章:矩陣鍵盤的檢測。
密碼比較模塊:Code_detect
信號名稱 |
I/O |
功能描述 |
clk |
I |
模塊時鐘 |
rst_n |
I |
模塊復位 |
key_falg |
I |
按鍵按下標志信號 |
key_value[3:0] |
I |
按鍵值 |
start |
I |
開始比較 |
error |
O |
密碼錯誤 |
right |
O |
密碼正確 |
code[3:0] |
O |
輸入密碼 |
每次輸入4位數的密碼,所以每次按下一次,就將這詞的鍵值先存到寄存器中。
所以這里需要一個計數器,來計算是第幾次按下的操作
在使用一個時序邏輯,將上個模塊的鍵值存儲到寄存器。
控制模塊:control
信號名稱 |
I/O |
功能描述 |
clk |
I |
模塊時鐘 |
rst_n |
I |
模塊復位 |
error |
I |
錯誤信號 |
right |
I |
正確信號 |
beep |
o |
蜂鳴器 |
Error_led |
o |
錯誤指示燈 |
Right_led |
o |
正確指示燈 |
這個模塊要操作的信號較多,并且每種情況下,各個指示燈的情況也不一樣,為了設計的簡單,我們在這采用一個狀態機設計,每個狀態下規定不同的操作就行了。
狀態機的設計主要要有3個狀態,主要是有空閑狀態,正確狀態,錯誤狀態,狀態轉移圖如下所示:
空閑狀態:等待檢測
正確狀態:right_led亮
錯誤狀態:error_led亮,并且BEEP叫1s;
根據MDY的模板設計出4段狀態機:
根據模板我們只需要修改很少的部分就可以,
1根據自己的狀態圖,修改所需要的狀態轉移條件
2修改狀態發生變化的條件
3修改最后的輸出信號
本次需要注意的是89行中的時鐘條件被修改了,原因是,這幾個狀態中的燈亮或者蜂鳴器發出響聲會持續一段時間,狀態改變要等到每次小的狀態結束,或者接收到新的上有信號。
數碼管顯示模塊:dis_play
信號名稱 |
I/O |
功能描述 |
clk |
I |
模塊時鐘 |
rst_n |
I |
模塊復位 |
Code[3:0] |
I |
密碼 |
Seg_Sel[3:0] |
0 |
位選信號 |
Segment[7:0] |
0 |
段選信號 |
數碼管動態顯示接口是應用最為廣泛的一種顯示方式之一,動態驅動是將所有數碼管的 8 個顯示筆劃"a,b,c,d,e,f,g,dp"的同名端連在一起,另外為每個數碼管的公共極 COM 增加位選通控制電路,位選通由各自獨立的 I/O 線控制,當要輸出字形碼時,所有數碼管都接收相同的字形碼,但究竟是哪個數碼管會顯示出字形,取決于單片機對位選通 COM 端電路的控制,所以我們只要將需要顯示的數碼管的選通控制打開,該位就顯示出字形,沒有選通的數碼管就不會亮。
通過分時輪流控制各個數碼管的的 COM 端,就使各個數碼管輪流受控顯示,這就是動態驅動。在輪流顯示過程中,每位數碼管的點亮時間為 1~2ms,由于人的視覺暫留現象及發光二極管的余輝效應,盡管實際上各位數碼管并非同時點亮,但只要掃描的速度足夠快,給人的印象就是一組穩定的顯示數據,不會有閃爍感,動態顯示的效果和靜態顯示是一樣的,能夠節省大量的 I/O 端口,而且功耗更低。
動態掃描是利用人眼視覺滯留的特點,點亮某一位后,在人眼反應之前,進行下一位的顯示,故而出現重影現象。而人的視覺暫留時間大約在1/24秒左右,所以應該保持24幀以上才會保持連續而不會出現閃爍,通俗來講,應該在一秒內至少掃描多次。也就是每次掃描時間至少小于40ms 。
相關代碼可參考之前設計:“數字秒表”一文中。
四、實驗總結:
事先在程序中設置內置密碼為1111,當下載完成后輸入4591,按下確認鍵之后,發現正確的燈不變化,蜂鳴器會響持續1s,重新輸入1111后,正確的燈會先滅然后恢復,蜂鳴器也不發聲,說明設計正確。