1. 首先大致了解下按键
按键分为常开和常闭两种,工作原理是按下后电势发生了变化。
2. 看原理图
可以看出,这里按键是常开的,按下前, KP_COL 处是高电压,按下后为低电压,所以可以通过监视 KP_COL 来确定是否按下。
通过查阅原理图可以指导 INT 和 KP_COL 对应的GPIO,这样就知道对应的寄存器了,那么只需要设置对应的GPIO为输入模式,并读寄存器,只要为0就说明按下。
3. 处理按键
处理按键需要通常使用中断,但这里先使用轮询的方式,测试上面的推论是否正确,中断将在中断部分独立讨论。
#define rGPH0CON (*(volatile unsigned int *)0xE0200C00) #define rGPH0DAT (*(volatile unsigned int *)0xE0200C04) #define rGPH2CON (*(volatile unsigned int *)0xE0200C40) #define rGPH2DAT (*(volatile unsigned int *)0xE0200C44) #include "stdio.h" static void delay20ms() { volatile unsigned int i = 1000, j = 1000; for (; i > 0; i--) for (; j > 0; j--); } void key_polling() { rGPH0CON &= ~(0xff << 8); rGPH2CON &= ~0xffff; while (1) { if (!(rGPH0DAT & (1 << 2))) { delay20ms(); if (!(rGPH0DAT & (1 << 2))) printf("EINT2\n"); } if (!(rGPH0DAT & (1 << 3))) { delay20ms(); if (!(rGPH0DAT & (1 << 3))) printf("EINT3\n"); } if (!(rGPH2DAT & (1 << 0))) { delay20ms(); if (!(rGPH2DAT & (1 << 0))) printf("KP_COL0\n"); } if (!(rGPH2DAT & (1 << 1))) { delay20ms(); if (!(rGPH2DAT & (1 << 1))) printf("KP_COL1\n"); } if (!(rGPH2DAT & (1 << 2))) { delay20ms(); if (!(rGPH2DAT & (1 << 2))) printf("KP_COL2\n"); } if (!(rGPH2DAT & (1 << 3))) { delay20ms(); if (!(rGPH2DAT & (1 << 3))) printf("KP_COL3\n"); } } }
上面代码模拟了按键消抖,按键消抖就是当检查到按下后,不处理,延迟一段时间等待电压变化稳定后再次判断是否按下。