花了好几天时间学习PS2键盘IP核,看PS2协议,看别人写的代码,由于基础不是很好,所以中间犯了低级错误而不知道,只是不停的在编译下载,一次又一次的调试,第一次的时候,没有任何反应,然后检查代码,该各种参数,就是没有想到reset数据会有问题,
Always @(posedge clk or posedge reset)//我想要复位信号高有效。结果调试了大半天,原来这样是行不通的。还有各种小错误,都是敲代码的时候不注意,也没有仔细检查,然后就直接编译运行,结果肯定出不来正确结果,所以以后写代码的时候千万要仔细,写完代码也不要急着编译下载,先检查代码的正确性,确认无误了再编译下载,这样会大大的提高效率。
好了,废话不多说,说怎么写吧。PS2键盘驱动是比较简单的,当然(不考虑从主机向键盘发命令),只是考虑从键盘中发送数据给PC(主机),然后主机能够及时接收数据,这样就可以了。
上图所示是PS2端口的数据线定义,PS2_DATA是串行数据线,PS2_CLK是时钟信号,min = 60us,max = 100us,
下图所示为读取数据时序图,可以看出跟串行通讯很像,有个起始位,然后是8个数据位,1个奇偶校验位,一个停止位,在下降沿时读取,那么我们所做的东西就很少了,只需要找出它的下降沿,然后读取11个数据就可以了,然后将数据存储起来,比较其扫描码,然后进行转换,最终输出ASCII值。
下降沿有效信号,我是通过最普通的方法来实现的,即利用两级D寄存器,然后就可以求其下降沿。具体代码如下:
数据读写也非常简单,定义8位的缓冲器,然后按序将数据存储在缓冲区中就可以了,具体实现如下:
以下代码类似,只是在case10的时候需要,将计数器清零。那么怎么检测什么时候按键弹起呢?当弹起时,PS2键盘会向主机发送0XF0的数据,如果接收到该数据,说明了按键被弹起了,那么此时需要released信号为高,信号不会写入ascii端口。具体如下
红线所示为关键部分,当released信号为高,rx_output_strobe信号为低,rx_ascii值不变仍然为上次按键按下时的值。