经典按键检测程序(二)--带长按检测

/*************************************
// 函数名称: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 ;		
	}	
}


 

原文地址:https://www.cnblogs.com/jiangu66/p/3212470.html