免责及权益声明:
1、本游戏手柄制作教程所涉及的部分软件和图片来源于互联网,如若侵犯了您的合法权益请告知,我会在得到消息后的24小时内删除。
2、由于制作不当或其它原因造成的硬件损坏本人不付任何责任。
3、本帖所涉及的软件和硬件技术未经授权不得用于商业或其他盈利用途。
4、您可以任意转载本贴,但请注明出处。
2009-11-9更新
这些天都在研究M8的串口手柄,因为有人说蓝牙模块比较昂贵(淘宝45元左右,不算邮费),而且很费电,制作起来又比较费力。记得小勃MM说M8是带有串口的,串口线在USB接口排针的另一侧,于是就盘算着做一个串口手柄,像USB手柄一样插M8屁股上,这样的话成本会低很多,而且没有延迟。
查阅了很多相关资料,自己做了一跟简易串口线。材料很简单,几根铜丝、一片薄塑料片、热熔胶若干。用烙铁把铜丝整齐地烫到塑料片的表面,用热熔胶固定,然后焊上导线即可。做好以后连到电脑上,用串口调试助手一根一根地测试,终于摸清了串口的定义和波特率。
M8底部的串口貌似是一个调试串口,从按下电源键开始就源源不断地以字符的方式输出调试信息,以下是按下电源键以后,输出的调试信息很少的一部分:
复制内容到剪贴板
代码:
++ ONBL2 : main ++
++ ONBL2 : main : BML_Init ok++
[ONLD : MSG] nDev = 00
[ONLD : MSG] nMID = 0x00ec
[ONLD : MSG] nDID = 0x0040
[ONLD : MSG] nVID = 0x0121
[ONLD:MSG] nNumOfBlks = 2048
[ONLD:MSG] nNumOfPlanes = 1
[ONLD:MSG] nBlksInRsv = 40
[ONLD:MSG] nBadPos = 0
[ONLD:MSG] nLsnPos = 2
[ONLD:MSG] nECCPos = 8
[ONLD:MSG] nBWidth = 1
[ONLD:MSG] nMEFlag = 1
[ONLD:MSG] nLKFlag = 0
[BBM: ] << DevNO:0 MAPPING INFORMATION >>
[BBM: ] Bad Mark Information
[BBM: ] - Bad Mark (0x22) by write error
[BBM: ] - Bad Mark (0x11) by erase error
[BBM: ] pstDev->n1stSbnOfULArea = 0
[BBM: ] << Total : 0 BAD-MAPPING INFORMATION >>
++ ONBL2 : main : BML_Open ok++
Press [SPACE] to enter EBOOT within 2 sec.
++ Shadow Eboot ++
_ReadImage, nStartVsn=256, nNumOfScts=1024, nSrcAddr=80030000
-- Shadow Eboot --
LaunchAddr=0x80030000 PhysicalJump=0x50030000
Microsoft Windows CE Bootloader Common Library Version 1.4 Built Mar 21 2009 11:06:07
Microsoft Windows CE Bootloader for the Samsung SMDK641
0 Version 2.4 Built Mar 21 2009
[EBOOT: IN] ++PocketStoreInitialize()
[EBOOT: ] BML_Init success
[EBOOT: IN] ++_SetXSRPI POCKETSTORE15
[ONLD : MSG] nDev = 00
[ONLD : MSG] nMID = 0x00ec
[ONLD : MSG] nDID = 0x0040
[ONLD : MSG] nVID = 0x0121
[ONLD:MSG] nNumOfBlks = 2048
[ONLD:MSG] nNumOfPlanes = 1
[ONLD:MSG] nBlksInRsv = 40
[ONLD:MSG] nBadPos = 0
[ONLD:MSG] nLsnPos = 2
[ONLD:MSG] nECCPos = 8
[ONLD:MSG] nBWidth = 1
[ONLD:MSG] nMEFlag = 1
[ONLD:MSG] nLKFlag = 0
[BBM: ] << DevNO:0 MAPPING INFORMATION >>
[BBM: ] Bad Mark Information
[BBM: ] - Bad Mark (0x22) by write error
[BBM: ] - Bad Mark (0x11) by erase error
[BBM: ] pstDev->n1stSbnOfULArea = 0
[BBM: ] << Total : 0 BAD-MAPPING INFORMATION >>
[EBOOT: ] Vol 0 is Opened
[EBOOT: ] PocketStoreInitialize success
+OALArgsInit()
Arguments area has some values
-OALArgsInit()
[Eboot] ++InitializeDisplay()
Press [SPACE] to enter boot monitor.我对这些信息一无所知,但可以肯定地是,这个串口从CE系统启动之前就已经被用来当做调试口,我尝试了很多方法也没能把它占为己用。自然串口手柄的制作也就到此为止了。如果哪位牛人能提供点此串口的具体使用方法,相信将会造福广大魅友,小生将感激涕零。
串口手柄制作失败,暂时告一段落,我也就重新开始了
蓝牙手柄的改进工作。
今天去买了一个2.5mm的电源插座,一个单掷开关,又把一个旧MP3上的锂电池拆了下来,重新设计了供电电路,采用1N4148开关二极管(压降0.7v,锂电池实际电压4v左右,刚好可以供电3.3v),单片机里的代码也重新改写,简洁了许多。
我把手柄原来的SLOW键去掉了,把开关粘了上去,现在向左拨动开关就打开手柄电源,向右拨就断电,断电以后可以用万能充进行充电(暂不支持边使用边充电)。
附上新的单片机代码:
复制内容到剪贴板
代码:
/*******************************************************************************
*硬 件:由MAX232连接PC机
*软 件:UartAssist(设置为9600 无奇偶校验 8位数据位 1位停止位)
*主 芯 片:ATmega8L(DIP封装)
*编译软件:WINAVR
*编译语言:C
*晶振设置:内部8M时钟
*******************************************************************************/
#include <avr/io.h>
#include <avr/iom8.h>
#include <avr/macros.h>
#include <util/delay.h>
/***********串口初始化*****************/
void UART_Init(void)
{
CLI();
UCSRB = 0x18; //控制状态寄存器
UCSRC = 0x86; //异步 无奇偶校验 1位停止位 8位数据位
UBRRL = 51; //波特率 9600
SEI();
}
/****串口接收数据中断服务子程序********/
/*#pragma interrupt_handler Uart_recive:12
void Uart_recive(void)
{
while(!(UCSRA & (1 << RXC)))
;
received = UDR;
}*/
/****串口发送字符和字符串**************/
void Uart_putchar(unsigned char dat)
{
while(!(UCSRA & (1 << UDRE)))
;
UDR = dat;
}
void port_init(void) {
PORTB = 0xff;
DDRB = 0b01000000;
PORTC = 0xff;
DDRC = 0x00;
PORTD = 0xff;
DDRD = 0x00;
}
void init_devices(void) {
CLI();
port_init();
UART_Init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00;
SEI();
}
/*********主程序************************/
int main (void) {
unsigned short preKey = 0xFFFF;
unsigned short tmp = 0xFFFF;
init_devices();
tmp = ((PINB | 0xFFC1) >> 1) & (((0xFFE0 | PINC) << 5) | 0b1111110000011111);
preKey = tmp;
while(1) {
tmp = ((PINB | 0xFFC1) >> 1) & (((0xFFE0 | PINC) << 5) | 0b1111110000011111);
if(preKey != tmp) {
_delay_ms(10);
if(preKey != tmp) {
preKey = tmp;
Uart_putchar(0xf0);
Uart_putchar(~(preKey >> 8));
Uart_putchar(~preKey);
Uart_putchar(0x0f);
}
}
}
return 0;
}说了这么多,放几张照片吧,电路原理图和配置软件放在最后。
—————————————————————————————————————————————————————————————
2009-11-1更新
朋友想做一套街机摇台,用来回味“快乐的小时候”,我正好也想做一套蓝牙的,于是就上淘宝买了两套街机配件,包括仿清水的摇杆和仿三和的按钮。买回来以后,找了两个装笔记本电脑的纸箱,用圆规划了几个孔就把配件装上了。朋友刚好有一个废旧的USB手柄,拆开取出电路板,把摇杆和按钮的引脚用导线焊手柄的触点上就直接可以用了。我只有一个自制的北通蓝牙小手柄,没办法,只能全部拆开,用排针把手柄的触点一根一根引出来,连在了摇台上,哎手柄里面已经全是导线了……嘿嘿,现在既可以当USB手柄使,又可以当
蓝牙手柄使,也可以当USB摇台使,还可以当蓝牙摇台使……呵呵,4合一。先上两张图,视频以后上。
PS:我一直没找到好的供电方法,自己也没什么经验,貌似蓝牙对电压的精确度要求较高,否则会很不稳定,所以也急需各位大大提供一个行之有效的3.3v供电电路啊,谢了
—————————————————————————————————————————————————————————————
2009-10-27更新
又录了个视频,但是不知道怎么贴到帖子里,放出个地址吧!
http://v.youku.com/v_show/id_XMTI4MTM1NDUy.html
第一个视频请见
http://v.youku.com/v_show/id_XMTI3MjY4Mzky.html
—————————————————————————————————————————————————————————————
2009-10-26更新
经过两天的努力,自制手柄的配置软件“Joypad_for_M8” 终于可以正常使用了,姑且称其为0.1版,软件压缩包见附件。
1.可以读取.ini配置文件,大家可以针对不同的模拟器、不同的游戏进行配置
2.连接成功后可以切换到后台运行,无需再按“M”键
3.连接成功后可以测试按键,按键图片借用了MINISNES的图片^_^
关于配置
以下是配置文件config.ini的内容,只可以修改“=”之后的部分,修改其他部分的内容将导致出错。
[DEVICE]
BLUETOOTH_DEVICE_NAME=joypad_for_m8
[KEY]
1=38
2=40
4=37
8=39
16=13
32=27
64=193
128=194
256=195
512=196
“joypad_for_m8”是蓝牙设备的名字,我把蓝牙模块买回来通过串口AT命令修改了模块名称和波特率。
[KEY]下面的1,2,4,……,512是手柄发过来的按键编码(学过计算机的人都应该能看懂为什么是两倍两倍地增加),我制作的手柄按键编码对应如下:
1=上
2=下
4=左
8=右
16=START
32=SELECT
64=A
128=B
256=C
512=D
“=”后面的值是windows系统的虚拟按键编码,编码如下(对应括号里面的值,有些在windows CE里面不好使):
ESC键 VK_ESCAPE (27)
回车键: VK_RETURN (13)
TAB键: VK_TAB (9)
Caps Lock键: VK_CAPITAL (20)
Shift键: VK_SHIFT ()
Ctrl键: VK_CONTROL (17)
Alt键: VK_MENU (18)
空格键: VK_SPACE (/32)
退格键: VK_BACK (8)
左徽标键: VK_LWIN (91)
右徽标键: VK_LWIN (92)
鼠标右键快捷键:VK_APPS (93)
Insert键: VK_INSERT (45)
Home键: VK_HOME (36)
Page Up: VK_PRIOR (33)
PageDown: VK_NEXT (34)
End键: VK_END (35)
Delete键: VK_DELETE (46)
方向键(←): VK_LEFT (37)
方向键(↑): VK_UP (38)
方向键(→): VK_RIGHT (39)
方向键(↓): VK_DOWN (40)
F1键: VK_F1 (112)
F2键: VK_F2 (113)
F3键: VK_F3 (114)
F4键: VK_F4 (115)
F5键: VK_F5 (116)
F6键: VK_F6 (117)
F7键: VK_F7 (118)
F8键: VK_F8 (119)
F9键: VK_F9 (120)
F10键: VK_F10 (121)
F11键: VK_F11 (122)
F12键: VK_F12 (123)
Num Lock键: VK_NUMLOCK (144)
小键盘0: VK_NUMPAD0 (96)
小键盘1: VK_NUMPAD0 (97)
小键盘2: VK_NUMPAD0 (98)
小键盘3: VK_NUMPAD0 (99)
小键盘4: VK_NUMPAD0 (100)
小键盘5: VK_NUMPAD0 (101)
小键盘6: VK_NUMPAD0 (102)
小键盘7: VK_NUMPAD0 (103)
小键盘8: VK_NUMPAD0 (104)
小键盘9: VK_NUMPAD0 (105)
小键盘.: VK_DECIMAL (110)
小键盘*: VK_MULTIPLY (106)
小键盘+: VK_MULTIPLY (107)
小键盘-: VK_SUBTRACT (109)
小键盘/: VK_DIVIDE (111)
Pause Break键: VK_PAUSE (19)
Scroll Lock键: VK_SCROLL (145)
—————————————————————————————————————————————————————————————
2009-10-24更新
放出用ATmega8L-8PU单片机实现的原理图和源代码,此单片机功能更强,体积更小,可以装进手柄,外围元件也更少。至于M8端的配置软件Joypad_for_M8,目前不能读取ini文件,bug一大堆,所以暂不放出。
硬件制作完成后把代码下载到ATmega8L芯片内即可工作,按照"468357"大大的帖子
http://bbs.meizu.com/viewthread.php?tid=830081&highlight=fba修改一下FBA的插件配置文件就可以在FBA中使用了
复制内容到剪贴板
代码:
#include <avr/io.h>
#include <avr/iom8.h>
#include <avr/macros.h>
void Delay_mS(unsigned int Time) {
unsigned char n;
while(Time > 0) {
for(n = 1; n < 187; n++) {
asm("nop");
}
Time--;
}
}
void port_init(void) {
PORTB = 0xff;
DDRB = 0x00;
PORTC = 0xff; //m103 output only
DDRC = 0x00;
PORTD = 0xff;
DDRD = 0x00;
}
void uart0_init(void) {
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x02;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x67; //set baud rate low (9600)
UBRRH = 0x00; //set baud rate high
UCSRB = 0x18;
}
void init_devices(void) {
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
uart0_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void uart0_putChar(unsigned char ch) {
while(!(UCSRA & (1 << UDRE)))
;
UDR = ch;
}
int main (void) {
unsigned short preKey = 0xFFFF;
unsigned short tmp = 0xFFFF;
init_devices();
tmp = ((PINB | 0xFFC1) >> 1) & (((0xFFE0 | PINC) << 5) | 0b1111110000011111);
preKey = tmp;
while(1) {
tmp = ((PINB | 0xFFC1) >> 1) & (((0xFFE0 | PINC) << 5) | 0b1111110000011111);
if(preKey != tmp) {
Delay_mS(30);
if(preKey != tmp) {
preKey = tmp;
uart0_putChar(0xf0);
uart0_putChar(~(preKey >> 8));
uart0_putChar(~preKey);
uart0_putChar(0x0f);
}
}
}
return 0;
}—————————————————————————————————————————————————————————————
2009-10-23更新
硬件和软件都借鉴了"468357"大大的帖子:
http://bbs.meizu.com/viewthread.php?tid=830081&highlight=fba,再次对大大表示感谢。
废话不多说,先上传个使用视频和几张照片,等过两天整理一下资料再悉数上传:
http://v.youku.com/v_show/id_XMTI3MjY4Mzky.html
[
本帖最后由 阿梯 于 2009-11-12 21:23 编辑 ]