/*************************************
// 函数名称:CheckKey
// 函数功能:按 键 检测程序
备注:本例是波两次的程序 需滤波三次或三次以上请参考被屏蔽的代码
程序的用法:每隔10MS 调用一次这个程序即可
uint8 KLST 上次按键的状态
uint8 KNOW 本次按键的状态
uint8 KSTBL 经滤波后的上次按键的状态
uint8 KSTB 经滤波后的本次按键的状态
uint8 KAVLP 按键抬起有效结果寄存器
uint8 KAVL 按键按下有效结果寄存器
本检测程序的典型应用:定时器,万年历
***************************************/
#define K_UP 0x01 //加键
#define K_DOMN 0x02 //减键
#define V_KLOV1 100 //1S确认为长按
#define V_KLOV2 20 //200MS置一次按键确认标志
void CheckKey(void)
{
uint8 KTmp1 = 0,KTmp2 = 0 ;
uint8 KeyStatu = 0;
if(P_K1 == 0) //读IO1状态 1有效
{
KeyStatu |= 0X01;
}
if(P_K2 == 0) //读IO2状态 1有效
{
KeyStatu |= 0X02 ;
}
if(P_K3 == 0) //读IO3状态 1有效
{
KeyStatu |= 0X04 ;
}
.
.
.
if(P_K8 == 0) //读IO8状态 1有效 总共一次性检测8个按键
{
KeyStatu |= 0X80 ;
}
KLST = KNOW ; //保存上次按键状态
KNOW = KeyStatu ; //保存当前按键状态
KTmp1 = (KNOW | KLST) ; //00 -> 0 取滤波值0
KTmp2 = (KNOW & KLST) ; //11 -> 1 取滤波值1
KSTBL = KSTB ; //保存上次经滤波后的值
KSTB &= KTmp1 ; //赋值当前经滤波后的值
KSTB |= KTmp2 ;
//去抖后的当前按键状态 1有效
// KAVLP = (KSTB ^ KSTBL) & KSTBL; //上升沿按下标志 获取1至0的状态
KAVL = (KSTB ^ KSTBL) & KSTB ; //下降沿按下标志 获取0至1的状态
//<<-- 长按检测 -->>
KTmp1 = KSTB & (K_UP | K_DOMN) ; //检测加、减键长按
if(KTmp1 != 0) //有键按下
{
if(!F_KLO)
{
if(--KLONG == 0) //长按1S确认是长按键
{
KLONG = V_KLOV2 ;
F_KLO = 1 ;
}
}
else
{
if(--KLONG == 0)
{
KLONG = V_KLOV2 ;
KAVL = KTmp1 ; //200MS置一次按键确认标志
}
}
}
else // 无长按
{
KLONG = V_KLOV1;
F_KLO = 0 ;
}
}