按键扫描函数,松手检测

首先说明一下我这个按键扫描函数的作用,我要实现的是长按按键就关闭MCU所有外设,即进入睡眠模式,睡眠之后可以使用这个按键进行唤醒MCU,那么这里就要考虑一个误唤醒的问题,所以思路是长按之后进行一个假睡眠(我这里的表现就是关闭小灯),松手之后才会真正意义上的执行睡眠指令,开启中断,进入睡眠模式。

对于准确的应用按键,那么首先要了解按键的几种状态:

①刚开始都是松开的;

②使用时由松开到按下;

③一直按下不松开;这里还涉及到是否要连续有效还是单次有效;

④由按下到松开;

⑤一直松开;

首先说明几个变量的作用:

1、Release_cnt:松手之后或者没有按下按键进行累加,用以按下按键松手之后的消抖;

2、Presse_cnt:按键按下进行累加,消抖作用;

3、Key1_Flag:按键按下标志,设置按键状态,防止重复触发的作用;

4、Key1_Pressed:标志位,为1表示按键确认按下了;

5、Key1_Function:也是一个标志位,为1去执行相应的操作;

6、Key1_Released:标志位:为1表示按键按下有效并且确认松手了;

下面是一个大概的流程图; 

下面是具体的按键扫描函数,长按关机,松手有效,单次触发; 

void KeyScan(void)
{
    //单纯短按按键
    if(!KEY1)
    {
        Release_cnt = 0;
        if(!Key1_Flag)
        {
            Presse_cnt++;
            if(Presse_cnt >= 1000)		//1s长按防抖
            {
                Key1_Flag = 1;			//设置按键状态,防止重复触发
                Key1_Pressed = 1;
                Key1_Function = 1;
            }
        }
    }
    else
    {
        if(Key1_Pressed)
        {
            Release_cnt++;
            if(Release_cnt >= 50)		//50ms释放防抖
            {
                Key1_Pressed = 0;
                Key1_Released = 1;
            }
        }
        Presse_cnt = 0;
        Key1_Flag = 0;
    }
}

下面是主函数里的while循环,Key1_Function这个标志长按不松手就置1,现象就是P20引脚电平拉高,熄灭小灯;松手之后Key1_Released置1,就开启中断进入睡眠;

 while (1)
    {
        delay_ms(1);

        KeyScan();
        if(Key1_Function)
        {
            Key1_Function = 0;
            printf("Sleep Ready.\r\n");
            P20 = 1;    //LED OFF(关闭外设,准备进入休眠)
        }
        if(Key1_Released)
        {
            Key1_Released = 0;
            printf("MCU Sleep.\r\n");

            IE0  = 0;   //外中断0标志位
            EX0 = 1;    //INT0 Enable

            IT0 = 1;        //INT0 下降沿中断       
        //  IT0 = 0;        //INT0 上升,下降沿中断  

            _nop_();
            _nop_();
            PCON |= 0x02;   //Sleep
            _nop_();
            _nop_();
            _nop_();
            _nop_();
            _nop_();
            _nop_();
            _nop_();
            printf("MCU Wakeup.\r\n");
            P20 = 0;    //LED ON
        }
    }

最后注意嗷,相应的判断标志在进入之后一定要清0。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值