/******************************************************************************
  * 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 LED P03D
#define testio P03D
#define P_Senddata P12D

//寄存器定义
uchar ABuf, StatusBuf, FSR_TEMP;

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 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_Touch_Read Flag_Touch.bits.bit0

/*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 	16 		//基准值更新次数
#define 	off 	0
#define 	on 		1
/************************************************
函数名:初始化函数
说明:
************************************************/
void Init_Sys(void)
{
	//========= Io初始化 ==============
	OEP0 = 0xff;
	OEP1 = 0xff;

	IOP0 = 0x00;
	IOP1 = 0x00;

	PUP0 = 0x00;
	PUP1 = 0x00;
	P16OE = 0;
	P16PU = 0;
	P16PD = 0;
	P16DC = 0;

	//========= 寄存器初始化 ==============
	TK_Value = 0;
	TK_BaseSamples = 0;
	TK_Value_Filter = 0;
	TK_Value_H = 0;
	TK_Value_L = 0;
}

/************************************************
函数名:定时器初始化
说明:
************************************************/
void Init_timer(void)
{
	T0CR = 0x44;
	T0CNTH = 0Xf0;
	T0CNTL = 0XFF;
	T0LOADH = 0Xf0;
	T0LOADL = 0XFF; //32MS
	TKCR0 = 0XD8;	//跳频模式
	TKCR1 = 0X80;	//通道0
	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);
//}
/************************************************
函数名: 电压采集
说明: (1-a)D+aB-((1-b)D+bC)=D-aD+aB-D+bD-bC=
************************************************/
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 >> 4;
				TK_BaseSamples_Buf = 0;
				P_Senddata = !P_Senddata;
			}
		}

		//采样值与基准值做比较
		if (TK_Value < TK_BaseSamples)
		{
			TK_Value_Filter = TK_BaseSamples - TK_Value;
			if (TK_Value_Filter > TK_Threshold_Channel0)
			{
				LED = on;
			}
		}
		else
		{
			LED = off;
		}

		//新一轮检测
		TKCON = 0;
		TKCNTH = 0;
		TKCNTL = 0; //注意一定要手动清掉TK值，软件不会自动清
		TKCON = 1;
		T0EN = 1; //重新开启新的TK采集
	}
}
/************************************************
函数名:主函数
说明:
************************************************/
void main()
{
	Init_Sys();
	Init_timer();
	while (1)
	{
		Touch_Value_Deal();
	}
}

/************************************************
函数名:中断程序
说明:
************************************************/
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;
		TK_Value = TK_Value >> 4;

		Flag_Touch_Read = 1;
	}
	if (TKIF)
	{
		TKIF = 0;
	}
	if (ADIF)
	{
		ADIF = 0;
	}
	//========= 外部中断 ==============

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