手機 - Nokia N900 - 自製遊戲手把(380機架)



雖然司徒之前已經自製一個N900手把,不過體積有點大,加上缺少Start、Select和L、R鍵,因此,司徒決定再製作一個更小、按鍵更多的手把,於是司徒找了一下可用的材料,發覺Dingoo Tech A380的按鍵還不錯


當然Dingoo Tech A330的手把也相當好看,只是它的A面並不是平面,製作難度比較高


Dingoo A320的按鍵是司徒最想拿來當材料,不過這一台是要拿來改IPS顯示屏,因此,這一台不能動刀


最後司徒決定使用Dingoo Tech A380,因為司徒覺得它的改造難度比較簡單,加上司徒短期應該沒時間研究它,但是A380的按鍵還是不夠多,因此,司徒決定使用如下材料當作其餘按鍵


抹掉外漆


剪裁


A380的D-Pad和按鍵


使用3秒膠固定


PCB板也使用3秒膠固定


PCB背面


使用CD-ROM的蓋子當支撐架


上D-Pad和按鍵


背面


拉線


使用更小的STM32F103板


焊接


固定STM32F103和手把主體


正面


需要一個USB Micro B接頭


USB Micro B連接到STM32F103主板


背面


連接支架


背面


完成


側面


背面


更薄的手把


另一面


底面


上邊


上手


相當棒的手把


跟前一代比較


另一面


電路圖


程式碼(修改自Keil MCBSTM32 Project):

volatile unsigned int cur_state = 0, pre_state = 0;
unsigned char index = 2;
unsigned char buffer[8] = {0};

void PushKey(unsigned char key)
{
    if (index >= 5) {
        buffer[0] = 0x00;
        buffer[1] = 0x00;
        buffer[2] = 0x01;
        buffer[3] = 0x01;
        buffer[4] = 0x01;
        buffer[5] = 0x01;
        buffer[6] = 0x01;
        buffer[7] = 0x01;
    }
    else {
        buffer[index] = key;
        index += 1;
    }
}

int main(void)
{
    stm32_Init(); // STM32 Initialization
    GPIOA->CRL = 0x88888888;
    GPIOA->CRH = 0x88888888;
    GPIOA->ODR = 0x00000000;
    GPIOB->CRL = 0x88888888;
    GPIOB->CRH = 0x88888888;
    GPIOB->ODR = 0x00000000;

    USB_Init(); // USB Initialization
    USB_Connect(TRUE); // USB Connect
    while (1) {    
        cur_state = 0; 
        if (GPIOB->IDR & 0x1000) { // PB12
            cur_state |= 0x0001;
        }
        if (GPIOB->IDR & 0x2000) { // PB13
            cur_state |= 0x0002;
        }
        if (GPIOB->IDR & 0x4000) { // PB14
            cur_state |= 0x0004;
        }
        if (GPIOB->IDR & 0x8000) { // PB15
            cur_state |= 0x0008;
        }
        if (GPIOA->IDR & 0x0100) { // PA8
            cur_state |= 0x0010;
        }
        if (GPIOA->IDR & 0x0200) { // PA9
            cur_state |= 0x0020;
        }
        if (GPIOA->IDR & 0x0400) { // PA10
            cur_state |= 0x0040;
        }
        if (GPIOB->IDR & 0x0400) { // PB10
            cur_state |= 0x0080;
        }
        if (GPIOB->IDR & 0x0200) { // PB9
            cur_state |= 0x0100;
        }
        if (GPIOB->IDR & 0x0001) { // PB0
            cur_state |= 0x0200;
        }
        if (GPIOA->IDR & 0x0040) { // PA6
            cur_state |= 0x0400;
        }
        if (GPIOA->IDR & 0x0080) { // PA7
            cur_state |= 0x0800;
        }
        if (GPIOB->IDR & 0x0020) { // PB5
            cur_state |= 0x1000;
        }
        if (GPIOB->IDR & 0x0040) { // PB6
            cur_state |= 0x2000;
        }

        if (cur_state == pre_state) {
            continue;
        }
        pre_state = cur_state;

        index = 2;
        buffer[0] = 0x00;
        buffer[1] = 0x00;
        buffer[2] = 0x00;
        buffer[3] = 0x00;
        buffer[4] = 0x00;
        buffer[5] = 0x00;
        buffer[6] = 0x00;
        buffer[7] = 0x00;
        if (pre_state & 0x0001) PushKey(0x50);
        if (pre_state & 0x0002) PushKey(0x12);
        if (pre_state & 0x0004) PushKey(0x05);
        if (pre_state & 0x0008) PushKey(0x11); 
        if (pre_state & 0x0010) PushKey(0x51);
        if (pre_state & 0x0020) PushKey(0x4f);
        if (pre_state & 0x0040) PushKey(0x07);
        if (pre_state & 0x0080) PushKey(0x04);
        if (pre_state & 0x0100) PushKey(0x1b);
        if (pre_state & 0x0200) PushKey(0x06);
        if (pre_state & 0x0400) PushKey(0x52);
        if (pre_state & 0x0800) PushKey(0x10);
        if (pre_state & 0x1000) PushKey(0x1c);
        if (pre_state & 0x2000) PushKey(0x14);

        if (USB_Configuration) {
            USB_WriteEP(0x81, buffer, sizeof(buffer));
        }
    }
}