打印
[程序源码]

分享一个通用的按键驱动程序

[复制链接]
1829|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mcu5i51|  楼主 | 2016-5-9 09:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
很少发贡献类的东东,这是自己写了几年的一个按键通用驱动,好久没有改动了,目前可以满足应用;
这个驱动模块可以提供按键的单次,连续,抬起,以及按下的有效时间,只是处理按键代码,如果用单个字节,可以表示8个可以组合的按键或255个没有组合的按键,不过由于我用的多数按键在4个左右,没有对255的键码做优化,好了上代码:
#ifndef _KEY_H
#define _KEY_H

#include "Typedef.h"

#define K1 0x01
#define K2 0x02
#define K3 0x04
#define K4 0x08

#define K5 0x10
#define K6 0x20
#define K7 0x40
#define K8 0x80

#define K_TIM(T)        (T/5)
#define K_ONE_TIM          (K_TIM(24))
#define K_CON_TIM          (K_TIM(700))
#define K_MAX_TIM        (K_TIM(10000))


typedef struct  
{
        u8 Key;                // 按键状态
        u16 Tim;        // 按键时间
        u8 One;                // 单次有效按键,只用一次
        u8 Up;                // 按键放开,只用一次
        u8 Con;                // 连续有效按键,
}KeyType;

extern KeyType Key;

//////////////////////
void Key_Init(void);
u8 GetKeyPin(void);                 // 按键引脚
void KeyDrv(void);                // 驱动

////////////////////////
KeyType GetKey(void);


#endif
#include "io.h"

#include "stdlib.h"
#include "key.h"

static KeyType KeyVol;
KeyType Key;

//////////////////////////////////////
//        Key IO 操作
//////////////////////////////////////
void Key_Init(void)
{
        IO_Key_Init( );
}

u8 GetKeyPin(void)
//按键引脚
{       
        return IO_GetKeyPin( );
}

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

KeyType GetKey(void)
{
        static KeyType _key;
       
// 禁用中断,也可以用标志位实现
//        disable_interrupt( );
        _key = KeyVol;
        KeyVol.One = 0;
        KeyVol.Up = 0;       
//        enableInterrupts( );                        //开中断
        return _key;
}

void KeyDrv(void)
//驱动
{
        static u8 Tmp_u8;
        Tmp_u8 = GetKeyPin();
       
        //没有按键        调用频率,最高到最低排列,减少CPU占用时间
        if(Tmp_u8 == 0)
        {
                //按键放开
                if(KeyVol.Key != 0)        KeyVol.Up = KeyVol.Key;       
               
                KeyVol.Con = 0;        KeyVol.Tim = 0;KeyVol.Key = 0;
                return;
        }

        //按键没变
        if(Tmp_u8 == KeyVol.Key)
        {
                //最大按键有效时间
                if(KeyVol.Tim < K_MAX_TIM) KeyVol.Tim++;               
                //按键连按有效       
                if(KeyVol.Tim > K_CON_TIM)        {KeyVol.Con = Tmp_u8;return;}                       
                //按键首次有效
                if(KeyVol.Tim == K_ONE_TIM)        {KeyVol.One = Tmp_u8;}               
                return;
        }
        //按键改变
        {KeyVol.Key = Tmp_u8;        KeyVol.Tim = 0;        return;}
}
修改以下两个函数,对应硬件
void Key_Init(void)
u8 GetKeyPin(void)    //按键引脚

void KeyDrv(void) 这个是周期调用的,一般我是和LED动态显示一起处理,调好.H文件的时间定义就好了;

KeyType GetKey(void) 用户调用,返回按键值



没有测试的一个例子:

main()
{
int cont;
   Timer_Inti();  //200HZ
   Key_Init();
   
   while(1)
  {
     Key = GwtKey();
    switch(Key.One) 单次有效,如果怕与连续有冲突可以用Key.up,就是按键放开
    {
       case: break;.....
    }
   
    switch(Key.One | Key.Con) 单次和连续有效,表现为按下K1后数值加1,之后大约800MS左右就连续加1,速度是主循环的时间,常用100MS处理一次就是10HZ
    {
       case K1:
          Cont ++;
        break;.....
    }
       if(Key.Tim > TIM(2)  && (Key.Con == K2)  ){长按2秒处理}
       print(cont);
    wait(100);

  }
}







相关帖子

沙发
wsnsyy| | 2016-5-9 09:24 | 只看该作者
抄来用一下看看

使用特权

评论回复
板凳
mcu5i51|  楼主 | 2016-5-9 09:44 | 只看该作者
一个简单的测试工程,51的简单,不过没有实测,也就是静态分析正常

8051_keil_demo.rar

21.69 KB

使用特权

评论回复
地板
逍遥派掌门| | 2016-5-12 16:52 | 只看该作者
思路不错,但是楼主没有考虑按键的震荡,补上就更好了。

使用特权

评论回复
5
mcu5i51|  楼主 | 2016-5-13 08:30 | 只看该作者
逍遥派掌门 发表于 2016-5-12 16:52
思路不错,但是楼主没有考虑按键的震荡,补上就更好了。

按键的震荡,不是很明白什么意思,如果是指的去抖动的话,已经有了

使用特权

评论回复
6
any012| | 2016-5-13 14:23 | 只看该作者
感谢分享,先下载下来看看。
好像下载了楼主好几个程序了。

使用特权

评论回复
7
hgjinwei| | 2016-5-14 10:09 | 只看该作者
KeyVol.Up 这个状态不可靠,可能存在干扰
如果GwtKey();执行的够频繁,KeyVol.Up 不一定能反应真实的按键释放次数。
不知楼主是否验证。

附件是本年写的一个按键驱动,尚未确认是否稳定(使用的时间还不够长,平台也不够多),
喜欢的人可以下载看看,希望有不可靠的反馈。

PS:#include "key.h"里面只是一些数据类型定义,比如"uint8","__CONST"等,可以自行加入。

key_button.rar

1.93 KB

使用特权

评论回复
8
逍遥派掌门| | 2016-5-17 14:32 | 只看该作者
本帖最后由 逍遥派掌门 于 2016-5-17 15:40 编辑
mcu5i51 发表于 2016-5-13 08:30
按键的震荡,不是很明白什么意思,如果是指的去抖动的话,已经有了

去抖动,是在main里面的wait(100) 吗? 
如果是的话,这种方式不好。

使用特权

评论回复
9
洛理小子| | 2016-5-17 22:37 | 只看该作者
mark    以后学习下~~

使用特权

评论回复
10
mcu5i51|  楼主 | 2016-5-18 11:23 | 只看该作者
逍遥派掌门 发表于 2016-5-17 14:32
去抖动,是在main里面的wait(100) 吗? 
如果是的话,这种方式不好。

不是呀,这个驱动是在中断中调用的,比较读取的键值有效次数,达到之后就是有效按键了

使用特权

评论回复
11
any012| | 2016-5-19 13:24 | 只看该作者
楼主在3份楼分享的附件,我下载下来解压时总是失败...

使用特权

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

本版积分规则

5

主题

1878

帖子

9

粉丝