/******************************************************************************
  * mc32p8141 TouchDemo_MC32P8141_1Key程序
  * 说明：
  * 1.可实现1键触控
  * 2.连接引脚到TK焊盘上，通过手触摸，对应的LED会点亮
  * 3.模拟串口打印TK数据功能
  *	   	客户可通过外接串口工具，使能串口函数Uart_Process()，把TK数据打印出来分析
  ******************************************************************************
  * 几个特殊指令用法
  *	   	stop指令： Stop();
  *	   	清狗指令： Clrwdt();
  *	   	空指令：   	 Nop();
  ******************************************************************************
  * 仿真软件版本
  *	   	WinScopeIDE_Beta_v1.14.11_20200302
  *	
 ******************************************************************************/
#include "mc32p8141.h"

//引脚定义
#define  RXD           	P03D
#define  TXD     	     	P02D
#define  Key     	     	P04D
#define  BUZZUR      	  P05D
#define  LED            P17D
//触控端口控制器
#define TKN0_OE            P16OE 
#define TKN1_OE            P15OE
#define TKN2_OE            P14OE
#define TKN3_OE            P13OE
#define TKN4_OE            P12OE
#define TKN5_OE            P11OE
#define TKN6_OE            P10OE
#define TKN7_OE            P05OE

#define TKN0_ADCR            P16DC 
#define TKN1_ADCR            P15DC
#define TKN2_ADCR            P14DC
#define TKN3_ADCR            P13DC
#define TKN4_ADCR            P12DC
#define TKN5_ADCR            P11DC
#define TKN6_ADCR            P10DC
#define TKN7_ADCR            P05DC

//寄存器定义
uchar      	   	ABuf,StatusBuf;
                   	
uint       	   	TK_Value;	//采样数据原始值
uint       	   	TK_BaseSamples;	//触摸键基准值
uchar	 	 	 	 	 	TK_BaseSamples_Time;//触摸键基准采样次数
uint       	   	TK_Value_Filter;//采样数据和基准值的差值
uint       	   	TK_BaseSamples_Buf;
uchar	 	 	 	 	 	TK_Value_H;//采样数据高8位
uchar	 	 	 	 	 	TK_Value_L;//采样数据低8位
uchar  	   	   	TK_BaseSamples_H;//基准数据高8位         	   	   	
uchar  	   	   	TK_BaseSamples_L;//基准数据低8位

uchar	 	 	 	 	 	TK_BaseSamples_Cnt;
uchar	 	 	 	 	 	mode,TK_Value_Difference;
uint 	 	 	 	 	 	Cnt_3s,TK_Value_Temp;
typedef union{
unsigned char byte;
struct{
           	unsigned char bit0:1;
           	unsigned char bit1:1;
           	unsigned char bit2:1;
           	unsigned char bit3:1;
           	unsigned char bit4:1;
           	unsigned char bit5:1;
           	unsigned char bit6:1;
           	unsigned char bit7:1;
}bits;
}flag;

flag Flag_Touch;

#define        	Flag_Touch_Read	   	   	   	Flag_Touch.bits.bit0
#define        	F_Stop 	   	   	   	 	 	 	 	Flag_Touch.bits.bit1
#define        	F_3s 	   	   	   	 	 	 	 	 	Flag_Touch.bits.bit2
#define	 	 	 	 	F_TK_Weakup_Updata 	 	 	 	 	Flag_Touch.bits.bit3



           


#define TK_BaseSamples_perscan 	 	 	 	 	4  	//基准值更新次数
#define  off   	   	   	   	   	   	   	0
#define  on    	   	   	   	   	   	   	1
#define	 TK_Channel	 	 	 	 	 	 	 	 	 	 	1	 	//通道1
#define	 TK_Threshold_Channel_Stop 	 	 	10
#define	 TK_Threshold_Channel_Normal 	 	100
/************************************************
函数名:初始化RAM
说明:
************************************************/
void  Clr_Ram(void)
{
   	__asm
ClrRam:
       	movai  	0x7F
       	movra  	FSR0
ClrRam_Loop:
       	clrr   	INDF0
       	djzr    FSR0
   	   	goto   	ClrRam_Loop
   	   	clrr   	INDF0      	   	
    __endasm;
} 
/************************************************
函数名:初始化函数
说明:
************************************************/
void  Init_Sys(void)
{  	  
 	 	   	
//========= Io初始化 ==============
        OEP0=0xff;
        OEP1=0xff;
        
   	   	IOP0=0x00;
   	   	IOP1=0x00;
   	   	
   	   	PUP0=0x00;
   	   	PUP1=0x00;
   	   	PDP0=0;
   	   	PDP1=0;
//========= TK通道配置 ==============
#if  	TK_Channel == 0
 	 	 	TKN0_OE=0;TKN0_ADCR=1;
#elif TK_Channel == 1
 	 	 	TKN1_OE=0;TKN1_ADCR=1;
#elif TK_Channel == 2
 	 	 	TKN2_OE=0;TKN2_ADCR=1;
#elif TK_Channel == 3
 	 	 	TKN3_OE=0;TKN3_ADCR=1;
#elif TK_Channel == 4
 	 	 	TKN4_OE=0;TKN4_ADCR=1;
#elif TK_Channel == 5
 	 	 	TKN5_OE=0;TKN5_ADCR=1;
#elif TK_Channel == 6
 	 	 	TKN6_OE=0;TKN6_ADCR=1;
#elif TK_Channel == 7
 	 	 	TKN7_OE=0;TKN7_ADCR=1;
#endif   	   


} 
    
/************************************************
函数名:定时器初始化
说明:
************************************************/
void  Init_timer(void)
{  	
 
 	 	T1CR=0x03;
 	 	T1CNT=250;
 	 	T1LOAD=250;
 	 	T0LOADH=0Xf0;	 	
 	 	T0LOADL=0X7F;	 	//32MS
 	 	TKCR0=0X18;	 	//跳频模式
 	 	TKCR1=0X80;	 	   
 	 	TKCR1=TKCR1&0xf8;
 	 	TKCR1=TKCR1+TK_Channel;    	 	  
 	 	T0IE=1;
 	 	T1IE=1;
 	 	T1EN=1;
 	 	GIE= 1;    	   	//开总中断     	   	       	    
}

/************************************************
函数名: 	Stop_Deal()
说明:	 	 	
************************************************/
void 	Stop_Deal()
{
 	 	if(F_Stop&&mode==0)
 	 	{
 	 	 	 	TKCON=0;
   	   	TKCNTH=0;
   	   	TKCNTL=0;
 	 	 	 	T0EN=0;
 	 	 	 	TKEN=0;
 	 	 	 	Nop();
 	 	 	 	Nop();
 	 	 	 	Nop();
 	 	 	 	TXD=0;
 	 	 	 	Stop();
 	 	 	 	TXD=1;
 	 	 	 	Nop();
 	 	 	 	Nop();
 	 	 	 	Nop();
 	 	 	 	F_Stop=0;
 	 	 	 	T0CR=0x4A;
 	 	 	 	T0CNTH=0Xf0; 
 	 	 	 	T0CNTL=0Xff;
 	 	 	 	T0LOADH=0Xf0;	 	
 	 	 	 	T0LOADL=0Xff;
 	 	 	 	TKEN=1;
 	 	 	 	TKCON=1; 
   	   	T0EN=1;
 	 	}
 	 	else
 	 	{
 	 	 	 	if(Flag_Touch_Read)
 	 	 	 	{
 	 	 	 	 	 	Flag_Touch_Read=0;
 	 	 	 	 	 	if(F_TK_Weakup_Updata)
 	 	 	 	 	 	{
 	 	 	 	 	 	 	 	F_TK_Weakup_Updata=0;
 	 	 	 	 	 	 	 	TK_Value_Temp=TK_Value;
 	 	 	 	 	 	 	 	F_Stop=1;
 	 	 	 	 	 	}
     	 	 	 	else
     	 	 	 	{
     	 	 	 	 	 	if(TK_Value_Temp>TK_Value)
     	 	 	 	 	 	{
     	 	 	 	 	 	 	 	TK_Value_Difference=TK_Value_Temp-TK_Value;
     	 	 	 	 	 	 	 	if(TK_Value_Difference>TK_Threshold_Channel_Stop)
     	 	 	 	 	 	 	 	{
     	 	 	 	 	 	 	 	 	 	F_Stop=0;
     	 	 	 	 	 	 	 	 	 	mode=1;
     	 	 	 	 	 	 	 	 	 	Cnt_3s=0;
     	 	 	 	 	 	 	 	 	 	F_3s=0;
 	 	 	 	 	 	 	 	 	 	 	 	TKCON=0;
 	 	 	 	 	 	 	 	 	 	 	 	TK_Value=0;
 	 	 	 	 	 	 	 	 	 	 	 	T0CNTH=0;
 	 	 	 	 	 	 	 	 	 	 	 	T0CNTL=0;
 	 	 	 	 	 	 	 	 	 	 	 	T0EN=0;
 	 	 	 	 	 	 	 	 	 	 	 	T0CR=0x44;
 	 	 	 	 	 	 	 	 	 	 	 	T0CNTH=0Xf0;
 	 	 	 	 	 	 	 	 	 	 	 	T0CNTL=0Xff;
 	 	 	 	 	 	 	 	 	 	 	 	T0LOADH=0Xf0;	 	
 	 	 	 	 	 	 	 	 	 	 	 	T0LOADL=0Xff;
 	 	 	 	 	 	 	 	 	 	 	 	TKCON=1;
 	 	 	 	 	 	 	 	 	 	 	 	T0EN=1;
     	 	 	 	 	 	 	 	}
     	 	 	 	 	 	 	 	else
     	 	 	 	 	 	 	 	{
     	 	 	 	 	 	 	 	 	 	F_Stop=1;
     	 	 	 	 	 	 	 	 	 	TK_Value_Temp=TK_Value;
     	 	 	 	 	 	 	 	}
     	 	 	 	 	 	}
     	 	 	 	 	 	else
     	 	 	 	 	 	{
     	 	 	 	 	 	 	 	F_Stop=1;
     	 	 	 	 	 	 	 	TK_Value_Temp=TK_Value;
     	 	 	 	 	 	}
     	 	 	 	}
     	 	 	 	
     	 	}
    }
}
 	 	
/************************************************
函数名: 触摸按键处理
说明: 
************************************************/ 
void Touch_Value_Deal()
{
   	if(Flag_Touch_Read)
   	{
   	   	Flag_Touch_Read=0;
 	 	 	//基准值更新  	
   	   	if(++TK_BaseSamples_Cnt>10)//平均每10次转换取一次基准采样值，可调
   	   	{
   	   	   	TK_BaseSamples_Cnt=0;
   	   	   	TK_BaseSamples_Buf=TK_Value+TK_BaseSamples_Buf;
   	   	   	if(++TK_BaseSamples_Time>=TK_BaseSamples_perscan)
   	   	   	{
   	   	   	   	TK_BaseSamples_Time=0;
   	   	   	   	TK_BaseSamples=TK_BaseSamples_Buf>>2;
   	   	   	   	TK_BaseSamples_H=TK_BaseSamples>>2;
   	   	   	   	TK_BaseSamples_L=TK_BaseSamples<<2;
   	   	   	   	TK_BaseSamples_Buf=0;
   	   	   	}
   	   	}
   	   	
   	   	
   	  //采样值与基准值做比较 	 	
 	 	 	 	if(TK_Value<TK_BaseSamples)
   	   	{
   	   	 	 	
   	   	   	TK_Value_Filter=TK_BaseSamples-TK_Value;
   	   	   	if(TK_Value_Filter>TK_Threshold_Channel_Normal)
   	   	   	{
 	 	 	 	 	 	 	 	Cnt_3s=0;
   	   	 	 	 	 	F_3s=0;
   	   	   	   	LED=on;
   	   	   	}
   	   	   	
   	   	}
   	   	else
   	   	{  	
   	   	 	 	LED=off;
   	   	 	 	if(F_3s)
   	   	 	 	{
   	   	 	 	 	 	F_3s=0;
   	   	 	 	 	 	F_Stop=1;
   	   	 	 	 	 	mode=0;
 	 	 	 	 	 	 	 	TK_Value=0;
 	 	 	 	 	 	 	 	F_TK_Weakup_Updata=1;
   	   	 	 	}
   	   	}
   	   	
 	 	 	//新一轮检测
 	 	 	 	if(mode==1)
 	 	 	 	{
   	   	 	 	TKCON=0;
   	   	 	 	TKCNTH=0;
   	   	 	 	TKCNTL=0;	//注意一定要手动清掉TK值，软件不会自动清
   	   	 	 	TKCON=1; 
   	   	 	 	T0EN=1;  //重新开启新的TK采集
   	   	}
   	   	
   	}  	   	
  
   	
}          	
/************************************************
函数名:主函数
说明:
************************************************/
void main()
{      	     
 	 	Clr_Ram();            
 	 	Init_Sys();
 	 	Init_timer();
 	 	F_Stop=1;
 	 	F_TK_Weakup_Updata=1;
 	 	while(1) 
 	 	{      	
 	 	   	if(mode==0)
 	 	   	{
 	 	   	 	 	Stop_Deal();
 	 	   	}
 	 	   	else 	
 	 	   	{
 	 	   	 	 	Touch_Value_Deal();
 	 	   	}
 	 	 	 	ClrWdt();
 	 	}
}
   	       	       	       	       	       	


/************************************************
函数名:中断程序
说明:
************************************************/
void int_isr(void) __interrupt
{
       	__asm
       	       	movra   _ABuf
       	       	swapar  PFLAG
       	       	movra   _StatusBuf
       	__endasm;
//========= T0/T1中断 ==============     	
       	if(T0IF)
       	{      	       	
       	   	T0IF   = 0;    
   	   	   	TK_Value_H=TKCNTH;   
       	   	TK_Value_L=TKCNTL; 	 
       	   	TK_Value= TK_Value_H;
       	   	TK_Value=TK_Value<<8;
       	   	TK_Value=TK_Value+TK_Value_L; 
       	   	if(mode) 
       	   	{
   	   	   	 	 	TK_Value=TK_Value>>4;    	
   	   	   	}
   	   	   	else
   	   	   	{
   	   	   	 	 	TK_Value=TK_Value>>2;
   	   	   	}   
       	   	Flag_Touch_Read=1;    
   	   	   	       	
       	}
   	   	if(TKIF)
   	   	{
   	   	   	TKIF=0;
   	   	}
       	if(ADIF)
       	{      	       	
       	   	ADIF  = 0;             	       	
       	} 
       	if(T1IF&&T1IE)
       	{
       	 	 	T1IF=0;
       	 	 	Cnt_3s++;
       	 	 	if(Cnt_3s>3000)
       	 	 	{
       	 	 	 	 	Cnt_3s=0;
       	 	 	 	 	F_3s=1;
       	 	 	}
       	}   
       	 	 	     	

       	__asm
       	       	swapar  _StatusBuf
       	       	movra   PFLAG
       	       	swapr   _ABuf
       	       	swapar  _ABuf
       	__endasm;
}