📄 key.c
字号:
#include <pic.h>
#define AN_XD_DL 2 //按键消抖常数 消抖时间(初按响应时间)大约2*10ms
#define AN_CJ_DL 200 //按键长按计数器,长按响应时间为200*10ms
#define AN_LJ_DL 15 //按键连按计数,连按响应时间为 15*10ms
struct clock{unsigned int h;
unsigned int m;
unsigned int s;
};
struct clock real_clk={12,0,0};
unsigned char clkstr[6];
unsigned char Key_Scan_F; //为了使得10ms能扫描一次,其他时间可以不用扫描 为1表示可以扫描 为0表示扫描过了
unsigned char Key_Num=0x00; //本次按键码
unsigned char Key_Backup=0x00; //备用键 用于消抖
unsigned char Key_JSQ; //按键闭合计数器 用于长按
unsigned char Key_Delay; //按键响应延时时间 用于连按
unsigned char NOKEY_JSQ; //无键计时器 (每1s加一)
unsigned char Key_Dis_F=0; //键处理结束 1表示禁止响应 0 可以响应
unsigned char power_btn_long;
unsigned char power_btn_short;
unsigned char alarm_btn_long;
unsigned char alarm_btn_short;
unsigned char timer_btn_short;
unsigned char _12_to_24;
unsigned char set_clock_F;
unsigned char demo_mode_F;
void no_key_deal(void)
{
if(++NOKEY_JSQ==20)
SLEEP();//如果20s每按键,进入休眠
}
unsigned char key_scan()
{
PORTC=PORTC;
PORTC=PORTC&0XF8;
switch(PORTC)
{
case 0xF0:
return 1; //POERN_BTN
case 0xB8:
return 2; //Alarm_btn
case 0x78:
return 3; //Timer_btn
case 0xE8:
return 4; //Up_btn
case 0xD8:
return 5; //Down_btn
case 0x58:
return 6; //12to24
case 0x38:
return 7; //Setclock
case 0xE0:
return 8; //demo_mode
default :
return 0;
}
}
void Key_DJ_Deal(void)//按键短击处理
{
switch(Key_Backup)
{
case 1:
power_btn_long=0;
power_btn_short++;//短按一次
if(power_btn_short==2)
power_btn_short=0;
break;
case 2:
alarm_btn_long=0;
alarm_btn_short++;
if(alarm_btn_short==3)
alarm_btn_short=0;
break;
case 3:
timer_btn_short++;
if(timer_btn_short==2)
timer_btn_short=0;
break;
default:
break;
}
}
void Key_CJ_Deal(void)//按键长击处理
{
switch(Key_Num)
{
case 1:
power_btn_long=1;
break;
case 2:
alarm_btn_short=1;
break;
case 6:
_12_to_24++;
if(_12_to_24==2)//
_12_to_24=0;
break;
case 7:
set_clock_F=1;
break;
case 8:
demo_mode_F=1;
default:
break;
}
}
void Key_LJ_Deal(void)//按键连击处理
{
switch(Key_Num)
{
case 4:
if(alarm_btn_short==2)
clock_plus(alarm_clk);
else if(set_clock_F==1)
clock_plus(real_clk);
break;
case 5:
if(alarm_btn_short==2)
clock_sub(alarm_clk);
else if(set_clock_F==1)
clock_sub(real_clk);
break;
default:
LJ_Dis_F=1;
break;
}
}
void key_process()
{
if(Key_Scan_F==1)
{
Key_Scan_F=0;
Key_Num=key_scan();
if(Key_Num!=0x00)//有键按下
{
if(Key_Num==Key_Backup) //Key_Backup初始化为0,此句用来判别是不是去抖动的第一次按键
{
NOKEY_JSQ=0; //表示有键按下,休眠计数器重新计时
if(Key_Dis_F==0)
{
if((--Key_Delay==0) && (LJ_Dis_F==0))
{
Key_Delay=AN_LJ_DL;
Key_LJ_Deal();
}
else if(++Key_JSQ==AN_CJ_DL)//连击和长击不可能共存(UP和DOWN键才有连击)
{
Key_CJ_Deal();
Key_JSQ=0;
Key_Dis_F=1;
}
}
}
else
{
Key_Backup=Key_Num;//第一次按下时的初始化
Key_Dis_F=0;
LJ_Dis_F=0;
Key_Delay=AN_XD_DL;
Key_JSQ=0;
}
}
else
{
if((Key_Dis_F==0) && (Key_JSQ>=AN_XD_DL) && (Key_JSQ<AN_CJ_DL)) //(LJ CJ)弹起或无按键
{
Key_DJ_Deal();
Key_JSQ=0;
Key_Dis_F=1;
}
Key_Backup=Key_Num;
Key_Dis_F=0;
}
}
}
void clock_plus(struct clock clk)//判断是12小时制还是24小时制
{
if(++clk.s==60)
{
clk.s=0;
if(++clk.m==60)
{
clk.m=0;
if(_12_to_24==1)
{
if(++clk.h==24)
clk.h=0;
}
else
{
if(++clk.h==12)
clk.h=0;
}
}
}
}
void clocksub(struct clock clk)//要判断是12小时制还是24小时制
{
if(--clk.s==0)
{
clk.s=60;
if(--clk.m==0)
{
clk.m=60;
if(_12_to_24==1)
{
if(--clk.h==0)
clk.h=24;
}
else
{
if(++clk.h==0)
clk.h==12;
}
}
}
}
void update_clockstr(struct clock clk)
{
clkstr[0]=(int)(clk.h/10);
clkstr[1]= clk.h%10;
clkstr[2]=(int)(clk.m/10);
clkstr[3]=clk.m%10;
clkstr[4]=(int)(clk.s/10);
clkstr[5]=clk.s%10;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -