MENU

MAME移植之树莓派驱动FC手柄

2024 年 07 月 06 日 • 嵌入式

为了研究红白机上FC手柄的工作原理,从某宝上花了十几块钱买了一个FC手柄。

uUyuhH

当然买了之后就拆了,这东西也就值个几块钱。后续这些按键和导电胶可以用在自己的电路板上。

ryx7er

小时候一直好奇,有10个按键,为啥只有5根线,当然当时啥都不会也就一直不知道为什么。
现在去查资料,才知道手柄中用了一个8位锁存器,将8个按键值(手柄外观上有10个键,其中快A和快B和A、B的键值是一样的,不过快A和快B会触发定时器持续输出脉冲模拟快速按下)从并转串,整个手柄的输出波形如下:

0Ua9IH

五条线分别为

  • 5V电压输入
  • GND接地线
  • CLK时钟信号
  • LATCH锁存器信号
  • DATA数据

工作原理就是每一个CLK是一个脉冲输入给手柄,LATCH也是输入信号输入给手柄(上升沿或者下降沿进行锁存),然后每一个CLK,DATA数据线就会输出一位锁存的数据,8位锁存器需要在8个时钟信号中将数据全部输出。

这个的检测代码比较好写,如下:

void check_key(void)
{
    gpiod_line_set_value(g_key_latch, 1);
    usleep(1);
    gpiod_line_set_value(g_key_latch, 0);

    uint8_t i;
    uint8_t temp = 0;
    for (i = 0; i < 8; i++) {
        temp >>= 1;
        int b = gpiod_line_get_value(g_key_data);
        if (b == 0) {
            temp |= 0x80;
        }
        gpiod_line_set_value(g_key_clock, 1);
        usleep(1);
        gpiod_line_set_value(g_key_clock, 0);
        usleep(1);
    }

    struct key_val_map val;
    memcpy(&val, &temp, sizeof(temp));

    if (temp != 0) {
        printf("read done %u %u %u %u %u %u %u %u\n",
            val.r, val.l, val.d, val.u,
            val.start, val.select, val.a, val.b);
        
        for (int i = 0; i < 8; i++) {
            if ((temp >> i) & 0x01) {
                printf("1 ");
            } else {
                printf("0 ");
            }
        }
        printf("\n");
    }
}

通过判断temp的值就可以处理手柄的输入了🎉。

最后编辑于: 2024 年 07 月 21 日