本帖最后由 reille 于 2013-4-25 09:14 编辑
简 介:
这个按键扫描程序,是我自己写的,在安富莱开发板上已验证OK。功能实现上有参照了安富莱开发板上的按键示例。但具体实现上有自己的特点,也是eCos应用程序一个典型应用程序。
为读取按键值,程序开了一个线程轮询扫描按键状态(频率间隔默认10ms),使用软件滤波方式去除按键抖动,实现了按键按下、按键弹起、按键长按、按键连发等按键状态的读取,并支持组合按键。读取到的按键值将保存在一个缓冲区即所谓的FIFO中,供其它模块读取(在这里是直接打印在串口上)。运行效果如下图所示。
源程序说明:
程序可作为一个单独的功能模块,与其它应用程序模块一起组成一个综合应用程序。因此,设计上,该程序由3个源文件组成,分别是:button.c、button.h、button_api.h。其中,button.c是功能实现;button.h是私有头文件;button_api.h是供其它应用程序模块包含的头文件。提供了3个对外的API函数:
/****************************************************************************/
/* API functions */
/****************************************************************************/
/* Module initialization */
void button_init(void * data);
key_t read_key(void);
key_t read_key_by_id(const key_id_t id);
初始化:
/* Module initialization */
void button_init(void * data)
{
button_global_t * btn = &BUTTON_global;
BUTTON_MUTEX_init();
bzero(btn->key_buff, sizeof(btn->key_buff));
btn->key_buff_read_idx = btn->key_buff_write_idx = 0;
INIT_BUTTON_USER((&btn->button[KID_USER]));
INIT_BUTTON_TAMPER((&btn->button[KID_TAMPER]));
INIT_BUTTON_WAKEUP((&btn->button[KID_WAKEUP]));
INIT_BUTTON_JOY_UP((&btn->button[KID_JOY_UP]));
INIT_BUTTON_JOY_DOWN((&btn->button[KID_JOY_DOWN]));
INIT_BUTTON_JOY_LEFT((&btn->button[KID_JOY_LEFT]));
INIT_BUTTON_JOY_RIGHT((&btn->button[KID_JOY_RIGHT]));
INIT_BUTTON_JOY_OK((&btn->button[KID_JOY_OK]));
INIT_BUTTON_USER_TAMPER((&btn->button[KID_USER_TAMPER]));
/* Create button thread */
cyg_thread_create(6, /* Priority */
button_thread,
0,
"Button thread",
BUTTON_thread_stack,
sizeof(BUTTON_thread_stack),
&BUTTON_thread_handle,
&BUTTON_thread_block);
cyg_thread_resume(BUTTON_thread_handle);/* Starting thread */
}
/* Application entry */
void cyg_user_start(void)
{
button_init(NULL);
cyg_scheduler_start();/* Scheduler start */
return;
}
按键扫描线程函数:
static void button_thread(cyg_addrword_t data)
{
button_global_t * btn = &BUTTON_global;
key_id_t id;
/* Informations */
diag_printf("******************************************************************************\n");
diag_printf("** A KEY TEST ROUTINE **\n");
diag_printf("** **\n");
diag_printf("** Copyright (C) 2013 eCos Tech Nets(www.52ecos.net). All Rights Reserved. **\n");
diag_printf("** **\n");
diag_printf("** Author: reille **\n");
diag_printf("** Date : 2013.04 **\n");
diag_printf("** Ver : Ver0.1 **\n");
diag_printf("** **\n");
diag_printf("******************************************************************************\n");
diag_printf("\nPlease press a key...\n\n");
while(1) {
for (id = KID_START; id < KEY_COUNTS; id++) {
button_detect(&btn->button[id]);
}
#if (BUTTON_PRINT_KEY_INFO)
key_t key = read_key();
if (key != KEY_NONE) {
diag_printf("key = %d, ", key);
switch (key) {
case KEY_DOWN_USER: /* User键按下 */
diag_printf("'USER' Key Down\n"); break;
case KEY_UP_USER: /* User键弹起 */
diag_printf("'USER' Key Up\n"); break;
case KEY_LONG_USER: /* User键长按 */
diag_printf("'USER' Key Long Press\n"); break;
case KEY_DOWN_WAKEUP: /* WakeUp键按下 */
diag_printf("'WAKEUP' Key Down\n");break;
case KEY_UP_WAKEUP: /* WakeUp键弹起 */
diag_printf("'WAKEUP' Key Up\n");break;
case KEY_DOWN_TAMPER: /* Tamper键按下 */
diag_printf("'TAMPER' Key Down\n");break;
case KEY_UP_TAMPER: /* Tamper键弹起 */
diag_printf("'TAMPER' Key Up\n");break;
case KEY_DOWN_JOY_UP: /* 摇杆UP键按下 */
diag_printf("'JOY UP' Key Down\n");break;
case KEY_DOWN_JOY_DOWN: /* 摇杆DOWN键按下 */
diag_printf("'JOY DOWN' Key Down\n");break;
case KEY_DOWN_JOY_LEFT: /* 摇杆LEFT键按下 */
diag_printf("'JOY LEFT' Key Down\n");break;
case KEY_DOWN_JOY_RIGHT: /* 摇杆RIGHT键按下 */
diag_printf("'JOY RIGHT' Key Down\n");break;
case KEY_DOWN_JOY_OK: /* 摇杆OK键按下 */
diag_printf("'JOY OK' Key Down\n");break;
case KEY_UP_JOY_OK: /* 摇杆OK键弹起 */
diag_printf("'JOY OK' Key Up\n");break;
case KEY_DOWN_USER_TAMPER:
diag_printf("'USER & TAMPER' Combination Key Down\n");break;
default:
diag_printf("Unknown Key\n");break;
}
}
#endif
APPL_OS_MSLEEP(BUTTON_SCAN_PERIOD_MS);
}
}
更多的实现,看代码吧。
注 意:
本程序是一个小型的综合性的eCos应用程序,集合了线程、GPIO应用、软件滤波、FIFO、高级宏等知识。因此,如果有什么疑问的话,可以在这里发贴子,我将及时回复。
下载地址:
button (from www.52ecos.net).zip
(272.33 KB)
|