FPGA开发之解析SONY-PS2手柄SPI协议

在嵌入式开发过程中,常用到的通讯方式之一就是SPI协议,SPI(Serial Peripheral Interface–串行外设接口)总线系统是一种同步串行外设接口,通常通过四根线即可实现通讯

  • 使用对象:PS2游戏手柄
  • 使用环境:ISE14.7和BASYS2开发板

1.PS2游戏手柄及其协议介绍

自从PS2手柄被破解后,许多玩家喜欢用它作为遥控器做DIY小机器人,它使用的是SPI通信协议,且两个摇杆可以输出四路模拟量

接收器的接口定义为:

DI/DAT:手柄接收器发送给主机(本实验中为FPGA)的信号,此信号是一个8bit 的串行数据,同步传送于时钟的下降沿。
DO/CMD: 主机发送给手柄接收器的信号,信号是一个8bit 的串行数据,
同步传送于时钟的下降沿。
NC:空端口;
GND:电源地;
VDD: 接收器工作电源,电源范围3~5V;
CS/SEL :用于提供手柄触发信号。在通讯期间,处于低电平,即主机拉低CS信号线表明开始通讯;
CLK: 时钟信号,由主机发出,用于保持数据同步;
NC: 空端口;
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=01111111;
注意,发送数据的顺序是从低位bit0到高位bit7

2.SPI通讯波形

经过计算,每次读取数据时,CS片选信号拉低时间为1020us

每次拉低CS片选信号后,过6us时钟信号clk开始出现第一个下降沿,此时主机给接收器发送第一个byte的bit0,byte1=0x01=00000001,故bit0=1。如图所示,第一个byte期间一共八个clk的下降沿,读到的mosi的数据一次为bit0~bit7=10000000,即第一个byte为0x01,第二个byte期间读到的依次是01000010,即第二个byte为0x42,作用是请求数据

每读完一个byte,CLK信号拉高24us,然后读下一个byte,一共读9个byte,读完后拉高CS,结束本次通讯

Verilog代码实现

1.首先定义两个时钟,周期分别为6us和1020us,计算方法在我的上一篇博客讲过

always @(posedge clk)   //定义两个时钟,周期分别为6us和1020us
beginif(cnt_clk_6us == 10'b00_1001_0110-1) begincnt_clk_6us <= 0;clk_6us <= ~clk_6us;   //按位取反endelsecnt_clk_6us <= cnt_clk_6us + 1;if(cnt_1020us == 16'b0110_0011_1001_1100-1) begin    //  110 0011 1001 1100  周期1020uscnt_1020us <= 0;clk_1020us <= ~clk_1020us;   //按位取反endelsecnt_1020us <= cnt_1020us + 1;
end

每10ms读取一次数据,定义一个reg trig作为一个中间变量,比CS信号提前6us,波形完全一样

always @( posedge clk_1020us)
begin
count_for_trig<=count_for_trig+1;if (count_for_trig==4'b0001)   trig<=0;else if (count_for_trig==4'b0010)   //trig拉低1020ustrig<=1;else    if (count_for_trig==4'b1010)count_for_trig<=4'b0000;
end

trig作为处罚,引起CS和MOSI改变(MOSI为主机输出端口),定义trig的作用是是cs和mosi同时作用,因为always里是非阻塞赋值,如果检测到cs拉低再拉高mosi,mosi会慢6us

reg [7:0] data_in1;
reg [7:0] count_trig=0;
always @(negedge clk_6us)
beginif (trig==0)   beginscs<=0;    count_trig<=count_trig+1;//////////spi_clk波形产生////////////if ((0<count_trig)&(count_trig<17))   //byte1sclk<=~sclk;else if ((19<count_trig)&(count_trig<36))  //byte2sclk<=~sclk;else if ((38<count_trig)&(count_trig<55))  //byte3sclk<=~sclk;else if ((57<count_trig)&(count_trig<74))  //byte4sclk<=~sclk;else if ((76<count_trig)&(count_trig<93))  //byte5sclk<=~sclk;else if ((95<count_trig)&(count_trig<112))  //byte6sclk<=~sclk;else if ((114<count_trig)&(count_trig<131))  //byte7sclk<=~sclk;else if ((133<count_trig)&(count_trig<150))  //byte8sclk<=~sclk;else if ((152<count_trig)&(count_trig<169))  //byte9sclk<=~sclk;///////////////////mosi波形产生/////////////////////通过波形图可以看出莫斯一共拉高了三次,每次持续12us,因为只需要发送一个0x01和0x42if (count_trig<2)smosi<=1;else if ((20<count_trig)&(count_trig<23))smosi<=1;else if ((30<count_trig)&(count_trig<33))smosi<=1;else smosi<=0;//////////////读取miso////////////////////if (count_trig==58)    //读byte4data_in1[0]<=spi_miso;else if (count_trig==60)data_in1[1]<=spi_miso;else if (count_trig==62)data_in1[2]<=spi_miso;else if (count_trig==64)data_in1[3]<=spi_miso;else if (count_trig==66)data_in1[4]<=spi_miso;else if (count_trig==68)data_in1[5]<=spi_miso;else if (count_trig==70)data_in1[6]<=spi_miso;else if (count_trig==72)data_in1[7]<=spi_miso;  endelse if(trig==1)   //不通讯时(即trig=1时)cs信号拉高,clk信号拉高beginscs<=1;sclk<=1;count_trig<=0;end
end

这样miso传过来的第四个字节就放到data_in1这个八位寄存器里了,后续的其他字节的读取以此类推,关于PS2手柄的跟详细教程百度上可以从搜到

FPGA 解析PS2游戏手柄相关推荐

  1. 基于STM32的PS2游戏手柄智能小车

    我们小时候在家经常使用PS2游戏手柄打游戏,后来学习了单片机也想做一个智能的遥控坦克.之前做的智能车基本上他的流畅度不好,所以感觉用起来不是很满意,于是在做毕业设计的时候就购买了这样一个坦克模型和PS ...

  2. 半定制器件课程设计——基于FPGA的PS2键盘人机输入显示系统

    基于FPGA的PS2键盘人机输入显示系统 第一部分 课程设计概述 1 课程设计的目的与任务 2 课程设计题目 3 设计功能要求 4 设计实现提示 5 课程设计的内容与要求 5.1 设计内容 5.2 设 ...

  3. FPGA模拟PS2接口的方法

    FPGA模拟PS2接口的方法 本来以为模拟PS2协议相当的麻烦,今天下了一本PS2协议手册看了半天,原来读键盘值相当简单嘛,比模拟SPI.I2C简单多了呵呵. 下面介绍一下具体过程 1.明确接线关系, ...

  4. FPGA解析串口协议帧3.0版本,增加了错误重发功能,提供仿真文件以及源码

    FPGA解析串口协议帧已经发布2个版本了,分别如下: 版本1:点击查看版本1 版本1详细介绍了串口协议帧的帧组成和设计思想,但设计粗糙,注释不详细: 版本1:点击查看版本2 版本2优化了代码,添加了详 ...

  5. 源码系列:基于FPGA的PS2通信电路设计(附源码)

    今天给大侠带来基于FPGA的PS2通信电路设计,附源码,获取源码,请在"FPGA技术江湖"公众号内回复"PS2源码",可获取源码文件.话不多说,上货. 设计背景 ...

  6. 【树莓派C语言开发】实验14:PS2游戏手柄模块(关联PCF8591)

    本次实验还是需要用到PCF8591模数转换器,莫非它要取代双色LED成为新的常驻嘉宾吗? 本次实验是摇杆实验.这个玩意可以用于操控机器人或者是树莓派的遥控小车.当然,生活中最常见的用途还是在游戏手柄上 ...

  7. FPGA解析B码----连载7(完结篇)

    前言 上篇完结篇介绍了程序的整体架构和B码错误保护程序,这篇主要介绍下1PPS的产生. 写到这里想先聊聊现在的软件,用的是QII,不知道这个软件还能免费用多久.现在国外的软件慢慢的都不能用了,只能用国 ...

  8. FPGA解析B码----连载8(完结篇)

    前言 前两个完结篇介绍了B码的结构,B码保护程序和B码的1PPS产生程序,下面介绍B码的UTC时间产生.当然B码中含有UTC时间和UTC时间的关键信息.程序的整体思路是差不多的,翻过来调过去也就是那点 ...

  9. 智宇科技 ZYARJX-1机械臂智能小车 —— PS2游戏手柄控制程序

    头文件 #ifndef PS2X_lib_h#define PS2X_lib_h#if ARDUINO > 22#include "Arduino.h" #else#incl ...

最新文章

  1. jquery二维码生成插件jquery.qrcode.js
  2. Determine destination location of apt-get install package?
  3. 一步一步学习Ultimus - 三、系统设置
  4. easyUI的combobox选中无法显示
  5. 为什么HashMap要树化呢?
  6. SAP Spartacus B2B 页面 info icon 设计 - 版本1.0
  7. 月老办事处月云开发微信小程序源码
  8. struts 通配符的使用
  9. javascript实现silverlight pivotViewer控件
  10. Comet:基于HTTP长连接的“服务器推”技术
  11. windows下编辑的shell复制到linux无法执行
  12. 2021新版OPEN易支付免费开源版 亲测可用
  13. 使用POI操作Ecxel文档遇到转化成String类型的电话号码无法转化成Cell类型了
  14. 共享资源计算机的用户名和密码,电脑共享文件为什么提示要用户名密码?
  15. 【数值预报】按时间维度合并/重新生成nc、grib网格数据(按天、小时组织的文件合并成按月组织文件)
  16. 2023第5届中国(济南)国际福祉及残疾人用品展览会开启招商
  17. 科普“知识共享”严重缺失,国内亟待补课
  18. 微信视频号标题怎么写吸引眼球
  19. 【Delphi】中使用消息Messages(五)Windows消息
  20. Android Material Design 之 CardView卡片式布局

热门文章

  1. 中国移动和中国广电共用700MHz,联通和电信的5G输定了
  2. 孔维滢《面向对象程序设计(java)》课程学习总结
  3. 【愚公系列】2022年02月 wireshark系列-数据抓包分析之DNS协议
  4. pandas 函数说明
  5. 一行字还要占用一页纸?教你缩减Word页面节省打印纸
  6. 机器学习从入门到创业手记-2.1.4 分类决策树与去还是不去
  7. git 裁切_git 命令
  8. 【AWS系列】第七讲: AWS Serverless之API Gateway
  9. wow魔兽版 中国队VS乌兹别克
  10. 动手学深度学习--课堂笔记图片分类数据集