首页 > 代码库 > 单片机处理触摸按键例程

单片机处理触摸按键例程

//文件touchbutton.h

#ifndef _TOUCHBUTTON_H_
#define _TOUCHBUTTON_H_
//=========宏定义=========================================== 
#define		DEF_WATCH_TKREFER		//查看参考	-用于测试
        
		
		
//===========================================================		
		
		                
#define     V_REFER         1   //AD值超过此值 更新参考值

#define     V_PRESS         7   //AD值-参考 大于此值 认为按键按下-按键灵敏度

#define     VT_KTc         30   //更新参考值所需要的次数


//--------按键位置定义-----------
#define 	 K_TKON				SETB0  //ON/OFF
#define 	 K_TKBL				SETB1  //沸腾
#define 	 K_TKPU				SETB2  //水泵
#define 	 K_TKST				SETB3  //恒温设定


//#define	  	 V_TKQK1			(uint8)5   //快速加减时间 值


typedef	struct TCHBUT{

    uint8  KTc1 ;  //更新参考值确认时间
    uint8  KRefer1 ;  //按键1参考电压
    uint8  KTc2 ;  //更新参考值确认时间
    uint8  KRefer2 ;  //按键2参考电压
 /*   uint8  KTc3 ;  //更新参考值确认时间
    uint8  KRefer3 ;  //按键2参考电压
    uint8  KTc4 ;  //更新参考值确认时间
    uint8  KRefer4 ;  //按键2参考电压

    uint8  KTc5 ;  //更新参考值确认时间
    uint8  KRefer5 ;  //按键2参考电压
    uint8  KTc6 ;  //更新参考值确认时间
    uint8  KRefer6 ;  //按键2参考电压
    uint8  KTc7 ;  //更新参考值确认时间
    uint8  KRefer7 ;  //按键2参考电压
//    uint8  KTc8 ;  //更新参考值确认时间
//    uint8  KRefer8 ;  //按键2参考电压
*/
    uint8 KTVal1 ;
    uint8 KTVal2 ; 
//    uint8 KTVal3 ;
//    uint8 KTVal4 ; 
           
}tTCHBut ;
extern xdata tTCHBut tCHBut ;

#define		KTc1			tCHBut.KTc1
#define		KRefer1			tCHBut.KRefer1
#define		KTc2			tCHBut.KTc2
#define		KRefer2			tCHBut.KRefer2
#define		KTc3			tCHBut.KTc3
#define		KRefer3			tCHBut.KRefer3
#define		KTc4			tCHBut.KTc4
#define		KRefer4			tCHBut.KRefer4

#define		KTc5			tCHBut.KTc5
#define		KRefer5			tCHBut.KRefer5
#define		KTc6			tCHBut.KTc6
#define		KRefer6			tCHBut.KRefer6
#define		KTc7			tCHBut.KTc7
#define		KRefer7			tCHBut.KRefer7
//#define		KTc8			tCHBut.KTc8
//#define		KRefer8			tCHBut.KRefer8

#define		KTVal1			tCHBut.KTVal1
#define		KTVal2			tCHBut.KTVal2
#define		KTVal3			tCHBut.KTVal3
#define		KTVal4			tCHBut.KTVal4

//=======按键检测==============
typedef	struct BUTTON2{

		uint8		TKNOW ;  //当前几次按键的状态
		uint8		TKLST ;
//		uint8 	    TKLST1 ;		
//		uint8 	TKLST2 ;	
//		uint8 	TKLST3 ;	
		
		uint8		TKSTB ;  //去抖后按键状态
		uint8		TKSTBL ;	//上次 去抖后按键状态
		
		uint8		TKAVL ;   //下降沿有效值
		uint8		TKAVLP ;  //上升沿有效值
				
		uint8		TKeyStatu ;	//读按键的当前值
		
		uint8		TKLONG  ; //长按键计数
//		uint8		TTconQK ; //快速调节计数 111 555 10 10 10
}tButton2 ;
extern  tButton2 tKey2 ;

#define		TKNOW				tKey2.TKNOW
#define		TKLST				tKey2.TKLST
#define		TKLST1				tKey2.TKLST1
//#define		KLST2				tKey.TKLST2
//#define		KLST3				tKey.TKLST3
  
#define		TKSTB				tKey2.TKSTB
#define		TKSTBL				tKey2.TKSTBL

#define		TKAVL				tKey2.TKAVL
#define		TKAVLP				tKey2.TKAVLP

#define		TKeyStatu		tKey2.TKeyStatu

#define		TKLONG				tKey2.TKLONG
#define		TTconQK			tKey2.TTconQK

#define		 V_TKLOV1				200   //1S确认为长按
#define		 V_TKLOV2				20//15	//150MS置一次按键标志
 
//=========================================
typedef	struct KFlag2//按键处理标志位定义
{
		uint8 Flg1: 1 ;
		uint8 Flg2: 1 ;
		uint8 Flg3: 1 ;
		uint8 Flg4: 1 ;
		uint8 Flg5: 1 ;
		uint8 Flg6: 1 ;
		uint8 Flg7: 1 ;
		uint8 Flg8: 1 ;	
		
}tKFlg2 ;
extern tKFlg2 KF2 ;
//#define	  F_TRdKeyOK		  KF2.Flg1 //读按键有效
#define	  F_TKLO			  KF2.Flg2 //长按有效

//#define	  F_TKQK1			KF2.Flg4
//#define	  F_TKQK2			KF2.Flg5
#define	  F_TKEYOK			KF2.Flg6	


//===========================================


//================================
extern void ReadTKRefer(uint8 CH_AD,uint8 *a) ;

extern void CheckTouch1(void) ;
extern void CheckTouch2(void) ;

extern  void CheckTKey(void) ;


#endif

//文件touchbutton.c

#include "global.h"
#include "touchbutton.h"

//#include "touchbutton.h"
/***********************************************
触摸PWM 500K
当按按键时 电压值抬高 

***********************************************/

tButton2 tKey2 ;

tKFlg2 KF2 ;

xdata tTCHBut tCHBut ;


//#define		LKEY_ENB	//长按键使能
//***************************************
// 函数名称:ReadTKRefer
// 函数功能:读触摸按键参考
// 入口参数:CH_AD 按键AD通道 
// 出口参数:*a 对应该按键的AD参考值
//***************************************
void ReadTKRefer(uint8 CH_AD,uint8 *a)
{
	uint8	R_Save[3];
	uint8	R_Save2[3];		
	uint16 R_SaveSum = 0 ;
    uint8 Tcon = 0 ;
    uint8 Tmp1 ;
    uint8 i ;

    for(i=40;i>0;i--)
    {
        AdcSwitch(CH_AD) ;   //读按键1电压
        Tmp1 = ADDH ;
    
        RMov3Data_Byte(R_Save,Tmp1) ;			
    	Tmp1 = C3MidVal(R_Save); //处理位数最大3位  取中值处理

        RMov3Data_Byte(R_Save2,Tmp1) ;			
    	Tmp1 = C3MidVal(R_Save2); //处理位数最大3位  取中值处理
        	
        R_SaveSum += Tmp1 ;
    
        Tcon ++ ;
        if(Tcon >= (1<<3))
        {
            *a = R_SaveSum>>3 ; 
            Tcon = 0 ;
            R_SaveSum = 0 ;    
        }
    }
}
//***************************************
// 函数名称:CheckTouch1
// 函数功能:检测触摸按键
// 入口参数:无
// 出口参数:无
//***************************************
void CheckTouch1(void) 
{
    uint8 a[3];
    uint8 Tmp1 ;
    uint8 TmpAD ; //临时参考值

    AdcSwitch(V_ADCH_tch1) ;   //读按键电压
    a[0] = ADDH ;
    _nop_();_nop_();_nop_();_nop_();_nop_();
    AdcSwitch(V_ADCH_tch1) ;   //读按键电压
    a[1] = ADDH ;
    _nop_();_nop_();_nop_();_nop_();_nop_();
    AdcSwitch(V_ADCH_tch1) ;   //读按键电压
    a[2] = ADDH ;

   //----以下为三次AD值的取中间值处理-----
    TmpAD = C3MidVal(a) ;

#ifdef	DEF_WATCH_TKREFER
    KTVal1 = TmpAD ;  //当前按键AD值 -- 用于测试   ^^^^^^^^^^^^^^^^^^^^
#endif
    if(!(TKSTB & SETB0)) //此按键此时处于抬起状态 --更改参考值
    {
        if(TmpAD < KRefer1)
        {
            Tmp1 = KRefer1 - TmpAD ;
        }
        else
        {
            Tmp1 = TmpAD - KRefer1 ;
        }
        
        if(Tmp1 >= V_REFER) //更新参考门槛值
        {
            KTc1 -- ;
            if(KTc1 == 0)
            {
                KTc1 = VT_KTc ;

                if(KRefer1 == TmpAD) //KRefer1 = TmpAD ; 
                {}
                else if(KRefer1 < TmpAD)
                {
                    KRefer1 ++ ;  //更新参考 每次加减1     
                }
                else
                {
                    KRefer1 -- ;
                }
                    
            }    
        }
        else
        {
            KTc1 = VT_KTc ;    
        }        
    }
    else //if(TKSTB & SETB0) //此按键此时处于被按下状态
    {
        KTc1 = VT_KTc ;
    }
    
    Tmp1 = KRefer1 + V_PRESS ;
    if(TmpAD >= Tmp1) //大于参考值的门槛 认为按下
    {
        TKeyStatu |= SETB0 ;
    }
    else
    {
        TKeyStatu &= ~SETB0 ;       
    }              
}
//***************************************
// 函数名称:CheckTouch2
// 函数功能:检测触摸按键
// 入口参数:无
// 出口参数:无
//***************************************
void CheckTouch2(void) 
{
    uint8 a[3];
    uint8 Tmp1 ;
    uint8 TmpAD ; //临时参考值

    AdcSwitch(V_ADCH_tch2) ;   //读按键电压
    a[0] = ADDH ;
    _nop_();_nop_();_nop_();_nop_();_nop_();
    AdcSwitch(V_ADCH_tch2) ;   //读按键电压
    a[1] = ADDH ;
    _nop_();_nop_();_nop_();_nop_();_nop_();
    AdcSwitch(V_ADCH_tch2) ;   //读按键电压
    a[2] = ADDH ;

   //----以下为三次AD值的取中间值处理-----
    TmpAD = C3MidVal(a) ;

#ifdef	DEF_WATCH_TKREFER
    KTVal2 = TmpAD ;  //当前按键AD值 -- 用于测试   ^^^^^^^^^^^^^^^^^^^^
#endif
    if(!(TKSTB & SETB1)) //此按键此时处于抬起状态 --更改参考值
    {
        if(TmpAD < KRefer2)
        {
            Tmp1 = KRefer2 - TmpAD ;
        }
        else
        {
            Tmp1 = TmpAD - KRefer2 ;
        }
        
        if(Tmp1 >= V_REFER) //更新参考门槛值
        {
            KTc2 -- ;
            if(KTc2 == 0)
            {
                KTc2 = VT_KTc ;
                if(KRefer2 == TmpAD) //KRefer1 = TmpAD ; 
                {}
                else if(KRefer2 < TmpAD)
                {
                    KRefer2 ++ ;  //更新参考 每次加减1     
                }
                else
                {
                    KRefer2 -- ;
                }     
            }    
        }
        else
        {
            KTc2 = VT_KTc ;    
        }        
    }
    else //if(TKSTB & SETB0) //此按键此时处于被按下状态
    {
        KTc2 = VT_KTc ;
    }
    
    Tmp1 = KRefer2 + V_PRESS ;
    if(TmpAD >= Tmp1) //大于参考值的门槛 认为按下
    {
        TKeyStatu |= SETB1 ;
    }
    else
    {
        TKeyStatu &= ~SETB1 ;       
    }              
}


//文件maic.c
//======简易例程===========

//*************************************
// 函数名称:Init_TKey
// 函数功能:读取触摸按键的参考值
// 入口参数:无
// 出口参数:无
//***************************************
void Init_TKey(void) //
{
    uint8 i ;

    for(i=250;i>0;i--) //等待约250MS 让触摸电压稳定
    {
        Nopt(250) ;
        Nopt(250) ;
        Nopt(250) ;
        Nopt(250) ;
        Nopt(250) ;
    }

    ReadTKRefer(V_ADCH_tch1,&KRefer1) ;
    ReadTKRefer(V_ADCH_tch2,&KRefer2) ;
    ReadTKRefer(V_ADCH_tch3,&KRefer3) ;
    ReadTKRefer(V_ADCH_tch4,&KRefer4) ;

}
//--------------------
void CmdTK1(void) 
{			
    if(!(TKAVL & K_TKON)) return ;
    TKAVL &= ~K_TKON ;

	//处理按键1按下程序
}
//--------------------
void CmdTK2(void) 
{			
    if(!(TKAVL & K_TKBL)) return ;
    TKAVL &= ~K_TKBL ;

	//处理按键2按下程序
}
//--------------------------------------
void main(void)
{

    Init_TKey() ; //上电读取触摸按键的参考值

	while(1)
	{
		if(F_20MS)	//20MS	跑一次
		{
			F_20MS = 0 ;


		    CheckTouch1() ; //检测按键1并更新参考值
		    CheckTouch2() ; //检测按键2并更新参考值

			CheckTKey() ;

			CmdTK1() ;  //处理按键1 
			CmdTK2() ;  //处理按键2

		}
		
	}

}


//电路参考如下 PAN2为AD检测口 此图为例,当有按键按下时,PAN2端口的电压会抬高




单片机处理触摸按键例程