AVR單晶片製作的N900手把

電路圖

原本要使用的藍牙手把



最後選定的材料

STM32F103開發板

裁切D-Pad和4顆按紐的面板以及PCB板

Micro USB和Mini USB傳輸線直接對接

底座

A320的Logo還是蠻好看的

固定位置

焊接

接線

外觀

背面就比較醜陋

支架固定

調整最佳的手感間距

用膠帶固定裸線

打一根樁腳

上架並焊接到STM32F103開發板

使用AB膠固定

開始蓋房子

側面

背面

使用塑鋼土補底

使用指甲油彩繪

光亮的背面

完成

側面

厚度有點厚,不過手感很棒

厚電池加上厚手把

手把底部使用沙紙磨圓,讓手感更好

這一面沒有可以固定的東西,因此,底部使用雙面膠替代,避免手把搖晃

手感相當不錯

由於司徒改裝的手把沒有Start、Select、L、R按鈕,因此,司徒只好使用音量+/-鍵(F7/F8)當作Start和Select按鈕,捨棄L、R按鈕,Mapping的方式如下:
$ sudo apt-get install xbindkeys xdotool
$ vim ~/.xbindkeysrc
"xdotool key q"
F7
"xdotool key w"
F8
$ xbindkeys
司徒將音量+/-改成q/w鍵,因此,在遊戲的Key Define中,使用者直接設定Start/Select成q/w即可
電路圖:

程式碼(修改自Keil MCBSTM32 Project):
unsigned char cur_state = 0;
unsigned char 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] = 4 + (key - 'a');
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 (GPIOA->IDR & 0x100) { // PA8
cur_state |= 0x01;
}
if (GPIOB->IDR & 0x8000) { // PB15
cur_state |= 0x02;
}
if (GPIOB->IDR & 0x4000) { // PB14
cur_state |= 0x04;
}
if (GPIOB->IDR & 0x2000) { // PB13
cur_state |= 0x08;
}
if (GPIOB->IDR & 0x1000) { // PB12
cur_state |= 0x10;
}
if (GPIOB->IDR & 0x800) { // PB11
cur_state |= 0x20;
}
if (GPIOB->IDR & 0x4) { // PB2
cur_state |= 0x40;
}
if (GPIOB->IDR & 0x400) { // PB10
cur_state |= 0x80;
}
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 & 0x01) PushKey('a');
if (pre_state & 0x02) PushKey('b');
if (pre_state & 0x04) PushKey('c');
if (pre_state & 0x08) PushKey('d');
if (pre_state & 0x10) PushKey('e');
if (pre_state & 0x20) PushKey('f');
if (pre_state & 0x40) PushKey('g');
if (pre_state & 0x80) PushKey('h');
USB_WriteEP(0x81, buffer, sizeof(buffer));
}
}