<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于STEP FPGA的矩陣按鍵驅(qū)動(dòng)

          基于STEP FPGA的矩陣按鍵驅(qū)動(dòng)

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

          硬件說(shuō)明

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

          本文引用地址:http://www.ex-cimer.com/article/202311/453167.htm

          FPGA驅(qū)動(dòng)矩陣按鍵模塊,首先我們來(lái)了解矩陣按鍵的硬件連接:

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

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

          當(dāng)某一時(shí)刻,F(xiàn)PGA控制4根行線分別為ROW1=0、ROW2=1、ROW3=1、ROW4=1時(shí),

          • 對(duì)于K1、K2、K3、K4按鍵:按下時(shí)對(duì)應(yīng)4根列線輸出COL1=0、COL2=0、COL3=0、COL4=0,不按時(shí)對(duì)應(yīng)4根列線輸出COL1=1、COL2=1、COL3=1、COL4=1,
          • 對(duì)于K5~~~K16之間的按鍵:無(wú)論按下與否,對(duì)應(yīng)4根列線輸出COL1=1、COL2=1、COL3=1、COL4=1,

          通過(guò)上面的描述:在這一時(shí)刻只有K1、K2、K3、K4按鍵被按下,才會(huì)導(dǎo)致4根列線輸出COL1=0、COL2=0、COL3=0、COL4=0,否則COL1=1、COL2=1、COL3=1、COL4=1,反之當(dāng)FPGA檢測(cè)到列線(COL1、COL2、COL3、COL4)中有低電平信號(hào)時(shí),對(duì)應(yīng)的K1、K2、K3、K4按鍵應(yīng)該是被按下了。

          按照掃描的方式,一共分為4個(gè)時(shí)刻,分別對(duì)應(yīng)4根行線中的一根拉低,4個(gè)時(shí)刻依次循環(huán),這樣就完成了矩陣按鍵的全部掃描檢測(cè),我們?cè)诔绦蛑幸赃@4個(gè)時(shí)刻對(duì)應(yīng)狀態(tài)機(jī)的4個(gè)狀態(tài)。 至于循環(huán)的周期,根據(jù)我們基礎(chǔ)教程里可知,按鍵抖動(dòng)的不穩(wěn)定時(shí)間在10ms以內(nèi),所以對(duì)同一個(gè)按鍵采樣的周期大于10ms,這同樣取20ms時(shí)間。20ms時(shí)間對(duì)應(yīng)4個(gè)狀態(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	//定義計(jì)數(shù)器cnt的計(jì)數(shù)范圍,例化時(shí)可更改)(
          	input					clk_in,			//系統(tǒng)時(shí)鐘
          	input					rst_n_in,		//系統(tǒng)復(fù)位,低有效
          	input			[3:0]	col,			//矩陣按鍵列接口
          	output	reg		[3:0]	row,			//矩陣按鍵行接口
          	output	reg		[15:0]	key_out			//消抖后的信號(hào));/*
          因使用4x4矩陣按鍵,通過(guò)掃描方法實(shí)現(xiàn),所以這里使用狀態(tài)機(jī)實(shí)現(xiàn),共分為4種狀態(tài)
          在其中的某一狀態(tài)時(shí)間里,對(duì)應(yīng)的4個(gè)按鍵相當(dāng)于獨(dú)立按鍵,可按獨(dú)立按鍵的周期采樣法采樣
          周期采樣時(shí)每隔20ms采樣一次,對(duì)應(yīng)這里狀態(tài)機(jī)每隔20ms循環(huán)一次,每個(gè)狀態(tài)對(duì)應(yīng)5ms時(shí)間
          對(duì)矩陣按鍵實(shí)現(xiàn)原理不明白的,請(qǐng)去了解矩陣按鍵實(shí)現(xiàn)原理
          */	
          	localparam			STATE0 = 2'b00;
          	localparam			STATE1 = 2'b01;
          	localparam			STATE2 = 2'b10;
          	localparam			STATE3 = 2'b11; 	//計(jì)數(shù)器計(jì)數(shù)分頻實(shí)現(xiàn)5ms周期信號(hào)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í)計(jì)數(shù)器cnt清零,clk_200hz信號(hào)起始電平為低電平
          			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信號(hào)取反
          			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信號(hào)在4個(gè)狀態(tài)間循環(huán),每個(gè)狀態(tài)對(duì)矩陣按鍵的行接口單行有效
          	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)及對(duì)應(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 	//因?yàn)槊總€(gè)狀態(tài)中單行有效,通過(guò)對(duì)列接口的電平狀態(tài)采樣得到對(duì)應(yīng)4個(gè)按鍵的狀態(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ù)賦值給對(duì)應(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è)計(jì),需要大家掌握的同時(shí)自己創(chuàng)建工程,通過(guò)整個(gè)設(shè)計(jì)流程,生成FPGA配置文件加載測(cè)試。
          如果你對(duì)Diamond軟件的使用不了解,請(qǐng)參考這里:Diamond的使用。



          評(píng)論


          相關(guān)推薦

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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();