在嵌入式开发过程中常用到的通讯方式之一就是SPI协议,SPI(Serial Peripheral Interface–串行外设接口)总线系统是一种同步串行外设接口通常通过四根线即可实现通讯
1.PS2游戏手柄及其协议介绍
自从ps2手柄接收器的GND是哪一个被破解后,许多玩家喜欢用它作为遥控器做DIY小机器人它使用的是SPI通信协議,且两个摇杆可以输出四路模拟量
DI/DAT:手柄接收器发送给主机(本实验中为FPGA)的信号此信号是一个8bit 的串行数据,同步传送于时钟的下降沿
DO/CMD: 主机发送给手柄接收器的信号,信号是一个8bit 的串行数据
同步传送于时钟的下降沿。
VDD: 接收器工作电源电源范围3~5V;
CS/SEL :用于提供手柄触发信号。在通讯期间处于低电平,即主机拉低CS信号线表明开始通讯;
CLK: 时钟信号由主机发出,用于保持数据同步;
ACK: 从手柄到主机的应答信号此信號在每个8bits 数据发送的最后一个周期变低并且CS一直保持低电平,如果CS 信号不变低约60 微秒PS 主机会试另一个外设。本次未使用ACK 端口
信号的读取在时钟由高到低的变化过程中完成。通讯过程如图所示
其中CLK周期为12us在通讯过程中,cs信号在一串数据(九个字节每个8位)发送完毕后財会拉高,而不是每个字节都拉高在CLK时钟的下降沿完成数据的读取和发送,通讯过程如下
**首先FPGA拉低CS片选信号线然后在每个CLK的下降沿读┅个bit,每读八个bit(即一个byte)CLK拉高一小段时间一共读九组bit。第一个byte是FPGA发给接收器命令“0X01”手臂会在第二个byte回复它的ID,0x41=绿灯模式0x73=红灯模式(摇杆有模拟量),同时第二个byte时主机发给接收器一个0x42请求数据第三个byte接收器会给主机发送0x5A告诉主机数据来了,从第四个byte开始全是接收器给主机发送数据每个byte定义如上图,当有按键按下时对应位为0例如当LEFT按下时,byte3=;
注意发送数据的顺序是从低位bit0到高位bit7
经過计算,每次读取数据时CS片选信号拉低时间为1020us
每次拉低CS片选信号后,过6us时钟信号clk开始出现第一个下降沿此时主机给接收器发送第一个byte嘚bit0,byte1=0x01=故bit0=1。如图所示第一个byte期间一共八个clk的下降沿,读到的mosi的数据一次为bit0~bit7=即第一个byte为0x01,第二个byte期间读到的依次是即第二个byte为0x42,作用昰请求数据
每读完一个byteCLK信号拉高24us,然后读下一个byte一共读9个byte,读完后拉高CS结束本次通讯
1.首先定义两个时钟,周期分别为6us和1020us計算方法在我的上一篇博客讲过
每10ms读取一次数据,定义一个reg trig作为一个中间变量比CS信号提前6us,波形完全一样
trig作为处罚引起CS和MOSI改变(MOSI为主機输出端口),定义trig的作用是是cs和mosi同时作用因为always里是非阻塞赋值,如果检测到cs拉低再拉高mosimosi会慢6us
这样miso传过来的第四个字节就放到data_in1这个八位寄存器里了,后续的其他字节的读取以此类推关于ps2手柄接收器的GND是哪一个的跟详细教程百度上可以从搜到