功能:单键操作 长按开关机;开机状态下,短按切换闪烁频率5Hz 8Hz,红蓝灯双闪
闪烁方式:红单闪5次----蓝单闪5次----红蓝同闪5次
1MS扫描
bit B_1ms=0;
u16 T_2s=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;
u8 key_num=0;
bit key_Flag=0;
#define Const_Flash_5Hz_On 100 // 100ms
#define Const_Flash_5Hz_Off 100 // 100ms
#define Const_Flash_8Hz_On 62 // 62ms
#define Const_Flash_8Hz_Off 63 // 63ms
#define Flash_Times 5 //闪5次
u8 Temp_On; //用于数据缓存
u8 Temp_On_Times;
u8 Temp_Off;
u8 Temp_Off_Times;
u8 Temp_Times;
bit FLone,FLtwo,Plon;
/*******************************************************
当短按有效时,继续计数,满足长按条件自锁
松手解锁
短按为松手后判断
长按不需要松手就有效
*******************************************************/
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;
key_Flag=1;
}
}
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; //长按锁住
Short_Click=0;
Power_On=~Power_On; //长按开关机
}
}
}
/*******************************************************
当短按有效时,根据键值,切换频率
*******************************************************/
void KEY_Result()
{
if(key_Flag)
{
key_Flag=0;
key_num++;
if(key_num>=2)key_num=0;
switch(key_num)
{
case 0:
Temp_On_Times=Const_Flash_5Hz_On;
Temp_Off_Times=Const_Flash_5Hz_Off;
Temp_Times=Flash_Times;
break;
case 1:
Temp_On_Times=Const_Flash_8Hz_On;
Temp_Off_Times=Const_Flash_8Hz_Off;
Temp_Times=Flash_Times;
break;
}
}
}
/*******************************************************************
标志法写闪烁循环
1、长按开机进入闪烁频率为5Hz:红闪5次,蓝闪5次,红蓝同闪5次
2、短按改变闪烁频率,即在5Hz、8Hz之间切换
3、长按关机,并进入睡眠状态
********************************************************************/
void RED_Flash()
{
if((Power_On)&&(FLone==0)&&(FLtwo==0))
{
if(Plon==0)
{
RED=1;
if((Temp_On--)==0)
{
Temp_On=Temp_On_Times;
Plon=1;
}
}
else
{
RED=0;
if((Temp_Off--)==0)
{
Temp_Off=Temp_Off_Times;
Plon=0;
if((Temp_Times--)==0)
{
Temp_Times=Flash_Times;
FLone=1;
}
}
}
}
}
void BLUE_Flash()
{
if((Power_On)&&(FLone==1)&&(FLtwo==0))
{
if(Plon==0)
{
BLUE=1;
if((Temp_On--)==0)
{
Temp_On=Temp_On_Times;
Plon=1;
}
}
else
{
BLUE=0;
if((Temp_Off--)==0)
{
Temp_Off=Temp_Off_Times;
Plon=0;
if((Temp_Times--)==0)
{
Temp_Times=Flash_Times;
FLtwo=1;
}
}
}
}
}
void ALL_Flash()
{
if((Power_On)&&(FLtwo==1))
{
if(Plon==0)
{
BLUE=1;
RED=1;
if((Temp_On--)==0)
{
Temp_On=Temp_On_Times;
Plon=1;
}
}
else
{
BLUE=0;
RED=0;
if((Temp_Off--)==0)
{
Temp_Off=Temp_Off_Times;
Plon=0;
if((Temp_Times--)==0)
{
Temp_Times=Flash_Times;
FLone=0;
FLtwo=0;
}
}
}
}
}
void main( )
{
GPIO_Inilize();
Timer0_Inilize();
Exti_Inilize();
Temp_On_Times=Const_Flash_5Hz_On;
Temp_On=Temp_On_Times;
Temp_Off_Times=Const_Flash_5Hz_Off;
Temp_Off=Temp_Off_Times;
Temp_Times=Flash_Times;
delay_ms(5);
TR0=1;
EA=1;
while(1)
{
if(B_1ms==1)
{
B_1ms=0;
if(++T_2s>=2000)
{
T_2s=0;
if(INT1&&(Power_On==0))
{
TR0=0;
BLUE=0;
RED=0;
INT1_Clear(); //清标志 IE1=0
INT1_Enable(); //使能按键中断EX1=1,用于唤醒
MCU_POWER_DOWN(); //进入睡眠 PCON |= 2
NOP7();
}
}
Key_Scan();
RED_Flash();
BLUE_Flash();
ALL_Flash();
}
KEY_Result();
}
}
/********************* Timer0中断函数************************/
void timer0_int (void) interrupt TIMER0_VECTOR
{
TF0=0;
B_1ms=1;
}
void Ext_INT1 (void) interrupt INT1_VECTOR //进中断时已经清除标志
{
INT1_Disable(); //关闭按键中断使能 EX1=0
TR0=1;
}