键盘ps/2信号传输

ps/2简介

PS/2 接口使用两根信号线,一根信号线传输时钟 PS2_CLK,另一根传输数据 PS2_DAT。时钟信号主要用于指示数据线上的比特位在什么时候是有效的。
键盘和主机间可以进行数据双向传送,这里只讨论键盘向主机传送数据的情况。当 PS2_DAT 和 PS2_CLK 信号线都为高电平(空闲)时,键盘才可以给主机发送信号。
如果主机将 PS2_CLK 信号置低,键盘将准备接受主机发来的命令。
当用户按键或松开时,键盘以每帧 11 位的格式串行传送数据给主机,同时在 PS2_CLK 时钟信号上传输对应的时钟(一般为 10.0–16.7kHz)。第一位是
开始位(逻辑 0),后面跟 8 位数据位(低位在前),一个奇偶校验位(奇校验)和一位停止位(逻辑 1)。

示例代码

使用FIFO序列,进行缓存。

module ps2_keyboard(clk,clrn,ps2_clk,ps2_data,data,ready,nextdata_n,overflow);
	input clk,clrn,ps2_clk,ps2_data;
	input nextdata_n;
	output [7:0] data;
	output reg ready;
	output reg overflow; 
	reg [9:0] buffer; // ps2_data bits
	reg [7:0] fifo[7:0]; // data fifo
	reg [2:0] w_ptr,r_ptr; // fifo write and read pointers
	reg [3:0] count; 
	reg [2:0] ps2_clk_sync;
	always @(posedge clk) 
	begin
		ps2_clk_sync <= {ps2_clk_sync[1:0],ps2_clk};
	end

	wire sampling = ps2_clk_sync[2] & ~ps2_clk_sync[1];
	always @(posedge clk) 
	begin
		if (clrn == 0) 
		begin // reset
		count <= 0; w_ptr <= 0; r_ptr <= 0; overflow <= 0; ready<= 0;
		end
		else 
		begin
			if ( ready ) 
			begin // read to output next data
				if(nextdata_n == 1'b0) //read next data
				begin
					r_ptr <= r_ptr + 3'b1;
					if(w_ptr==(r_ptr+1'b1)) //empty
						ready <= 1'b0;
				end
			end
			if (sampling) 
				begin
					if (count == 4'd10) 
					begin
						if ((buffer[0] == 0) && (ps2_data) && (^buffer[9:1]))
						begin // odd parity
							fifo[w_ptr] <= buffer[8:1]; // kbd scan code
							w_ptr <= w_ptr+3'b1;
							ready <= 1'b1;
							overflow <= overflow | (r_ptr == (w_ptr + 3'b1));
						end
						count <= 0; // for next
					end 
					else 
					begin
						buffer[count] <= ps2_data; // store ps2_data
						count <= count + 3'b1;
					end
				end
		end
	end
	assign data = fifo[r_ptr]; //always set output data
	
endmodule

本文作者:心比天高xzh

本文链接:https://www.cnblogs.com/xzh-personal-issue/p/17356627.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   心比天高xzh  阅读(239)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起