为了研究红白机上FC手柄的工作原理,从某宝上花了十几块钱买了一个FC手柄。
当然买了之后就拆了,这东西也就值个几块钱。后续这些按键和导电胶可以用在自己的电路板上。
小时候一直好奇,有10个按键,为啥只有5根线,当然当时啥都不会也就一直不知道为什么。
现在去查资料,才知道手柄中用了一个8位锁存器,将8个按键值(手柄外观上有10个键,其中快A和快B和A、B的键值是一样的,不过快A和快B会触发定时器持续输出脉冲模拟快速按下)从并转串,整个手柄的输出波形如下:
五条线分别为
- 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
的值就可以处理手柄的输入了🎉。