|
先看看成品~ 街机摇杆游戏控制器 用起来还是不错的 ^_^ 模拟键盘按键,可支持6键同时按下 主要材料:1、摇杆和按钮 2、M8单片机 3、厚压缩板 下面来看看制作过程 1、程序开发调试(程序搞不好也不用做其他了,整个项目流产) M8单片机测试,用于处理按键信息转换USB键盘信号 够乱吧,哈哈 xD 程序做好之后就要准备其他东西了 淘宝的两个摇杆和20按钮连运费一共58,也不知道是便宜还是贵 找朋友给了块厚木板 打印一张比例差不多的街机按键尺寸图,直接在圆的中间点戳个洞 用笔穿过洞,点在板上 又问朋友借 了把电钻和开孔器,开工 安装上按钮看看效果 做边框和底部 接线 基本完成了,找个砖家来试车,按键的反应点调了好久才调的差不多 电路板暂用平时的开发板,等有空再焊一块专用吧 开始玩游戏罗~哈哈,谢谢收看 下面是源码,我这程序好像有点不稳定,有时会USB通讯错误,看不出那的原因,还望各位大哥指教 - /* Name: HIDKEY.c
- * Project: HID-Test
- * Creation Date: 2013-01-28
- */
- #define F_CPU 12000000L /* evaluation board runs on 4MHz */
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #include <avr/pgmspace.h>
- #include <avr/wdt.h>
- #include <util/delay.h> /* for _delay_ms() */
- #include "usbdrv.h"
- #include "oddebug.h"
- static uchar reportBuffer[7]={0}; /* buffer for HID reports */
- static uchar idleRate; /* in 4 ms units */
- /* ----------------------- hardware I/O abstraction ------------------------ */
- /* pin assignments:
- PB0 USB-
- PB1 USB+
- PB2 Key
- PB3 Key
- PB4 Key
- PB5 Key
- PC0 Key
- PC1 Key
- PC2 Key
- PC3 Key
- PC4 Key
- PC5 Key
- PC6 Key
- PD0 key
- PD1 key
- PD2 USB+ (int0)
- PD3 Key
- PD4 Key
- PD5 Key
- PD6 Key
- PD7 Key
- */
- static void hardwareInit(void)
- {
- PORTC = 0x3f; /* activate all pull-ups pc6脚为复位键下降沿即触发所以不可用*/
- DDRC = 0; /* all pins input m8的引脚只有7个,除掉pc6脚后就是0x3f*/
- PORTD = 0xfb; /*activate all pull-ups pd2为中断口,不能占用,故用0xfb*/
- DDRD = 0; /* all pins input */
- }
- /* ----------------------------- USB interface ----------------------------- */
- /* ------------------------------------------------------------------------- */
- //描述报告的大小要修改usbconfig.h的大小#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 35 /* total length of report descriptor */项
- PROGMEM char usbHidReportDescriptor[35] = { /* USB report descriptor */
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x06, // USAGE (Keyboard)
- 0xa1, 0x01, // COLLECTION (Application)
- 0x05, 0x07, // USAGE_PAGE (Keyboard)
- 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
- 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x25, 0x01, // LOGICAL_MAXIMUM (1)
- 0x75, 0x01, // REPORT_SIZE (1)
- 0x95, 0x08, // REPORT_COUNT (8)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
- 0x95, 0x06, // REPORT_COUNT (6)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x25, 0x65, // LOGICAL_MAXIMUM (101)
- 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
- 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
- 0x81, 0x00, // INPUT (Data,Ary,Abs)
- 0xc0 // END_COLLECTION
- };
- /* We use a simplifed keyboard report descriptor which does not support the
- * boot protocol. We don't allow setting status LEDs and we only allow one
- * simultaneous key press (except modifiers). We can therefore use short
- * 2 byte input reports.
- * The report descriptor has been created with usb.org's "HID Descriptor Tool"
- * which can be downloaded from http://www.usb.org/developers/hidpage/.
- * Redundant entries (such as LOGICAL_MINIMUM and USAGE_PAGE) have been omitted
- * for the second INPUT item.
- */
- /* Keyboard usage values, see usb.org's HID-usage-tables document, chapter
- * 10 Keyboard/Keypad Page for more codes.
- */
- #define MOD_CONTROL_LEFT (1<<0)
- #define MOD_SHIFT_LEFT (1<<1)
- #define MOD_ALT_LEFT (1<<2)
- #define MOD_GUI_LEFT (1<<3)
- #define MOD_CONTROL_RIGHT (1<<4)
- #define MOD_SHIFT_RIGHT (1<<5)
- #define MOD_ALT_RIGHT (1<<6)
- #define MOD_GUI_RIGHT (1<<7)
- #define KEY_A 4
- #define KEY_B 5
- #define KEY_C 6
- #define KEY_D 7
- #define KEY_E 8
- #define KEY_F 9
- #define KEY_G 10
- #define KEY_H 11
- #define KEY_I 12
- #define KEY_J 13
- #define KEY_K 14
- #define KEY_L 15
- #define KEY_M 16
- #define KEY_N 17
- #define KEY_O 18
- #define KEY_P 19
- #define KEY_Q 20
- #define KEY_R 21
- #define KEY_S 22
- #define KEY_T 23
- #define KEY_U 24
- #define KEY_V 25
- #define KEY_W 26
- #define KEY_X 27
- #define KEY_Y 28
- #define KEY_Z 29
- #define KEY_1 30
- #define KEY_2 31
- #define KEY_3 32
- #define KEY_4 33
- #define KEY_5 34
- #define KEY_6 35
- #define KEY_7 36
- #define KEY_8 37
- #define KEY_9 38
- #define KEY_0 39
- #define KEY_F1 58
- #define KEY_F2 59
- #define KEY_F3 60
- #define KEY_F4 61
- #define KEY_F5 62
- #define KEY_F6 63
- #define KEY_F7 64
- #define KEY_F8 65
- #define KEY_F9 66
- #define KEY_F10 67
- #define KEY_F11 68
- #define KEY_F12 69
- /* ------------------------------------------------------------------------- */
- /* The following function returns an index for the first key pressed. It
- * returns 0 if no key is pressed.
- */
- uchar gamepad[]={0,0,KEY_W,KEY_A,KEY_D,KEY_S,KEY_U,KEY_C,KEY_K,KEY_X,KEY_I,KEY_J};
- uchar change=0,x1=0,y1=0;
- uchar pinkey[10]={0};
- uchar check=0;
- uchar delaycheck=0;//防止KeyRead第一次延时
- static uchar KeyRead( void )
- {
- uchar mask, x,y,xi=0;
- x = PINC;
- y = PIND;
- mask = 1;
- if((x1 != x) || (y1 != y)){y1=y;x1=x;change=1;}else{change = 0;}
- if(delaycheck > 0){
- for(int i=0;change && i<6;i++){
- if((x1 & mask) == 0){
- _delay_us(9500);
- if((x1 & mask) == 0) {
- pinkey[xi]=0;
- if(change && x1 != 0x3f){
- pinkey[xi++]=i;
- }}}
- mask <<= 1;
- }
- mask=1;
- for(int i=0;change && i<7;i++){
- if((y1 & mask) == 0){
- _delay_us(9500);
- if((y1 & mask) == 0) {
- pinkey[xi]=0;
- if(change && y1 != 0xfb){
- pinkey[xi++]=i+6;
- }}}
- if(i==1){mask <<= 1;}
- mask <<= 1;
- }
- xi=0;
- if(change){
- if(pinkey[0] != 0)
- {
- while(check == 0)
- {
- if(usbInterruptIsReady())
- {
- reportBuffer[0]=0; //特殊功能键
- reportBuffer[1]=gamepad[pinkey[0]];//键值
- reportBuffer[2]=gamepad[pinkey[1]];//键值
- reportBuffer[3]=gamepad[pinkey[2]];//键值
- reportBuffer[4]=gamepad[pinkey[3]];//键值
- reportBuffer[5]=gamepad[pinkey[4]];//键值
- reportBuffer[6]=gamepad[pinkey[5]];//键值
- usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
- check = 1;
- }
- }
- check=0;
- }
- }
- if(PINC == 0x3f && PIND == 0xfb){
- _delay_ms(5);
- if(change && (PINC == 0x3f && PIND == 0xfb))
- {
- while(check == 0)
- {
- if(usbInterruptIsReady())
- {
- reportBuffer[0]=0; //特殊功能键
- reportBuffer[1]=0;//键值
- reportBuffer[2]=0;//键值
- reportBuffer[3]=0;//键值
- reportBuffer[4]=0;//键值
- reportBuffer[5]=0;//键值
- reportBuffer[6]=0;//键值
- usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
- check = 1;
- }
- }
- check=0;
- }
- }
- xi=0;
- while(pinkey[xi] != 0)
- {
- pinkey[xi++]=0;
- }
- }//delaycheck one time
- delaycheck = 1;
- return 0;
- }
- /* ------------------------------------------------------------------------- */
- uchar usbFunctionSetup(uchar data[8])
- {
- usbRequest_t *rq = (void *)data;
- usbMsgPtr = reportBuffer;
- if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */
- if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
- /* we only have one report type, so don't look at wValue */
- }else if(rq->bRequest == USBRQ_HID_GET_IDLE){
- usbMsgPtr = &idleRate;
- return 1;
- }else if(rq->bRequest == USBRQ_HID_SET_IDLE){
- idleRate = rq->wValue.bytes[1];
- }
- }else{
- /* no vendor specific requests implemented */
- }
- return 0;
- }
- /* ------------------------------------------------------------------------- */
- int main(void)
- {
- wdt_enable(WDTO_2S);
- odDebugInit();
- usbInit();
- sei();
- DBG1(0x00, 0, 0);
- hardwareInit();
- for(;;){ /* main event loop */
- wdt_reset();
- usbPoll();
- KeyRead();
- }
- return 0;
- }
- /* ------------------------------------------------------------------------- */
[ 此帖被coolcall在2013-02-26 18:20重新编辑 ]
|