单片机按键长按短按检测MS8006示例代码说明

在MS8006示例代码库中有一个mculib_key.c文件中主要是按键实现的相关函数,mculib_key_init是作为MS8006开发平台的IO口初始化配置,_do_key_scan()函数是按键扫描函数,是一个很经典的按键扫描算法,这个函数可实现按键的长按短按功能,并且可配置按键IO口的位操作或者是总线操作。原理是检测按下的瞬间和弹起的瞬间。可以从以下示例代码逐步分析:

VOID _do_key_scan()

{

UINT8 u8keyVal,PortB_Val;

//先定义两个变量

PortB_Val=0xf0 | PIN_KEY4 << 3 | PIN_KEY3 << 2 | PIN_KEY2 << 1 | PIN_KEY1;

//这里按键IO使用的位操作,利用移位将4个位整合成一组数据

u8keyVal=PortB_Val & KEY_GLOBAL_SWITCH;

//按键可配置成共阴接法或是共阳接法,这里使用的共阴接法,即低电平触发,在mculib_key.h中可知KEY_GLOBAL_SWITCH为0xff,举个例子说明,假设此时按下了1按键即PortB_Val=0xfe,则u8keyVal=0xfe

g_u8keyTrigger=u8keyVal & (u8keyVal ^  g_u8keyCount);

// g_u8keyCount代表连续按下的变量,这里第一次默认为0xff,与u8keyVal进行异或运算,所以

(1)、如果按键1是短按的情况为:按下后短时间弹起说明此函数还能检测到弹起瞬间的,而物理按键按下时间必然大于函数运行时间,所以弹起瞬间时g_u8keyCount已为0xfe,但是由于已弹起u8keyVal变成0xff,计算下式后又将值赋给g_u8keyCount,所以g_u8keyCount参与算法运算后又变成0xff。

g_u8keyTrigger=0xff&(0xff^0xfe)计算后         g_u8keyTrigger=0x01    

此时g_u8keyTrigger=0x01

                          g_u8keyCount=0xff

(2)、如果按键1是长按的情况为:按下后开始定时器计算低电平时间,所以是检测不到弹起瞬间的,此时按键处于低电平状态此时由于是连续按下g_u8keyCount已被赋值为0xfe,而且u8keyVal此时也为0xfe,那么和进行异或运算后得

g_u8keyTrigger=0xfe&(0xfe^0xfe)计算后g_u8keyTrigger=0

此时 g_u8keyTrigger=0, g_u8keyCount=0xfe

g_u8keyCount  =u8keyVal;

//这是长按的情况将当前的u8keyVal赋给g_u8keyCount

}

接下来在mculib_key_detect()函数中实现长按短按各返回的值,因为在文件开头已经宏定义了

#define KEY_RESCAN_LONG     (60)         按键循环检测时间为50ms,这里设置60即长按时间为60*50ms=1s

#define KEY_SWITCH1         (0X01)

#define KEY_SWITCH2         (0X02)

#define KEY_SWITCH3         (0X04)

#define KEY_SWITCH4         (0X08)

#define KEY_GLOBAL_SWITCH   (0xff)

所以在mculib_key_detect()中再利用UINT8 mculib_key_detect(VOID)返回值函数,返回在主函数中加以应用

UINT8 mculib_key_detect(VOID)

{        

    UINT8  u8keyPressed = KEY_NONE;

    _do_key_scan();                      //运行上面的按键扫面函数

    if (g_u8keyTrigger & KEY_SWITCH1)      //这里只是列举了按键1按下的情况,由于此时是短按功能,所以由_do_key_scan();可得g_u8keyTrigger=0x01进行按位与后得0x01,if语句为真,即可运行

    {    

        if (g_bAntiShakeFlag)

        {

            u8keyPressed = KEY_MAP_1;    //将变量赋值返回函数以在主函数中应用

        }

        g_bAntiShakeFlag = TRUE;

    }

    //reset long key time count

    if (u8keyPressed != KEY_NONE)

    {

        g_u8keyTimes = 0;

    }

#if 1 //if support long key

    // key1 long pressed sample

if ((g_u8keyCount & KEY_SWITCH1) == 0 )     //这是按键长按时有上面计算后得到g_u8keyCount此时为0xfe,所以满足if条件

    {

        g_u8keyTimes ++;                         //进入低电平后开始计时

        if (g_u8keyTimes > KEY_RESCAN_LONG)       //当计时满足所设要求后进入

        {

            u8keyPressed = KEY_MAP_LONG1;        //赋长按变量返回函数后应用

            g_u8keyTimes = 0;                     //将计时清零

            g_bAntiShakeFlag = FALSE;

        }

    }

#endif

    

    return u8keyPressed;

}

下图是对按键动作过程的解析:

点击获取更多相关MS8006(F)驱动代码信息

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值