搜索
bottom↓
回复: 0

一个按键思路,大侠们给点建议。

[复制链接]

出0入0汤圆

发表于 2012-2-23 11:21:41 | 显示全部楼层 |阅读模式
优化一个4*4的按键程序,要返回长按键和短按键,大体思路如下:
1、功能函数key_scan 放while(1)里跑,不让系统有任何等待
2、通过状态机的方式实现
3、判断三次状态,有按键,消抖确定有按键,短按键或者长按键

看了很多种按键代码,消抖基本都用等待方式实现,效率不高,所以写了个这样的代码,全当练习。具体思路可以体现,但#define的不全。望高手指点二三。


type enum{
        KEY_SCAN_FIRST;
        KEY_SCAN_SECOND;
        KEY_SCAN_THIRD;
}KEY_SCAN_STATE;

typedef unsigned long long TICK_TYPE;

TICK_TYPE systick=0;
void Systick(void) //系统定时器中断 ,1ms 间隔
{
        systick++;
}

TICK_TYPE GET_currentTimetick() //获得当前TICK
{
        return systick;
}

struct KEY_BODY{
        unsigned char keynum;//哪个按键
        unsigned char keytype;//按键状态
        KEY_SCAN_STATE scan_status;//扫描状态
        TICK_TYPE scan_starttime; //扫描开始tick
        int keyshake_delay;//消抖tick
}key;



//KEYtype defines
#define KEY_DOWN_L 1
#define KEY_DOWN_S 2
#define KEY_UP     3








void key_init(struct KEY_BODY *key)
{
        key->keynum=key->keytype=0;
        key->scan_status = KEY_SCAN_FIRST;
        key->scan_starttime=0;
        key->keyshake_delay=25;//按键消抖时间
       
}
int key_on(void)
{
        ROWPORT_IN;//行,4 IO 入,低电平:下拉
        ROW_OUTPUT_LOW;
        LINEPORT_OUT; //列:4 IO 出,高电平
        LINE_OUTPUT_HING;
        if(ROW_PIN1 != ROW_LOW_MASK) //行 4IO 不全为低 有按键发生
                return KEY_ACTION;
        else
                return NO_KEY_ACTION;       
}

void key_scan (struct KEY_BODY *key)
{
                unsigned char i;
                unsigned char keymask=0;
                switch(key->scan_status)
                {
                        case KEY_SCAN_FIRST:
                                if(key_on()==KEY_ACTION) //有按键,记录时间TICK,状态变换
                                {
                                        key->scan_status = KEY_SCAN_SECOND;
                                        key->scan_starttime=GET_currentTimetick();
                                }
                                break;
                               
                                case KEY_SCAN_SECOND:
                                        if(key_on()==KEY_ACTION) //继续有按键
                                        {
                                                if(GET_currentTimetick()- key->scan_starttime > keyshake_delay) //消抖间隔25ms
                                                {
                                                        for(i=0;i<4;i++) //判按键 i是列
                                                        {
                                                                keymask|=(1<<i); //0000 0001 ,0000 0010,0000 0100,......
                                                                LINE_PIN=keymask;
                                                                switch(ROW_PIN) //判断行 IO 电平
                                                                {
                                                                        case 0x01: //第一行
                                                                        key->keynum = i+1; //第一行四个按键,键值:1,2,3,4
                                                                        break;
                                                                        case 0x02://第二行
                                                                        key->keynum = i+5; //第二行四个按键,键值:5,6,7,8
                                                                        break;
                                                                        case 0x04://第三行
                                                                        key->keynum = i+9;//第三行四个按键,键值:9,10,11,12
                                                                        break;
                                                                        case 0x08://第四行
                                                                        key->keynum = i+13;//第死行四个按键,键值:13,14,15,16
                                                                        break;
                                                                }                       
                                                        }
                                                        key->scan_status = KEY_SCAN_THIRD;
                                                }
                                                else return;                                       
                                        }
                                        else
                                                key->scan_status = KEY_SCAN_FIRST;
                                break;
                               
                                case KEY_SCAN_THIRD:
                                        key->scan_status = KEY_SCAN_FIRST;
                                        key->scan_starttime=GET_currentTimetick(); //获得当前tick
                                        do{ //等待按键释放
                                                if(GET_currentTimetick()- key->scan_starttime > 2000) //按键持续2s,跳出,长按键
                                                {
                                                        key->keytype=KEY_DOWNL;
                                                        return;
                                                }               
                                        }while(key_on()==KEY_ACTION)       
                                       
                                        key->keytype=KEY_DOWN; //释放,短按键
                                                                       
                                break;
                               
                                default:
                                break;
                }
       

}

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 08:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表