本人对电脑游戏不太感兴趣,唯独偶尔玩几下小霸王游戏,个人认为还是小霸王游戏比较休闲一点儿,于是早就想改造个手柄,用手柄玩才有感觉嘛,在网上搜了一圈,看有没有有同样想法的,于是乎就搜到了这里的一个帖子“[电脑]如果用普通小霸王游戏手柄改造成串口或者USB 电脑用手柄?”,但是回帖子的大多说不可能啊什么的,这就更坚定了我要DIY的信心。 如下为具体制作过程:1. 设计按键扫描因为要考虑允许多个按键同时被按下。最后采用如下图所示连接方法。串口部分用USB-TTL模块连接,USB-TTL:GND RXD TXD VCC单片机 :GND TXD RXD VCC
P1口 组成2x6键盘扫描 接手柄1P2口 组成2x6键盘扫描 接手柄2 本来是想设计成普通手柄无需改造直接可以接上使用的,但找了好久都没有找到手柄接口定义,及数据传输协议,无奈之下,只能这么设计了。
理论上讲,12个按键,如果算上可以有多个按键按下的话,12个按键共有2^12种状态,而P1口的8个数据线最多就只能有2^8种状态,所有,如果在不给手柄接外围器件的话,无法实现识别所有按键状态。
手柄共有12个按键(世嘉手柄 ),没错这个看上去只有11个按键(其实后边还有一个),当时在淘宝买的时候挑了好久,才挑到那种中间有两个按键的,没想到淘宝老板想啥来着发错了,嫌麻烦就没换。
现在有8位数据线,这种按键布局,正好2x6=12,可能有人会问,为什么不用4x4,可以接16个按键,但是这样的话,在增加了按键数量的同时,有增加了程序的复杂度,为了添加自己用不到的几个按键而增加其编程复杂度,不划算啊,再者说, 4x4可能无法完成我们想要的功能,因为要考虑手柄是可以同时按下多个按键的,4x4是单键扫描矩阵,它是无法识别多个按键同时按下的,当然2x6也不是所有的情况都能判断(当同一行的两个按键被同时按下时,会造成其它按键判断有误),考虑到同一行的两个按键同时按下时无法识别的情况(应该存在一种数据分析算法,可以最大程度的对按键情况进行识别),鉴于这种情况的存在,设计按键布局时,最好将不太可能被同时按下的两个按键放在同一行,比如将上、下两个按键放在同一行,将左、右两个按键放在同一行。
这样的话大多数情况是可以识别的。
手柄改造:
将手柄卸开,断开所有与“鸡屎”的连线(既然决定不用它,就要彻底不用它,也不能让它干扰了数据),按照电路设计重新连接按键。
红色序号为一列,紫色序号为一列,序号为该按键所在行
下图为改造好的手柄(图片质量不行,这还是借别人手机照的呢)
由于不知道接口协议,所以对于只有5根线的小霸王手柄来说,扫描它的10个按键的问题还没有解决,谁知道小霸王手柄接口引脚定义及数据传输协议的话,麻烦跟我说一声。
按键的扫描原理:1. 向P1口输出0x7F(0111 1111),用来扫描第一列,如果有哪个按键按下了,相应的数据线就会变为低电平,从P1口读取数据(防抖动处理后的数据),如果这次的数据与上次保存的数据不同的话说明按键状态发生了变化,将新数据通过串口发送出去,保存这次的数据,用于下次比较。
2. 向P1口输出0xBF(1011 1111) 其它操作基本一致。
如下为焊接的实物,单片机用的是PLCC-44封装的STC89C52,单片机与PC通信采用PL2303芯片USB-TTL模块。
手柄接口与RS232接口一致,用RS232公头作为插座,将插头焊在电路板上后俯视焊点2 4 3 8 7
6 9 1 5
下面是做好的成品
PC端软件,用Qt开发,用来接收单片机传来的数据,数据解析后根据设置的按键映射,将按键发送到游戏模拟器。
PC端软件收到数据后:1. 当数据的高两位为01时,该字节数据表示的是第一列按键的状态,然后逐位判断是哪个按键按下,判断是按下还是抬起,根据映射表找到其所对应的键盘按键,发送到游戏窗口。2. 当数据的高两位为10时,该字节数据表示的是第二列按键的状态。3. 当数据的高两位为00或11时,暂定为无效数据,将其丢弃,日后添加对手柄2的支持时,可作为手柄2数据的识别位,即将00当做手柄2的第一列,11当做手柄2的第二列。 如果要把手柄2也实现了的话,把手柄2连接到P2口,单片机程序与手柄1扫描基本一致,但须做一些转码,用来与手柄1发送的数据区分开。 PC端软件如下:
在游戏模拟器中设置好按键
由于是一边设计一边编写、修改代码,所以难免导致其中有冗余代码、Bug之类。经本人测试多日,用着挺爽的。第一次发帖子,没经验,莫笑 1. 单片机程序代码(C语言编写)2. PC端程序代码(C++,Qt库编写)3. 电路仿真(Proteus仿真)4. 全部资料