键盘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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步