ID:
网址:lihaiqun86.taobao.com
PS2 解码通讯使用手册 V1.5
ID:
网址:lihaiqun86.taobao.com
I
ID:
网址:lihaiqun86.taobao.com
目 录
1 PS2 手柄介绍. ............................................................................................................................. 1
2 手柄的使用、连接配对说明. .....................................................................................................2
3 硬件连接方式. .............................................................................................................................3
4 程序设计. .....................................................................................................................................3
5 下载与测试.................................................................................................................................10
附录 A:更新说明...........................................................................................................................14
附录 B:联系方式. ......................................................................................................................... 15
1
ID:
网址:lihaiqun86.taobao.com
PS2 解码通讯
ps2 手柄是索尼的 PlayStation2 游戏机的遥控手柄。索尼的 psx 系列游戏主机在全球很
是畅销。不知什么时候便有人打起 ps2 手柄的主意,破解了通讯协议,使得手柄可以接在其
他器件上遥控使用,比如遥控我们熟悉的机器人。突出的特点是这款手柄性价比极高,按键
丰富,方便扩展到其它应用中。
1 PS2 手柄介绍
ps2 手柄由手柄与接收器两部分组成,手柄主要负责发送按键信息;接收器与单片机(也
可叫作主机,可直接用在 PS2 游戏机上)相连,用于接收手柄发来的信息,并传递给单片
机,单片机也可通过接收器,向手柄发送命令,配置手柄的发送模式。
特别声明:因批次不同或代工厂家不同,手柄和接收器的外观会有所区别(接收器上都
有指示灯,但一种接收器上有电源灯,另一种没有电源灯),但是接收器的引脚定义是一样
的,解码方式是一样的,使用相同。
接收器引脚输出:
1
2
DI/DAT DO/CMD
3
NC
4
5
6
7
GND
VDD
CS/SEL
CLK
8
NC
9
ACK
接收器图片(一定要注意端口顺序):
图 1.1 接收器引脚序号
DI/DAT:信号流向,从手柄到主机,此信号是一个 8bit 的串行数据,同步传送于时钟
的下降沿。信号的读取在时钟由高到低的变化过程中完成。
DO/CMD:信号流向,从主机到手柄,此信号和 DI 相对,信号是一个 8bit 的串行数据,
同步传送于时钟的下降沿。
NC:空端口;
GND:电源地;
VDD:接收器工作电源,电源范围 3~5V;
CS/SEL:用于提供手柄触发信号。在通讯期间,处于低电平;
CLK:时钟信号,由主机发出,用于保持数据同步;
NC:空端口;
ACK:从手柄到主机的应答信号。此信号在每个 8bits 数据发送的最后一个周期变低并
且 CS 一直保持低电平,如果 CS 信号不变低,约 60 微秒 PS 主机会试另一个外设。在编程
时未使用 ACK 端口。
第 1页 共 15 页
ID:
网址:lihaiqun86.taobao.com
PS2 解码通讯
图 1.3 通讯时序
时钟频率 250KHz(4us),如果接收数据不稳定,可以适当的增加频率。在通讯过程中,
一串数据通讯完成后 CS 才会由低转高,不是 1 个字节通讯完成后就由低转高,在通讯期间,
一直处于低电平。
在时钟下降沿时,完成数据(1bit)的发送与接收,发送和接收是同时完成的。当单片
机想读手柄数据或向手柄发送命令时,将会拉低 CS 线电平,并发出一个命令“0x01”;手
柄会回复它的 ID“0x41=绿灯模式,0x73=红灯模式”;在手柄发送 ID 的同时,单片机将传
送 0x42,请求数据;随后手柄发送出 0x5A,告诉单片机“数据来了”。
idle:数据线空闲,该数据线无数据传送。
一个通讯周期有 9 个字节(8 位),这些数据是依次按位传送。
顺序
表 1:数据意义对照表
DO
0X01
0x42
idle
WW
YY
idle
idle
idle
idle
DI
idle
ID
0x5A
data
data
data
data
data
data
Bit0、Bit1、Bit2、Bit3、Bit4、Bit5、Bit6、Bit7、
SELECT、L3、R3、START、UP、RIGHT、DOWN、LEFT
0
1
2
3
4
5
6
7
8
当有按键按下,对应位为“0”,其他位为“1”,例如当键“SELECT”被按下时,
L2、R2、L1、R1、△、○、╳、□
PSS_RX(0x00=left、0xFF=right)
PSS_RY(0x00=up、0xFF=down)
PSS_LX(0x00=left、0xFF=right)
PSS_LY(0x00=up、0xFF=down)
Data[3]=11111110B。
在设置了震动模式后,我们就能发送 WW、YY 来控制震动电机。WW,用来控制右侧
的小震动电机,0x00 关,其他值为开;YY 用来控制左侧的大震动电机,0x40~0xFF 电机开,
值越大,电机转动越快,震动越明显。具体的设置请看下面的程序部分。
红灯模式时:左右摇杆发送模拟值,0x00~0xFF 之间,且摇杆按下的键值 L3、R3 有效;
绿灯模式时:左右摇杆模拟值为无效,推到极限时,对应发送 UP、RIGHT、DOWN、
LEFT、△、○、╳、□,按键 L3、R3 无效。
2 手柄的使用、连接配对说明
手柄需要两节 7 号 1.5V 的电池供电,接收器和单片机共用一个电源,电源范围为 3~5V,
第 2页 共 15 页
ID:
网址:lihaiqun86.taobao.com
PS2 解码通讯
不能接反,不能超压,过压和反接,都会使接收器烧坏。
手柄上有个电源开关,ON 开/OFF 关,将手柄开关打到 ON 上,在未搜索到接收器的状
况下,手柄的灯会不停的闪,在一定时间内,还未搜索到接收器,手柄将进入待机模式,手
柄的灯将灭掉,这时,只有通过“START”键,唤醒手柄。
接收器供电,在未配对的情况下,绿灯闪。
手柄打开,接收器供电,手柄和接收器会自动配对,这时灯常亮,手柄配对成功。按键
“MODE”(手柄批次不同,上面的标识有可能是“ANALOG”,但使用方法一样),可
以选择“红灯模式”,“绿灯模式”。
有些用户反映,手柄和接收器不能正常配对!多数问题是,接收器的接线不正确,或程
序有问题。
解决方法:接收器只接电源(电源线一定要连接正确),不接任何数据线和时钟线,一
般情况下手柄是能够配对成功。配对成功后灯常亮,说明手柄是好的,这时再检查接线是否
正确,程序移植是否有问题。
3 硬件连接方式
接收器与 stm32 连接方式
DI->PB12;
DO->PB13;
CS->PB14;
CLK->PB15。
4 程序设计
完整程序详见工程文件。
这里主要介绍 pstwo.c 文件中的函数。
void PS2_Init(void)
{
//使能 PORTB 时钟
//输入 DI->PB12
RCC->APB2ENR|=1<<3;
GPIOB->CRH&=0XFFF0FFFF;//PB12 设置成输入 默认下拉
GPIOB->CRH|=0X00080000;
// DO->PB13
RCC->APB2ENR|=1<<3;
GPIOB->CRH&=0X000FFFFF;
GPIOB->CRH|=0X33300000;
CS->PB14 CLK->PB15
//使能 PORTB 时钟
//PB13、PB14、PB15 推挽输出
}
端口初始化,PB12 为输入,PB13、PB14、PB15 为输出。
//向手柄发送命令
void PS2_Cmd(u8 CMD)
{
第 3页 共 15 页
ID:
网址:lihaiqun86.taobao.com
PS2 解码通讯
volatile u16 ref=0x01;
Data[1] = 0;
for(ref=0x01;ref<0x0100;ref<<=1)
{
if(ref&CMD)
{
DO_H;
}
else DO_L;
CLK_H;
delay_us(10);
CLK_L;
delay_us(10);
CLK_H;
if(DI)
//输出一位控制位
//时钟拉高
Data[1] = ref|Data[1];
}
delay_us(16);
}
//判断是否为红灯模式,0x41=模拟绿灯,0x73=模拟红灯
//返回值;0,红灯模式
//
u8 PS2_RedLight(void)
{
其他,其他模式
CS_L;
PS2_Cmd(Comd[0]);
PS2_Cmd(Comd[1]);
CS_H;
if( Data[1] == 0X73)
else return 1;
//开始命令
//请求数据
return 0;
}
//读取手柄数据
void PS2_ReadData(void)
{
volatile u8 byte=0;
volatile u16 ref=0x01;
CS_L;
PS2_Cmd(Comd[0]);
//开始命令
第 4页 共 15 页
PS2 解码通讯
ID:
网址:lihaiqun86.taobao.com
//请求数据
PS2_Cmd(Comd[1]);
for(byte=2;byte<9;byte++)
{
for(ref=0x01;ref<0x100;ref<<=1)
{
//开始接受数据
CLK_H;
delay_us(10);
CLK_L;
delay_us(10);
CLK_H;
if(DI)
Data[byte] = ref|Data[byte];
}
delay_us(16);
}
CS_H;
}
上面两个函数分别为主机向手柄发送数据、手柄向主机发送数据。手柄向主机发送的数
据缓存在数组 Data[ ]中,数组中共有 9 个元素,每个元素的意义请见表 1。还有一个函数是
用来判断手柄的发送模式,也就是判断 ID 即 Data[1]的值。
//对读出来的 PS2 的数据进行处理,只处理按键部分
//按下为 0, 未按下为 1
u8 PS2_DataKey()
{
u8 index;
PS2_ClearData();
PS2_ReadData();
Handkey=(Data[4]<<8)|Data[3];
for(index=0;index<16;index++)
{
//这是 16 个按键 按下为 0, 未按下为 1
if((Handkey&(1<<(MASK[index]-1)))==0)
return index+1;
}
return 0;
//没有任何按键按下
}
//得到一个摇杆的模拟量 范围 0~256
u8 PS2_AnologData(u8 button)
{
第 5页 共 15 页