搜索
bottom↓
回复: 234

FPGA模拟PS2协议,丢掉4x4键盘,来用标准键盘吧!

[复制链接]

出0入0汤圆

发表于 2007-12-26 00:00:00 | 显示全部楼层 |阅读模式
本来以为模拟PS2协议相当的麻烦,今天下了一本PS2协议手册看了半天,原来读键盘值相当简单嘛,比模拟SPI、I2C简单多了呵呵。

下面介绍一下具体过程

1.明确接线关系,只需接4根线,VCC要+5V,刚刚又测试过,3.3V也可以用。时钟和数据线要用bidir双向口线,FPGA可以不用外接上拉电阻。另外,USB键盘也可以用,只要用一个转接头转成PS2即可。


2.读取基本的键盘数据,不需要FPGA发送任何数据,只需读取键盘发回来的数据即可

如下面的时序图,每次键盘发送11个clock信号,我们需要做的事情就是在时钟的下降沿读取数据




3.如何来采样CLK低电平?

这里可以用一个FIFO来储存数据,如下面的程序,当ps2_clk信号处于下降沿时,ps2_clk_fallingedge值将被置高

reg [2:0] ps2_clkr;//用一个fifo来采样ps2_clk信号;
always @(posedge clk)
ps2_clkr <= {ps2_clkr[1:0], ps2_clk};

wire ps2_clk_risingedge = (ps2_clkr[2:1]==2'b01); // now we can detect ps2_clk rising edges
wire ps2_clk_fallingedge = (ps2_clkr[2:1]==2'b10); // and falling edges

4.当检测到第一个低电平时,我们只需要连续读取11个周期值就可以了,这里用一个变量i来控制

always @(posedge clk)
if(rst)
i <= 0;
else
begin
if(ps2_clk_fallingedge)
begin
data2 <= data;
data <= ps2_data;
if(i<10) i <= i+1;
else i <= 0;
end
end

最后来解释下这11个数据的功能,如下表




5.如果想进一步区分键值,就需要查表了,如下表




基本按键,键盘会发送“F0”+“键码”

扩展按键,则发送“E0”+“F0”+“键码”

大家都来试一下吧,一个下午就能搞定!

附程序,晶振频率降至1MHz,用LED输出键值

//==============================================================

module ps2(clk, rst, ps2_clk, ps2_data, data ,data2);

input clk, rst;
inout ps2_clk, ps2_data;
output [10:0] data;
output [10:0] data2;


reg [3:0] i;
reg [10:0] data;//another fifo
reg [10:0] data2;


reg [2:0] ps2_clkr;//用一个fifo来采样ps2_clk信号;
always @(posedge clk)
ps2_clkr <= {ps2_clkr[1:0], ps2_clk};

wire ps2_clk_risingedge = (ps2_clkr[2:1]==2'b01); // now we can detect ps2_clk rising edges
wire ps2_clk_fallingedge = (ps2_clkr[2:1]==2'b10); // and falling edges


always @(posedge clk)
if(rst)
i <= 0;
else
begin
if(ps2_clk_fallingedge)
begin
data2 <= data;
data <= ps2_data;
if(i<10) i <= i+1;
else i <= 0;
end
end

endmodule

//========================================================
点击此处打开ourdev_193396.JPG(文件大小:562K,只有300K以内的图片才能直接显示)


最后送上PS2协议中英文文档,非常详细

点击此处打开ourdev_193397.pdf(文件大小:667K)

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2007-12-26 00:07:25 | 显示全部楼层
感谢,先收藏了!

出0入0汤圆

发表于 2007-12-26 00:23:57 | 显示全部楼层
谢谢!楼主这方面很牛啊!

出0入0汤圆

发表于 2007-12-26 00:39:41 | 显示全部楼层
不错,看来真不复杂,回头在avr上搞一个

出0入0汤圆

发表于 2007-12-26 03:31:14 | 显示全部楼层
谢谢

出0入0汤圆

发表于 2007-12-26 06:54:21 | 显示全部楼层
好样的,先做个记号,等有用时再看。

出0入0汤圆

发表于 2007-12-26 08:25:03 | 显示全部楼层
PS2键盘我也在用,感觉还是用2个I/O口(最好有一个外中断引脚)简单,实在没有必要劳烦CPLD。添加不了多少代码。另外楼主提到的都是断码信息,我认为最好识别通码信息。这样敲打键盘的感觉会好一些。另外没有用到部分比如扩展键EO开头的,或者E1开头的,以及键盘的检测信息AA等都要处理否则,容易出错,起始位的判别对抑制干扰也很重要,不可忽略。

出0入0汤圆

发表于 2007-12-26 08:27:06 | 显示全部楼层
还有一点要说的就是外中断里面读PS2数据,最好设置FIFO,这样就可以在主程序里面解码。

出0入0汤圆

发表于 2007-12-26 08:39:47 | 显示全部楼层

出0入0汤圆

发表于 2007-12-26 08:41:56 | 显示全部楼层
楼上的,什么是FIFO?

出0入0汤圆

发表于 2007-12-26 08:49:18 | 显示全部楼层
First In, First Out.

出0入0汤圆

 楼主| 发表于 2007-12-26 09:08:00 | 显示全部楼层
最近在学FPGA才做的,以前玩AVR还真没有想过用PS2键盘,心里上以为很难

AVR用中断控制,应该也相当简单

要考虑到纠错,扩展键码,就要处理键值了

出0入0汤圆

发表于 2007-12-26 09:25:15 | 显示全部楼层
做上就知道了,疯狂的按键盘测试,比如shift,Ctrl,Alt,按下不释放,让后按扩展键,总之疯狂按多个按键。我用的ARM7,有时数据会错位,后来我把头尾和校验都加入了,疯狂测试了几天没有发现问题。但是我还是觉得超时也是非常有必要加入的。

出0入0汤圆

 楼主| 发表于 2007-12-26 09:32:22 | 显示全部楼层
恩,这样测试,漏掉一个沿触发,数据就不对拉,要加上校验

出0入8汤圆

发表于 2007-12-26 09:52:06 | 显示全部楼层
我的同【6楼】 appleboy
直接用avr io模拟也很好用

出0入0汤圆

发表于 2007-12-26 10:04:55 | 显示全部楼层
收藏备用

出0入0汤圆

发表于 2007-12-26 10:21:36 | 显示全部楼层
记号

出0入0汤圆

发表于 2007-12-26 10:30:53 | 显示全部楼层
我原来也用CPLD解码PS2键盘,问题多多呢,后来用一片专用的82C42,基本上没问题了

出0入0汤圆

发表于 2007-12-26 13:53:11 | 显示全部楼层
这么费劲?太费劲了,FPGA都用上了。

用BASCOM-AVR,里面直接提供的就有 PS2 键盘和鼠标 的通用软件接口,一个语句就搞定了。

出0入0汤圆

发表于 2007-12-26 14:08:29 | 显示全部楼层

出0入0汤圆

 楼主| 发表于 2007-12-26 16:27:31 | 显示全部楼层
to 18楼

请认清楚学习的本质,不要一味图方便

学习简单的时序是处理复杂问题的基础,难道你拿到FPGA一开始就搞DDR2、MPG解码?

FPGA只是学习的工具,其原理照样可以用在十几元钱的CPLD上

出0入0汤圆

发表于 2007-12-26 17:57:13 | 显示全部楼层
顶一下 。。。。

出0入0汤圆

发表于 2007-12-26 18:03:03 | 显示全部楼层
楼主强人,做个记号先...

出0入0汤圆

发表于 2007-12-30 14:00:52 | 显示全部楼层
呵呵  楼主用的 VERILOG  我也来发一个 VHDL的  献丑老~~~~~
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity key_ps2 is
    Port ( clk : in std_logic;
           res : in std_logic;
           clk_ps : in std_logic;
           date_ps : in std_logic;
           date_out : out std_logic_vector(7 downto 0));
end key_ps2;

architecture Behavioral of key_ps2 is
signal clk_f :std_logic;
signal date_r : std_logic_vector(10 downto 0);
begin
fen: process(clk,res)
variable cnt : integer range 0 to 512;
     begin
          if(res='1') then
                      clk_f<='0';
                                          cnt:=0;
          elsif(clk'event and clk='1') then
                      if(cnt=511) then
                                                 clk_f<='1';
                                          else   
                                                 clk_f<='0';
                                          end if;
                                          cnt:=cnt+1;
          end if;
end process fen;
aa:process(clk_f,clk_ps,date_ps,res)
variable check : std_logic;
variable n : integer range 0 to 12;
variable delay : std_logic_vector(6 downto 0);
variable over :std_logic;
     begin
               if(res='1') then
                              check:='0';
                                        over:='0';
                                        date_r<=(others=>'0');
                              delay:="1100001";
                         elsif(clk_ps'event and clk_ps='0' and delay="0000000") then
                              date_r<=date_ps&date_r(10 downto 1);
                                        n:=n+1;
                                        check:=check xor date_ps;
                                        if(n=11) then
                                                     n:=0;
                                                        over:='1';
                                        else
                                              over:='0';
                                        end if;
                         end if;
                         if(over='1') then
                              if(date_r(0)='0' and date_r(10)='1' and check='0') then
                                                date_out<=date_r(8 downto 1);
                                        end if;
                                        delay:="1100001";
                                        over:='0';
                                        check:='0';
                         end if;                                     
                         if(delay>0) then
                              delay:=delay-1;
                         end if;
end process aa;                                              
end Behavioral;

出0入0汤圆

发表于 2007-12-30 14:08:29 | 显示全部楼层
记号

出0入0汤圆

发表于 2007-12-31 17:26:09 | 显示全部楼层
在AVR上我是这样纠错的:
首先用示波器测量下相邻两个脉冲的时间T0和相邻两个帧的时间T1,使用定时器做一个时间介于T1和T0超时计数器,并且每次发生外部中断后就清零计数器,当计数器超时立即将PS2的时钟脉冲计数器清零.
我用这种方法进行了2天的不断自动测试,没有发生一次错误.将此献给大家.

出0入0汤圆

发表于 2008-1-4 12:57:30 | 显示全部楼层
好帖!收藏了

出0入0汤圆

发表于 2008-1-6 21:20:45 | 显示全部楼层
ps2 还要涉及到通码断码。在单片机上做没有必要吧做得这么麻烦吧

出0入0汤圆

发表于 2008-1-9 00:08:30 | 显示全部楼层
路过,顶了,以后有时间漫漫研究

出0入0汤圆

发表于 2008-1-9 08:07:46 | 显示全部楼层
记号,谢谢。

出0入0汤圆

发表于 2008-1-9 08:10:34 | 显示全部楼层
VHDL语言用UE编辑,怎么关键字不突出啊?大家一般是用什么编辑的啊?

出0入0汤圆

发表于 2008-1-9 16:56:52 | 显示全部楼层
看了一下图发现楼主的AVR板跟我的一模一样!

出0入0汤圆

发表于 2008-3-30 12:21:45 | 显示全部楼层
学习了!

出0入0汤圆

发表于 2008-3-30 12:31:25 | 显示全部楼层
支持

出0入0汤圆

发表于 2008-3-31 17:07:34 | 显示全部楼层
楼主光顾的板子都很熟悉嘛,呵呵

出0入0汤圆

发表于 2008-4-13 00:29:00 | 显示全部楼层
正在学习,可能以后用到

出0入46汤圆

发表于 2008-5-2 14:22:57 | 显示全部楼层
学习!

出0入0汤圆

发表于 2008-5-2 15:39:40 | 显示全部楼层
好资料,顶一个

出0入0汤圆

发表于 2008-5-19 21:35:52 | 显示全部楼层
顶一下,以后会用到的

出0入0汤圆

发表于 2008-5-20 00:12:31 | 显示全部楼层
强悍啊!!先记下来!

出0入0汤圆

发表于 2008-5-20 09:46:11 | 显示全部楼层
收藏,慢慢研究~~

出0入0汤圆

发表于 2008-6-22 13:00:50 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-6-24 15:01:16 | 显示全部楼层
标记!
以前看师兄们玩过,有空也去弄一个玩:)

出0入0汤圆

发表于 2008-6-24 15:03:33 | 显示全部楼层
...

出0入90汤圆

发表于 2008-6-24 16:18:57 | 显示全部楼层
做个记号!

出0入0汤圆

发表于 2008-8-1 16:49:23 | 显示全部楼层
有些鼠标识别不了?是不是电平不兼容的原因??可以同时兼容两种电平的电路图怎么样的?

出0入0汤圆

发表于 2008-8-1 17:16:00 | 显示全部楼层
做个记号

出0入0汤圆

发表于 2008-8-1 18:16:48 | 显示全部楼层
好厉害,学习一下

出70入145汤圆

发表于 2008-8-21 20:48:37 | 显示全部楼层
学习了

出0入0汤圆

发表于 2008-8-22 00:25:09 | 显示全部楼层
学习啦,呵呵

出0入0汤圆

发表于 2008-8-22 08:03:41 | 显示全部楼层
记号

出0入0汤圆

发表于 2008-8-22 08:34:02 | 显示全部楼层
这论坛咋没收藏功能呢。。只好记号一下。。

出0入0汤圆

发表于 2008-8-23 14:52:44 | 显示全部楼层
很好,收藏待试验。

出0入0汤圆

发表于 2008-8-26 23:59:22 | 显示全部楼层
没时间看了,做个记号下次看了。。。。
以前做过键盘的,就是扩展键没搞定~

出0入0汤圆

发表于 2008-8-27 08:55:58 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-8-27 08:58:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-9-4 16:49:25 | 显示全部楼层
很好,有增强信心作用

出0入0汤圆

发表于 2008-11-6 00:08:37 | 显示全部楼层
好,FPGA模拟PS2键盘

出0入0汤圆

发表于 2008-11-7 13:04:15 | 显示全部楼层
我也要一个&nbsp;好东西

出0入0汤圆

发表于 2008-11-23 23:52:23 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-11-24 00:06:29 | 显示全部楼层
收藏备用!

出0入0汤圆

发表于 2008-12-1 10:51:02 | 显示全部楼层
多谢..

出0入0汤圆

发表于 2008-12-7 20:16:55 | 显示全部楼层
记号。

出0入0汤圆

发表于 2008-12-7 21:44:35 | 显示全部楼层
PS/2是好,但也用不着丢掉4X4吧。

各有各的用途。

出0入0汤圆

发表于 2008-12-13 15:50:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-1-5 00:57:28 | 显示全部楼层
好!

出0入0汤圆

发表于 2009-1-7 20:55:30 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-1-19 21:20:46 | 显示全部楼层
看看我写的PS2通信程序....

http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=2167690&bbs_page_no=1&bbs_id=1029

出0入0汤圆

发表于 2009-1-20 01:22:21 | 显示全部楼层
标记

出100入0汤圆

发表于 2009-3-26 09:28:42 | 显示全部楼层
呵呵,极品

出0入0汤圆

发表于 2009-3-26 10:00:50 | 显示全部楼层
不错,记一个

出0入0汤圆

发表于 2009-3-26 10:36:53 | 显示全部楼层
ok,记号。

出0入0汤圆

发表于 2009-3-26 15:02:08 | 显示全部楼层
嘿嘿,真的是个学习的好素材

出0入0汤圆

发表于 2009-3-26 23:45:44 | 显示全部楼层
好东西,收藏

出0入0汤圆

发表于 2009-3-29 22:12:13 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-4-3 13:35:17 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-4-4 19:02:42 | 显示全部楼层
收藏

出0入0汤圆

发表于 2009-4-4 19:49:15 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-4-5 02:26:54 | 显示全部楼层
好东西,不过从实用的角度来说没啥用,楼主再接再劢加油啊,做点更猛烈的东西出来

出0入0汤圆

发表于 2009-4-10 09:39:27 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-4-10 10:39:32 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-4-15 15:01:03 | 显示全部楼层
mark

出0入70汤圆

发表于 2009-4-26 20:04:08 | 显示全部楼层
顶顶

出0入0汤圆

发表于 2009-4-27 09:55:55 | 显示全部楼层
记号,感谢楼主的分享

出0入0汤圆

发表于 2009-8-13 19:24:59 | 显示全部楼层
好东西

出0入0汤圆

发表于 2009-8-26 00:51:23 | 显示全部楼层
mark thanks

出0入0汤圆

发表于 2009-8-26 08:56:02 | 显示全部楼层
我顶~

出0入0汤圆

发表于 2009-8-29 10:53:47 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-8-29 12:37:44 | 显示全部楼层
顶之

出0入0汤圆

发表于 2009-9-15 10:36:20 | 显示全部楼层
Good!Mark....

出0入0汤圆

发表于 2009-9-22 23:37:44 | 显示全部楼层
看看..

出0入0汤圆

发表于 2009-9-23 07:39:19 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-9-23 08:27:03 | 显示全部楼层
.

出0入0汤圆

发表于 2009-9-23 10:46:55 | 显示全部楼层
加盖一楼!

出0入0汤圆

发表于 2009-9-23 11:29:31 | 显示全部楼层
楼主或其他各位大大,问个问题,我怎么知道我现在用的鼠标或键盘是5V的还是3.3V的?

出0入0汤圆

发表于 2009-9-23 11:41:01 | 显示全部楼层
幻想要是有中国人能用FPGA模拟个X86通用CPU出来就好了

出0入0汤圆

发表于 2009-9-23 11:44:22 | 显示全部楼层
Mark!

出0入0汤圆

发表于 2009-10-6 23:44:35 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-10-14 09:45:54 | 显示全部楼层
马克一下。

出0入0汤圆

发表于 2009-10-24 18:21:10 | 显示全部楼层
好贴
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 05:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表