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

/*
触控端口控制器
*/
#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

/*
触控指示灯，分别对应Touch Board的S1-S5
*/
#define LED1            P17D
#define LED2            P07D
#define LED3            P06D
#define LED4            P01D
#define LED5            P00D

/*
变量
*/
uchar      	   	ABuf,StatusBuf;                	
uint      	   	TK_Value;	//采样数据原始值
uint      	   	TK_BaseSamples[8];	//触摸键基准值
uint      	   	TK_BaseSamples_Buf[8];	
uchar      	   	TK_BaseSamples_Time[8];	//触摸键基准采样次数
uchar      	   	TK_Value_Filter[8];	//采样数据和基准值的差值
uchar      	   	TK_Channel_NUM;	//触控按键通道选择数

uchar      	   	TK_Value_H;	//采样数据高8位
uchar      	   	TK_Value_L;	//采样数据低8位
uchar  	   	   	TK_BaseSamples_H;	//基准数据高8位    	   	   	
uchar  	   	   	TK_BaseSamples_L;	//基准数据低8位



uchar      	   	i,j;
uchar      	   	DATA_Send,DATA_buf;
uchar      	   	R_Date_Length;//串口长度
uchar      	   	TK_BaseSamples_Cnt;

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_TK0   	   	   	   	Flag_Touch.bits.bit0
#define        	Flag_TK1   	   	   	   	Flag_Touch.bits.bit1
#define        	Flag_TK2   	   	   	   	Flag_Touch.bits.bit2
#define        	Flag_TK3   	   	   	   	Flag_Touch.bits.bit3
#define        	Flag_TK4   	   	   	   	Flag_Touch.bits.bit4
#define        	Flag_TK5   	   	   	   	Flag_Touch.bits.bit5
#define        	Flag_TK6   	   	   	   	Flag_Touch.bits.bit6
#define        	Flag_TK7   	   	   	   	Flag_Touch.bits.bit7

flag Flag_Touch_Func;
#define        	Flag_TK_Read					Flag_Touch_Func.bits.bit0


#define  off   	   	   	   	   	   	   	0
#define  on    	   	   	   	   	   	   	1

/*TK检测阈值选择*/
#define TK_Threshold_Channel0            75 //TK0检测阈值设置
#define TK_Threshold_Channel1            75 //TK1检测阈值设置
#define TK_Threshold_Channel2            75 //TK2检测阈值设置
#define TK_Threshold_Channel3            75 //TK3检测阈值设置
#define TK_Threshold_Channel4            75 //TK4检测阈值设置
#define TK_Threshold_Channel5            75 //TK5检测阈值设置
#define TK_Threshold_Channel6            75 //TK6检测阈值设置
#define TK_Threshold_Channel7            75 //TK7检测阈值设置

#define TK_BaseSamples_perscan	4	//基准值更新次数
/************************************************
函数名:	Init_Sys
说明:
************************************************/
void  Init_Sys(void)
{  	   	   	
//========= Io初始化 ==============
        OEP0=0xff;
        OEP1=0xC1;
        
   	   	IOP0=0x00;
   	   	IOP1=0x00;
   	   	
   	   	PUP0=0x00;
   	   	PUP1=0x00;
   	   	Flag_TK1=1;
   	   	PUP1=0;
   	   	PDP1=0;
//========= 寄存器初始化 ==============
   	   	   	   	TK_Value=0;
   	   	   	   	TK_Value_H=0;
   	   	   	   	TK_Value_L=0;
   	   	   	   	TK_Channel_NUM=1;
} 
/************************************************
函数名:	Clr_Ram
说明:
************************************************/
void  Clr_Ram(void)
{
   	__asm
ClrRam:
       	movai  	0x7F
       	movra  	FSR0
ClrRam_Loop:
       	clrr   	INDF0
       	djzr    FSR0
   	   	goto   	ClrRam_Loop
   	   	clrr   	INDF0      	   	
    __endasm;
}   
/************************************************
函数名:	Init_timer
说明:
************************************************/
void  Init_timer(void)
{
   	   	
   	   	T0CR=0x44;
   	   	T0CNTH=0Xf0;
   	   	T0CNTL=0X7F;
   	   	T0LOADH=0Xf0;
   	   	T0LOADL=0X7F;		//16MS
   	   	TKCR0=0XD8;
   	   	TKCR1=0X80;                	
   	   	TKCR1=TKCR1&0xf8;
   	   	TKCR1=TKCR1+TK_Channel_NUM;
       
   	   	T0IE=1;
   	   	T0EN=1;
        GIE     = 1;   	   	//1开总中断    	   	       	    
}
/************************************************
函数名:	UART_Deley
说明:	
************************************************/
void  UART_Deley(void)
{
   		for(j=0;j<18;j++)
   		{
   		   	Nop();
   		}
}

/************************************************
函数名:	UART_Send_Data
说明:	CPU=2M 9600波特率
************************************************/
void  UART_Send_Data(uchar DATA_buf)
{
   		P_Senddata=0;
   		UART_Deley();//起始位
   		for(i=0;i<8;i++)
   		{
   		DATA_Send=DATA_buf&0x01;
   		if(DATA_Send)
   		{
   		   	P_Senddata=1;
   		}
   		else 
   		{
   		   	P_Senddata=0;
   		}
   		DATA_buf=DATA_buf>>1;
   		UART_Deley();
   		}
   		P_Senddata=0;
   		UART_Deley();//结束位
   		P_Senddata=1;
   		UART_Deley();
}
 
/************************************************
函数名:	Uart_Process
说明: 
************************************************/ 
void Uart_Process()
{
		R_Date_Length=0x02;
		TK_Value_H=TK_Value>>8;
		TK_Value_L=TK_Value&0xff;
		UART_Send_Data(0x55);
		UART_Send_Data(R_Date_Length);
		UART_Send_Data(TK_Value_H); 
		UART_Send_Data(TK_Value_L);  
		UART_Send_Data(0xAA);
}  	

/************************************************
函数名: Touch_Value_Deal
说明: 
************************************************/ 
void Touch_Value_Deal()
{
	P03OE=1;
   	if(Flag_TK_Read)
   	{
   	   	Flag_TK_Read=0;
			//基准值更新
   	   	TK_BaseSamples_Cnt++;
   	   	if(TK_BaseSamples_Cnt<=8)//8个通道
   	   	{      	   	   	   	
   	   	   	TK_BaseSamples_Buf[TK_Channel_NUM]=TK_Value+TK_BaseSamples_Buf[TK_Channel_NUM];
   	   	   	if(++TK_BaseSamples_Time[TK_Channel_NUM]>=TK_BaseSamples_perscan)
   	   	   	{
   	   	   	   	TK_BaseSamples_Time[TK_Channel_NUM]=0;
   	   	   	   	TK_BaseSamples[TK_Channel_NUM]=TK_BaseSamples_Buf[TK_Channel_NUM]/TK_BaseSamples_perscan;
   	   	   	   	TK_BaseSamples_Buf[TK_Channel_NUM]=0;   	   	   	   	
   	   	   	}
   	   	}
   	   	else if(TK_BaseSamples_Cnt>=40)//应为通道个数的倍数
   	   	{
   	   			TK_BaseSamples_Cnt=0;
   	   	}  
   	   	
			//采样值与基准值做比较	   	
   	   	if(TK_Value<TK_BaseSamples[TK_Channel_NUM])
   	   	{
   	   	   	TK_Value_Filter[TK_Channel_NUM]=TK_BaseSamples[TK_Channel_NUM]-TK_Value;//基准值和采样值的差值
								if(TK_Channel_NUM==0)//TK0判断
								{
								   	if(TK_Value_Filter[0]>TK_Threshold_Channel0)
								   	   	Flag_TK0=1; 
								   	if(TK_Value_Filter[0]<20)
								   	   	Flag_TK0=0;    	
								}   	   	   	
   	   	   	   	else if(TK_Channel_NUM==1)//TK1判断
   	   	   	   	{
   	   	   	   	   	if(TK_Value_Filter[1]>TK_Threshold_Channel1)
   	   	   	   	   	   	Flag_TK1=1;
   	   	   	   	   	if(TK_Value_Filter[1]<20)
   	   	   	   	   	   	Flag_TK1=0;
   	   	   	   	} 
   	   	   	   	else if(TK_Channel_NUM==2)//TK2判断
   	   	   	   	{
   	   	   	   	   	if(TK_Value_Filter[2]>TK_Threshold_Channel2)
   	   	   	   	   	   	Flag_TK2=1;
   	   	   	   	   	if(TK_Value_Filter[2]<20)
   	   	   	   	   	   	Flag_TK2=0;
   	   	   	   	} 
   	   	   	   	else if(TK_Channel_NUM==3)//TK3判断
   	   	   	   	{
   	   	   	   	   	if(TK_Value_Filter[3]>TK_Threshold_Channel3)
   	   	   	   	   	   	Flag_TK3=1;
   	   	   	   	   	if(TK_Value_Filter[3]<20)
   	   	   	   	   	   	Flag_TK3=0;
   	   	   	   	}
   	   	   	   	else if(TK_Channel_NUM==4)//TK4判断
   	   	   	   	{
   	   	   	   	   	if(TK_Value_Filter[4]>TK_Threshold_Channel4)
   	   	   	   	   	   	Flag_TK4=1;
   	   	   	   	   	if(TK_Value_Filter[4]<20)
   	   	   	   	   	   	Flag_TK4=0;
   	   	   	   	}  	
   	   	   	   	else if(TK_Channel_NUM==5)//TK5判断
   	   	   	   	{
   	   	   	   	   	if(TK_Value_Filter[5]>TK_Threshold_Channel5)
   	   	   	   	   	   	Flag_TK5=1;
   	   	   	   	   	if(TK_Value_Filter[5]<20)
   	   	   	   	   	   	Flag_TK5=0;
   	   	   	   	}
   	   	   	   	else if(TK_Channel_NUM==6)//TK6判断
   	   	   	   	{
   	   	   	   	   	if(TK_Value_Filter[6]>TK_Threshold_Channel6)
   	   	   	   	   	   	Flag_TK6=1;
   	   	   	   	   	if(TK_Value_Filter[6]<20)
   	   	   	   	   	   	Flag_TK6=0;
   	   	   	   	}
   	   	   	   	else if(TK_Channel_NUM==7)//TK7判断
   	   	   	   	{
   	   	   	   	   	if(TK_Value_Filter[7]>TK_Threshold_Channel7)
   	   	   	   	   	   	Flag_TK7=1;
   	   	   	   	   	if(TK_Value_Filter[7]<20)
   	   	   	   	   	   	Flag_TK7=0;
   	   	   	   	}
   	   	   	
   	   	}
   	   	else
   	   	{  	
   	   	   	   	   	 if(TK_Channel_NUM==0)Flag_TK0=0;
   	   	   	   	else if(TK_Channel_NUM==1)Flag_TK1=0;
   	   	   	   	else if(TK_Channel_NUM==2)Flag_TK2=0;
   	   	   	   	else if(TK_Channel_NUM==3)Flag_TK3=0;
   	   	   	   	else if(TK_Channel_NUM==4)Flag_TK4=0;
   	   	   	   	else if(TK_Channel_NUM==5)Flag_TK5=0;
   	   	   	   	else if(TK_Channel_NUM==6)Flag_TK6=0;
   	   	   	   	else if(TK_Channel_NUM==7)Flag_TK7=0; 	
   	   	}   
			//切换TK通道，配置下一个TK采集                               
   	   			P1ADCR=0X00;
   	   			OEP1=OEP1|0X3E;
   	   			IOP1=IOP1&0XC1;
   	   	   	TK_Channel_NUM++; //这里是通道1到通道6依次切换，如果有不同需求，可对应更改通道配置
   	   	   	if(TK_Channel_NUM>=6)
   	   	   	{
   	   	   	   	TK_Channel_NUM=1;
   	   	   	} 
   	   	   	 if(TK_Channel_NUM==0){TKN0_OE=0;TKN0_ADCR=1;}
   	   	   	 else if(TK_Channel_NUM==1){TKN1_OE=0;TKN1_ADCR=1;}
   	   	   	 else if(TK_Channel_NUM==2){TKN2_OE=0;TKN2_ADCR=1;}
   	   	   	 else if(TK_Channel_NUM==3){TKN3_OE=0;TKN3_ADCR=1;}
   	   	   	 else if(TK_Channel_NUM==4){TKN4_OE=0;TKN4_ADCR=1;}
   	   	   	 else if(TK_Channel_NUM==5){TKN5_OE=0;TKN5_ADCR=1;}
   	   	   	 else if(TK_Channel_NUM==6){TKN6_OE=0;TKN6_ADCR=1;}
   	   	   	 else if(TK_Channel_NUM==7){TKN7_OE=0;TKN7_ADCR=1;}
   	   	   	
   	   	   	 TKCR1=TKCR1&0xf8;
   	   	   	 TKCR1=TKCR1+TK_Channel_NUM;
       	   	 
   	   	   	 TKCON=0;
   	   	   	 TKCNTH=0;
   	   	   	 TKCNTL=0;	//注意一定要手动清掉TK值，软件不会自动清
   	   	   	 TKCON=1; 
   	   	   	 T0EN=1;  //重新开启新的TK采集

   	}  	   	
  
   	
}  
/************************************************
函数名: LED_Process
说明: 
************************************************/ 
void LED_Process()
{
				if(Flag_TK1)	LED1=on;
				else	LED1=off;
				if(Flag_TK5)	LED2=on;
				else	LED2=off;   	   	   	
   	   	if(Flag_TK4)	LED3=on;  	   	   	
   	   	else	LED3=off;   	   	   	
   	   	if(Flag_TK3)	LED4=on;   	   	   	
   	   	else	LED4=off;   	   	   	
   	   	if(Flag_TK2)	LED5=on;   	   	   	
   	   	else	LED5=off;
}
   	   	   	        	
/************************************************
函数名:主函数
说明:
************************************************/
void main()
{      	                 
       	Init_Sys();
   	   	Clr_Ram();
   	   	Init_timer();
       	while(1) 
       	{      	
   	   	   	Touch_Value_Deal();
   	   	   	LED_Process();
   	   	   	
   	   	}
}
   	       	       	       	       	       	


/************************************************
函数名:中断程序
说明:
************************************************/
void int_isr(void) __interrupt
{
       	__asm
       	       	movra   _ABuf
       	       	swapar  PFLAG
       	       	movra   _StatusBuf
       	__endasm;
//========= T0/T1中断 ==============     	
       	if(T0IF)
       	{      	       	
       	   	T0IF   = 0; 
       	   	P03D=!P03D;   
   	   	   	TK_Value_H=TKCNTH;   
       	   	TK_Value_L=TKCNTL;	 
       	   	TK_Value=TK_Value_H;
       	   	TK_Value=TK_Value<<4;
       	   	TK_Value=TK_Value&0xFF0;         	   	
   	   	   	TK_Value=TK_Value+((TK_Value_L>>4)&0x0f); 
   	   	   	
   	   	   	Flag_TK_Read=1;
   	   	   	   	       	
       	}
   	   	if(TKIF)
   	   	{
   	   	   	TKIF=0;
   	   	}
       	if(ADIF)
       	{      	       	
       	   	ADIF  = 0;             	       	
       	}          	
//========= 外部中断 ==============

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