//长按开关机,短按切换功能
//开机状态下,短接按才有效
//长按时间到,不需松手就动作,便开观察开关机,短按松手动作
//按键去抖动
//关机状态下,5S内自动睡眠,按键唤醒
bit B_1ms=0;
u16 T_5s=0;
#define Const_Key_Jitter 40 //抖动计数
#define Const_Key_Long 1000 //长按1秒
u16 INT1_Cnt=0;
bit Short_Click=0;
bit Long_Click=0;
bit INT1_Lock=0;
bit Power_On=0;
/*******************************************************
当短按有效时,继续计数,满足长按条件自锁
松手解锁
短按为松手后判断
长按不需要松手就有效
*******************************************************/
void Key_Scan()
{
if(INT1==1)
{
INT1_Cnt=0; //按下计数清0
if(INT1_Lock==1) //长按锁标志
{
INT1_Lock=0;
}
else if (Short_Click==1&&(Power_On==1)) //短按标志且电源开启
{
Short_Click=0;
BLUE=~BLUE;
}
}
else if(INT1_Lock==0) //有键按下,且自锁标志为0,即第一次按下
{
INT1_Cnt++;
if(INT1_Cnt>=Const_Key_Jitter)
{
Short_Click=1; //短按有效标志
}
if(INT1_Cnt>=Const_Key_Long) //说明是长按,开自锁
{
INT1_Lock=1; //长按锁住
//INT1_Cnt=0;
Short_Click=0;
Power_On=~Power_On;
RED=~RED;
}
}
}
void main( )
{
GPIO_Inilize();
Timer0_Inilize();
Exti_Inilize();
TR0=1;
EA=1;
while(1)
{
if(B_1ms==1)
{
B_1ms=0;
if(++T_5s>=5000)
{
T_5s=0;
if(INT1&&(Power_On==0))
{
TR0=0;
BLUE=0;
RED=0;
INT1_Clear(); //清标志
INT1_Enable(); //使能按键中断,用于唤醒
MCU_POWER_DOWN(); //进入睡眠
NOP7();
}
}
Key_Scan();
}
}
}
/********************* Timer0中断函数************************/
void timer0_int (void) interrupt TIMER0_VECTOR
{
TF0=0;
B_1ms=1;
}
void Ext_INT1 (void) interrupt INT1_VECTOR //进中断时已经清除标志
{
INT1_Disable(); //关闭按键中断使能
TR0=1;
}
原文:https://www.cnblogs.com/Zyj1739/p/14894874.html