问题描述
移植正点原子的按键到其他开发板上不能正常使用。因为正点原子的战舰版有4个按键,而目标开发板只有一个按键,所以就需要改动,我把其它3个的GPIO通过条件编译注释掉了,最开始我以为是这里问题,后来发现不是。问题是按键扫描函数的逻辑处理部分。
/**
* @brief 按键扫描函数
* @note 该函数有响应优先级(同时按下多个按键): WK_UP > KEY2 > KEY1 > KEY0!!
* @param mode:0 / 1, 具体含义如下:
* @arg 0, 不支持连续按(当按键按下不放时, 只有第一次调用会返回键值,
* 必须松开以后, 再次按下才会返回其他键值)
* @arg 1, 支持连续按(当按键按下不放时, 每次调用该函数都会返回键值)
* @retval 键值, 定义如下:
* KEY0_PRES, 1, KEY0按下
* KEY1_PRES, 2, KEY1按下
* KEY2_PRES, 3, KEY2按下
* WKUP_PRES, 4, WKUP按下
*/
uint8_t key_scan(uint8_t mode)
{
static uint8_t key_up = 1; /* 按键按松开标志 */
uint8_t keyval = 0;
if (mode) key_up = 1; /* 支持连按 */
if (key_up && (KEY0 == 0 || KEY1 == 0 || KEY2 == 0 || WK_UP == 1)) /* 按键松开标志为1, 且有任意一个按键按下了 */
{
delay_ms(10); /* 去抖动 */
key_up = 0;
if (KEY0 == 0) keyval = KEY0_PRES;
if (KEY1 == 0) keyval = KEY1_PRES;
if (KEY2 == 0) keyval = KEY2_PRES;
if (WK_UP == 1)
{
keyval = WKUP_PRES;
//printf("keyval = WKUP_PRES;\n");
}
}
else if (KEY0 == 1 && KEY1 == 1 && KEY2 == 1 && WK_UP == 0) /* 没有任何按键按下, 标记按键松开 */
{
key_up = 1;
}
return keyval; /* 返回键值 */
}
可以看出,这个按键扫描函数挺简单的,定义了一个局部静态变量key_up,当有按键按下的时候会被置0,当全部按键松开的时候会被置位1(默认状态),如果模式设置为1的话,就能够支持多个按键连续按(也就是按着这个不松情况下按其它的)。如果是单击模式的话,某一个按键按下了,就会返回对应的值,同时该按键必须要松开,才能进行其它或者本次按键的再次检测。
重点就在于下面那个else if表达式中,可以看出,是4个按键同时都松开的情况下才会把key_up置1,但因为我只使用1个按键(WK_UP),所以此处,我应当把其它按键都注释掉就可以正常使用了!
同时,这里使用的是if结构,所以,最后一次判断才为实际的值,所以说最后一个按键的优先级最高,如果在连续模式,同时按下4个按键的话,每次就只能打印出最后一个按键WK_UP了。
该函数功能也不够完善,其实我是比较喜欢中断的方式去判断的,最好再配合队列。