由上篇博文介绍,按键主要有两种响应处理方式,本篇介绍按键的轮询方式。
0.源码
GitHub:https://github.com/Kilento/4412NoOS
1.按键初始化
由上篇博文已知按键使用的GPIO引脚,对应开发板上的丝印层如下:
- GPX1_1 -> Home
- GPX1_2 -> BACK
- GPX3_3 -> Sleep
- GPX2_1 -> Vol+
- GPX2_0 -> Vol-
使用按键,引脚需要处于输入模式。以 GPX1_1 为例,查阅芯片手册可知,设置 GPX1CON[1] 寄存器为 0x0 可以设置引脚 GPX1_1为输入模式。
GPX1CON[1]为输入模式时,通过GPX1DAT寄存器可以读取 8bit 的输入数据,其中GPX1DAT[1]为 GPX1_1 引脚的输入数据。
根据手册描述的寄存器地址,这两个寄存器定义如下:
#define GPIOBASE1 0x11000000
#define GPX1CON (*(volatile unsigned long *)(GPIOBASE1 + 0x0C20))
#define GPX1DAT (*(volatile unsigned long *)(GPIOBASE1 + 0x0C24))
1.1 按键初始化代码
void key_init(void)
{
GPX1CON = 0x00000000;
GPX2CON = 0x00000000;
GPX3CON = 0x00000000;
return;
}
2.按键轮询
按键轮询的逻辑也很简单。通过 while(1) 死循环获取所有引脚的值,如果引脚值为 0 ,说明按键被按下。
2.1 获取按键值
int get_key_value(int key_id)
{
int key_value = 0;
switch (key_id) {
case KEY_HOME:
{
key_value = GPX1DAT & 0x2;
break;
}
case KEY_BACK:
{
key_value = GPX1DAT & 0x4;
break;
}
case KEY_SLEEP:
{
key_value = GPX3DAT & 0x8;
break;
}
case KEY_VOLUME_REDUCE:
{
key_value = GPX2DAT & 0x1;
break;
}
case KEY_VOLUME_PLUS:
{
key_value = GPX2DAT & 0x2;
break;
}
default:
{
key_value = 1;
break;
}
}
return key_value;
}
2.2 打印按键值
void put_key_value(int key_id)
{
switch (key_id) {
case KEY_HOME:
{
printf("Home\n");
break;
}
case KEY_BACK:
{
printf("Back\n");
break;
}
case KEY_SLEEP:
{
printf("Sleep\n");
break;
}
case KEY_VOLUME_REDUCE:
{
printf("Vol-\n");
break;
}
case KEY_VOLUME_PLUS:
{
printf("Vol+\n");
break;
}
default:
{
printf("Invalid key id = %d\n", key_id);
break;
}
}
return;
}
2.3 main循环
while (1) {
key_value = get_key_value(KEY_HOME);
if (0 == key_value) {
put_key_value(KEY_HOME);
}
key_value = get_key_value(KEY_BACK);
if (0 == key_value) {
put_key_value(KEY_BACK);
}
key_value = get_key_value(KEY_SLEEP);
if (0 == key_value) {
put_key_value(KEY_SLEEP);
}
key_value = get_key_value(KEY_VOLUME_REDUCE);
if (0 == key_value) {
put_key_value(KEY_VOLUME_REDUCE);
}
key_value = get_key_value(KEY_VOLUME_PLUS);
if (0 == key_value) {
put_key_value(KEY_VOLUME_PLUS);
}
}
2023年03月28日
Kilento