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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 基于STEP FPGA的PS2鍵盤驅(qū)動

          基于STEP FPGA的PS2鍵盤驅(qū)動

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

          硬件說明

          我們的STEP-BaseBoard底板上集成了PS2鍵盤的接口,可以供大家連接PS2鍵盤或PS2鼠標完成相應設計,接下來我們來了解PS2接口的硬件連接及PS2鍵盤的驅(qū)動方法。
          PS2接口連線非常簡單,只需接4根線:

          本文引用地址:http://www.ex-cimer.com/article/202311/453397.htm
          • 4號引腳VCC接供電電源,一般為5V供電,后經(jīng)測試3.3V也可以
          • 3號引腳GND接地即可
          • 5號引腳時鐘線和1號引腳數(shù)據(jù)線為兩條雙向的信號線
          • 2號引腳和6號引腳為保留引腳,不需要連接

          當PS2鍵盤上有按鍵按動或操作的時候,鍵盤會發(fā)信號給主機,PS2接口的時鐘信號和數(shù)據(jù)信號的時序如下圖:

          FPGA或主機接收鍵盤發(fā)回的數(shù)據(jù),通過鍵盤的編碼規(guī)則判定鍵盤當前的操作,掃描碼有兩種不同的類型:通碼(make code)和斷碼(break code)。當一個鍵被按下或持續(xù)按住時,鍵盤會將該鍵的通碼發(fā)送給主機;而當一個鍵被釋放時,鍵盤會將該鍵的斷碼發(fā)送給主機。
          根據(jù)鍵盤按鍵掃描碼的不同,在此可將按鍵分為如下幾類:

          • 第一類按鍵,通碼為1字節(jié),斷碼為0xF0+通碼形式。如A鍵,其通碼為0x1C,斷碼為0xF0 0x1C。
          • 第二類按鍵,通碼為2字節(jié)0xE0+0xXX形式,斷碼為0xE0+0xF0+0xXX形式。如right ctrl鍵,其通碼為0xE0 0x14,斷碼為0xE0 0xF0 0x14。
          • 第三類特殊按鍵有兩個,print screen鍵通碼為0xE0 0x12 0xE0 0x7C,斷碼為0xE0 0xF0 0x7C 0xE0 0xF0 0x12; pause鍵通碼為0x E1 0x14 0x77 0xE1 0xF0 0x14 0xF0 0x77,斷碼為空。

          組合按鍵的掃描碼發(fā)送按照按鍵發(fā)生的次序,如以下面順序按左SHIFT+A鍵:1按下左SHIFT鍵,2按下A鍵,3釋放A鍵,4釋放左SHIFT鍵,那么計算機上接收到的一串數(shù)據(jù)為0x12 0x1C 0xF0 0x1C 0xF0 0x12。
          在驅(qū)動程序設計中,就是根據(jù)這樣的分類來對不同的按鍵進行不同處理的,當前簡單程序只支持第一類按鍵的操作。
          鍵盤中不同按鍵的編碼如下:

          Verilog代碼

          // --------------------------------------------------------------------
          // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
          // --------------------------------------------------------------------
          // Module: Keyboard_PS2
          // 
          // Author: Step
          // 
          // Description: PS2 keyboard driver
          // 
          // --------------------------------------------------------------------
          // Code Revision History :
          // --------------------------------------------------------------------
          // Version: |Mod. Date:   |Changes Made:
          // V1.0     |2016/04/20   |Initial ver
          // --------------------------------------------------------------------
          module Keyboard_PS2
          (
          input					clk_in,				//系統(tǒng)時鐘
          input					rst_n_in,			//系統(tǒng)復位,低有效
          input					key_clk,			//PS2鍵盤時鐘輸入
          input					key_data,			//PS2鍵盤數(shù)據(jù)輸入
          output	reg				key_state,			//鍵盤的按下狀態(tài),按下為1,松開為0
          output	reg		[7:0]	key_ascii			//按鍵鍵值對應的ASCII編碼); 
          /*
          這個模塊為FPGA驅(qū)動PS2鍵盤的簡單程序,只能支持鍵盤中第一類按鍵的單鍵按動,不支持多個按鍵同時按動
          */ 
          reg		key_clk_r0 = 1'b1,key_clk_r1 = 1'b1; 
          reg		key_data_r0 = 1'b1,key_data_r1 = 1'b1;
          //對鍵盤時鐘數(shù)據(jù)信號進行延時鎖存
          always @ (posedge clk_in or negedge rst_n_in) begin
          	if(!rst_n_in) begin
          		key_clk_r0 <= 1'b1;
          		key_clk_r1 <= 1'b1;
          		key_data_r0 <= 1'b1;
          		key_data_r1 <= 1'b1;
          	end else begin
          		key_clk_r0 <= key_clk;
          		key_clk_r1 <= key_clk_r0;
          		key_data_r0 <= key_data;
          		key_data_r1 <= key_data_r0;
          	endend //鍵盤時鐘信號下降沿檢測
          	wire	key_clk_neg = key_clk_r1 & (~key_clk_r0);  
          	reg				[3:0]	cnt; 
          	reg				[7:0]	temp_data;
          	//根據(jù)鍵盤的時鐘信號的下降沿讀取數(shù)據(jù),詳細參考PS2鍵盤數(shù)據(jù)的傳輸格式及時序
          	always @ (posedge clk_in or negedge rst_n_in) begin
          	if(!rst_n_in) begin
          		cnt <= 4'd0;
          		temp_data <= 8'd0;
          	end else if(key_clk_neg) begin 
          		if(cnt >= 4'd10) cnt <= 4'd0;
          		else cnt <= cnt + 1'b1;
          		case (cnt)
          			4'd0: ;	//起始位
          			4'd1: temp_data[0] <= key_data_r1;  //數(shù)據(jù)位bit0
          			4'd2: temp_data[1] <= key_data_r1;  //數(shù)據(jù)位bit1
          			4'd3: temp_data[2] <= key_data_r1;  //數(shù)據(jù)位bit2
          			4'd4: temp_data[3] <= key_data_r1;  //數(shù)據(jù)位bit3
          			4'd5: temp_data[4] <= key_data_r1;  //數(shù)據(jù)位bit4
          			4'd6: temp_data[5] <= key_data_r1;  //數(shù)據(jù)位bit5
          			4'd7: temp_data[6] <= key_data_r1;  //數(shù)據(jù)位bit6
          			4'd8: temp_data[7] <= key_data_r1;  //數(shù)據(jù)位bit7
          			4'd9: ;	//校驗位
          			4'd10:;	//結束位
          			default: ;
          		endcase
          	end
          end 
          	reg						key_break = 1'b0;   
          	reg				[7:0]	key_byte = 1'b0;//根據(jù)通碼和斷碼判定按鍵的當前是按下還是松開
          	always @ (posedge clk_in or negedge rst_n_in) begin 
          	if(!rst_n_in) begin
          		key_break <= 1'b0;
          		key_state <= 1'b0;
          		key_byte <= 1'b0;
          	end else if(cnt==4'd10 && key_clk_neg) begin 
          		if(temp_data == 8'hf0) key_break <= 1'b1;	//收到段碼(8'hf0)表示按鍵松開,設置斷碼標示為1
          		else if(!key_break) begin 	//當斷碼標示為0時,表示當前數(shù)據(jù)為按下數(shù)據(jù),輸出鍵值并設置按下標示為1
          			key_state <= 1'b1;
          			key_byte <= temp_data; 
          		end else begin	//當斷碼標示為1時,標示當前數(shù)據(jù)為松開數(shù)據(jù),斷碼標示和按下標示都清零
          			key_state <= 1'b0;
          			key_break <= 1'b0;
          		end
          	endend //將鍵盤返回的有效鍵值轉(zhuǎn)換為按鍵字母對應的ASCII碼值
          	always @ (key_byte) begin
          	case (key_byte)    //translate key_byte to key_ascii
          		8'h15: key_ascii = "Q";//8'h51;   //Q
          		8'h1d: key_ascii = "W";//8'h57;   //W
          		8'h24: key_ascii = "E";//8'h45;   //E
          		8'h2d: key_ascii = "R";//8'h52;   //R
          		8'h2c: key_ascii = "T";//8'h54;   //T
          		8'h35: key_ascii = "Y";//8'h59;   //Y
          		8'h3c: key_ascii = "U";//8'h55;   //U
          		8'h43: key_ascii = "I";//8'h49;   //I
          		8'h44: key_ascii = "O";//8'h4f;   //O
          		8'h4d: key_ascii = "P";//8'h50;   //P
          		8'h1c: key_ascii = "A";//8'h41;   //A
          		8'h1b: key_ascii = "S";//8'h53;   //S
          		8'h23: key_ascii = "D";//8'h44;   //D
          		8'h2b: key_ascii = "F";//8'h46;   //F
          		8'h34: key_ascii = "G";//8'h47;   //G
          		8'h33: key_ascii = "H";//8'h48;   //H
          		8'h3b: key_ascii = "J";//8'h4a;   //J
          		8'h42: key_ascii = "K";//8'h4b;   //K
          		8'h4b: key_ascii = "L";//8'h4c;   //L
          		8'h1a: key_ascii = "Z";//8'h5a;   //Z
          		8'h22: key_ascii = "X";//8'h58;   //X
          		8'h21: key_ascii = "C";//8'h43;   //C
          		8'h2a: key_ascii = "V";//8'h56;   //V
          		8'h32: key_ascii = "B";//8'h42;   //B
          		8'h31: key_ascii = "N";//8'h4e;   //N
          		8'h3a: key_ascii = "M";//8'h4d;   //M
          		default: ;
          	endcase
          	end 
          	endmodule

          小結

          本節(jié)主要為大家講解了PS2接口電路、PS2鍵盤編碼規(guī)則及使用FPGA簡單驅(qū)動PS2鍵盤的方法,需要大家掌握的同時自己創(chuàng)建工程,通過整個設計流程,生成FPGA配置文件加載測試。



          評論


          相關推薦

          技術專區(qū)

          關閉
          看屁屁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); })();