新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 基于STEP FPGA的矩陣按鍵驅動

        基于STEP FPGA的矩陣按鍵驅動

        作者: 時間:2023-11-22 來源:電子森林 收藏

        硬件說明

        在鍵盤中按鍵數量較多時,為了減少I/O口的占用,通常將按鍵排列成矩陣形式,使用行線和列線分別連接到按鍵開關的兩端,這樣我們就可以通過4根行線和4根列線(共8個I/O口)連接16個按鍵,而且按鍵數量越多優勢越明顯。

        本文引用地址:http://www.104case.com/article/202311/453167.htm

        FPGA驅動矩陣按鍵模塊,首先我們來了解矩陣按鍵的硬件連接:

        上圖為4×4矩陣按鍵的硬件電路圖,可以看到4根行線(ROW1、ROW2、ROW3、ROW4)和4根列線(COL1、COL2、COL3、COL4),同時列線通過上拉電阻連接到VCC電壓(3.3V),對于矩陣按鍵來講:

        1. 4根行線是輸入的,是由FPGA控制拉高或拉低,
        2. 4根列線數輸出的,是由4根行線的輸入及按鍵的狀態決定,輸出給FPGA

        當某一時刻,FPGA控制4根行線分別為ROW1=0、ROW2=1、ROW3=1、ROW4=1時,

        • 對于K1、K2、K3、K4按鍵:按下時對應4根列線輸出COL1=0、COL2=0、COL3=0、COL4=0,不按時對應4根列線輸出COL1=1、COL2=1、COL3=1、COL4=1,
        • 對于K5~~~K16之間的按鍵:無論按下與否,對應4根列線輸出COL1=1、COL2=1、COL3=1、COL4=1,

        通過上面的描述:在這一時刻只有K1、K2、K3、K4按鍵被按下,才會導致4根列線輸出COL1=0、COL2=0、COL3=0、COL4=0,否則COL1=1、COL2=1、COL3=1、COL4=1,反之當FPGA檢測到列線(COL1、COL2、COL3、COL4)中有低電平信號時,對應的K1、K2、K3、K4按鍵應該是被按下了。

        按照掃描的方式,一共分為4個時刻,分別對應4根行線中的一根拉低,4個時刻依次循環,這樣就完成了矩陣按鍵的全部掃描檢測,我們在程序中以這4個時刻對應狀態機的4個狀態。 至于循環的周期,根據我們基礎教程里可知,按鍵抖動的不穩定時間在10ms以內,所以對同一個按鍵采樣的周期大于10ms,這同樣取20ms時間。20ms時間對應4個狀態,每5分鐘進行一次狀態轉換。


        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	//定義計數器cnt的計數范圍,例化時可更改)(
        	input					clk_in,			//系統時鐘
        	input					rst_n_in,		//系統復位,低有效
        	input			[3:0]	col,			//矩陣按鍵列接口
        	output	reg		[3:0]	row,			//矩陣按鍵行接口
        	output	reg		[15:0]	key_out			//消抖后的信號);/*
        因使用4x4矩陣按鍵,通過掃描方法實現,所以這里使用狀態機實現,共分為4種狀態
        在其中的某一狀態時間里,對應的4個按鍵相當于獨立按鍵,可按獨立按鍵的周期采樣法采樣
        周期采樣時每隔20ms采樣一次,對應這里狀態機每隔20ms循環一次,每個狀態對應5ms時間
        對矩陣按鍵實現原理不明白的,請去了解矩陣按鍵實現原理
        */	
        	localparam			STATE0 = 2'b00;
        	localparam			STATE1 = 2'b01;
        	localparam			STATE2 = 2'b10;
        	localparam			STATE3 = 2'b11; 	//計數器計數分頻實現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		//復位時計數器cnt清零,clk_200hz信號起始電平為低電平
        			cnt <= 16'd0;
        			clk_200hz <= 1'b0;
        		end else begin
        			if(cnt >= ((NUM_FOR_200HZ>>1) - 1)) begin	//數字邏輯中右移1位相當于除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;
        	//狀態機根據clk_200hz信號在4個狀態間循環,每個狀態對矩陣按鍵的行接口單行有效
        	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	//狀態c_state跳轉及對應狀態下矩陣按鍵的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 	//因為每個狀態中單行有效,通過對列接口的電平狀態采樣得到對應4個按鍵的狀態,依次循環
        	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;		//采集當前狀態的列數據賦值給對應的寄存器位
        				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

        小結

        本節主要為大家講解了矩陣按鍵的工作原理及軟件設計,需要大家掌握的同時自己創建工程,通過整個設計流程,生成FPGA配置文件加載測試。
        如果你對Diamond軟件的使用不了解,請參考這里:Diamond的使用。



        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 民和| 永和县| 襄樊市| 观塘区| 水城县| 瓦房店市| 伊宁市| 电白县| 松江区| 九龙县| 永昌县| 石嘴山市| 石楼县| 漳州市| 孝感市| 远安县| 从化市| 乐陵市| 饶河县| 阿克苏市| 个旧市| 汕尾市| 浏阳市| 昌图县| 囊谦县| 隆回县| 锡林郭勒盟| 孟村| 绵阳市| 昭苏县| 望江县| 南川市| 乐东| 桐城市| 沅江市| 九寨沟县| 汉阴县| 黑山县| 徐州市| 明光市| 东明县|