打印

[源代码] 【eCos应用程序】一个按键扫描应用程序模块

[复制链接]
2859|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
reille|  楼主 | 2013-4-25 09:06 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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)
沙发
outstanding| | 2013-7-20 15:11 | 只看该作者
没有玩过 ecos

使用特权

评论回复
板凳
reille|  楼主 | 2013-7-22 09:37 | 只看该作者
outstanding 发表于 2013-7-20 15:11
没有玩过 ecos

有兴趣,可以了解!:lol

使用特权

评论回复
地板
outstanding| | 2013-7-22 10:32 | 只看该作者
reille 发表于 2013-7-22 09:37
有兴趣,可以了解!

恩,好的

使用特权

评论回复
5
aaaxmaaa007| | 2014-1-3 16:04 | 只看该作者
谢谢楼主的共享!对RTT比较熟悉,不知道ecos相比如何?

使用特权

评论回复
6
reille|  楼主 | 2014-1-3 19:22 | 只看该作者
aaaxmaaa007 发表于 2014-1-3 16:04
谢谢楼主的共享!对RTT比较熟悉,不知道ecos相比如何?

呵,对RTT不熟悉,所以暂时没有答案~

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:欢迎加入eCos群:144940146 欢迎访问我的个人博客: http://velep.com 喜欢eCos,就像当初喜欢linux一样,如果你也有兴趣访问:http://52ecos.net

17

主题

584

帖子

3

粉丝