基于STEP FPGA的矩陣按鍵驅(qū)動
硬件說明
在鍵盤中按鍵數(shù)量較多時,為了減少I/O口的占用,通常將按鍵排列成矩陣形式,使用行線和列線分別連接到按鍵開關(guān)的兩端,這樣我們就可以通過4根行線和4根列線(共8個I/O口)連接16個按鍵,而且按鍵數(shù)量越多優(yōu)勢越明顯。
本文引用地址:http://butianyuan.cn/article/202311/453167.htmFPGA驅(qū)動矩陣按鍵模塊,首先我們來了解矩陣按鍵的硬件連接:
上圖為4×4矩陣按鍵的硬件電路圖,可以看到4根行線(ROW1、ROW2、ROW3、ROW4)和4根列線(COL1、COL2、COL3、COL4),同時列線通過上拉電阻連接到VCC電壓(3.3V),對于矩陣按鍵來講:
當(dāng)某一時刻,F(xiàn)PGA控制4根行線分別為ROW1=0、ROW2=1、ROW3=1、ROW4=1時,
通過上面的描述:在這一時刻只有K1、K2、K3、K4按鍵被按下,才會導(dǎo)致4根列線輸出COL1=0、COL2=0、COL3=0、COL4=0,否則COL1=1、COL2=1、COL3=1、COL4=1,反之當(dāng)FPGA檢測到列線(COL1、COL2、COL3、COL4)中有低電平信號時,對應(yīng)的K1、K2、K3、K4按鍵應(yīng)該是被按下了。
按照掃描的方式,一共分為4個時刻,分別對應(yīng)4根行線中的一根拉低,4個時刻依次循環(huán),這樣就完成了矩陣按鍵的全部掃描檢測,我們在程序中以這4個時刻對應(yīng)狀態(tài)機(jī)的4個狀態(tài)。 至于循環(huán)的周期,根據(jù)我們基礎(chǔ)教程里可知,按鍵抖動的不穩(wěn)定時間在10ms以內(nèi),所以對同一個按鍵采樣的周期大于10ms,這同樣取20ms時間。20ms時間對應(yīng)4個狀態(tài),每5分鐘進(jìn)行一次狀態(tài)轉(zhuǎn)換。
Verilog代碼
// -------------------------------------------------------------------- // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< // -------------------------------------------------------------------- // Module: Array_KeyBoard // // Author: Step// // Description: Array_KeyBoard // // // -------------------------------------------------------------------- // Code Revision History : // -------------------------------------------------------------------- // Version: |Mod. Date: |Changes Made: // V1.0 |2015/11/11 |Initial ver // -------------------------------------------------------------------- module Array_KeyBoard #( parameter NUM_FOR_200HZ = 60000 //定義計數(shù)器cnt的計數(shù)范圍,例化時可更改)( input clk_in, //系統(tǒng)時鐘 input rst_n_in, //系統(tǒng)復(fù)位,低有效 input [3:0] col, //矩陣按鍵列接口 output reg [3:0] row, //矩陣按鍵行接口 output reg [15:0] key_out //消抖后的信號);/* 因使用4x4矩陣按鍵,通過掃描方法實現(xiàn),所以這里使用狀態(tài)機(jī)實現(xiàn),共分為4種狀態(tài) 在其中的某一狀態(tài)時間里,對應(yīng)的4個按鍵相當(dāng)于獨立按鍵,可按獨立按鍵的周期采樣法采樣 周期采樣時每隔20ms采樣一次,對應(yīng)這里狀態(tài)機(jī)每隔20ms循環(huán)一次,每個狀態(tài)對應(yīng)5ms時間 對矩陣按鍵實現(xiàn)原理不明白的,請去了解矩陣按鍵實現(xiàn)原理 */ localparam STATE0 = 2'b00; localparam STATE1 = 2'b01; localparam STATE2 = 2'b10; localparam STATE3 = 2'b11; //計數(shù)器計數(shù)分頻實現(xiàn)5ms周期信號clk_200hz reg [15:0] cnt; reg clk_200hz; always@(posedge clk_in or negedge rst_n_in) begin if(!rst_n_in) begin //復(fù)位時計數(shù)器cnt清零,clk_200hz信號起始電平為低電平 cnt <= 16'd0; clk_200hz <= 1'b0; end else begin if(cnt >= ((NUM_FOR_200HZ>>1) - 1)) begin //數(shù)字邏輯中右移1位相當(dāng)于除2 cnt <= 16'd0; clk_200hz <= ~clk_200hz; //clk_200hz信號取反 end else begin cnt <= cnt + 1'b1; clk_200hz <= clk_200hz; end end end reg [1:0] c_state; //狀態(tài)機(jī)根據(jù)clk_200hz信號在4個狀態(tài)間循環(huán),每個狀態(tài)對矩陣按鍵的行接口單行有效 always@(posedge clk_200hz or negedge rst_n_in) begin if(!rst_n_in) begin c_state <= STATE0; row <= 4'b1110; end else begin case(c_state) STATE0: begin c_state <= STATE1; row <= 4'b1101; end //狀態(tài)c_state跳轉(zhuǎn)及對應(yīng)狀態(tài)下矩陣按鍵的row輸出 STATE1: begin c_state <= STATE2; row <= 4'b1011; end STATE2: begin c_state <= STATE3; row <= 4'b0111; end STATE3: begin c_state <= STATE0; row <= 4'b1110; end default:begin c_state <= STATE0; row <= 4'b1110; end endcase end end //因為每個狀態(tài)中單行有效,通過對列接口的電平狀態(tài)采樣得到對應(yīng)4個按鍵的狀態(tài),依次循環(huán) always@(negedge clk_200hz or negedge rst_n_in) begin if(!rst_n_in) begin key_out <= 16'hffff; end else begin case(c_state) STATE0:key_out[3:0] <= col; //采集當(dāng)前狀態(tài)的列數(shù)據(jù)賦值給對應(yīng)的寄存器位 STATE1:key_out[7:4] <= col; STATE2:key_out[11:8] <= col; STATE3:key_out[15:12] <= col; default:key_out <= 16'hffff; endcase end end endmodule
小結(jié)
本節(jié)主要為大家講解了矩陣按鍵的工作原理及軟件設(shè)計,需要大家掌握的同時自己創(chuàng)建工程,通過整個設(shè)計流程,生成FPGA配置文件加載測試。
如果你對Diamond軟件的使用不了解,請參考這里:Diamond的使用。
評論