/*-------------------------------------------

程序名称：CMS89F628框架示例程序
日期版本：2018/6/15 <V1.1>

备注：

*本程序由 中微半导体有限公司 &应用支持部& 编写整理
*公司网址 www.mcu.com.cn
*技术支持QQ 3001082102  罗工
            3001085706	陈工
-------------------------------------------*/


#include "main.h"
#include "Touch_Kscan_Library.h"
#include "Set_Disp.h"

//#define Flag_Lcd			//选择那种显示方式			
#define Flag_Led	




void DelaySomeTime()	//上电延时
{
	unsigned int i=5000;
	while(i)
	{
		CLRWDT();
		i--;
	}
}





/***********************************************************
主循环
***********************************************************/
void main()
{
	Init_System();
	while(1)
	{
		CLRWDT();
				
		if(B_MainLoop)
		{
			B_MainLoop = 0;
			Refurbish_Sfr();
			
			#ifdef Flag_Lcd
			Set_Disp_Lcd();			//设置Lcd显示
			#endif
			
			
			#ifdef Flag_Led
			Set_Disp_Led();		//设置Led显示
			Disp_Led();			//点Led  
			#endif
			
			Set_Time();			//计时
			Test_AD();			//AD测试
			DealTemperature();  //将AD转换成温度
						
			CheckTouchKey();	//扫描按键
			Kscan();			//按键处理
		
		}
	}
}






















//*************子函数*****************

//数据转换 10进制为99内
void Hex_To_Bcd(unsigned char data)
{
	unsigned char i=0;
	while(data>=10)
	{
		data-=10;
		i++;
	}
	BCD_L=data;
	BCD_H=i;	
}

//中断服务函数
void interrupt Isr_Timer()
{
	if(TMR2IF)				//若只使能了一个中断源,可以略去判断
	{
		TMR2IF = 0;
//---------------	

		if(Flag_buz)	
        {			
            PORTE ^= 0x08;  //PORTE,3--蜂鸣器驱动 					
			if(BuzTime <= 800)
			{
				BuzTime++;				
			}
			else
			{
				Flag_buz = 0;
				BuzTime = 0;
			}
				
		}
		else
			RE3=0;
		
//--------------		
		if(++MainTime >= 20)		//一次主循环时间，20*125us=2.5ms
		{
			MainTime = 0;
			B_MainLoop = 1;
		}
//-------------						
#ifdef  Flag_Lcd
		if(++LcdTime>=10)
		{
			LcdTime=0;
			Disp_Lcd();
		}
#endif		
			
	}
	else
	{
		PIR1 = 0;
		PIR2 = 0;
	}
}


//系统初始化
void Init_System()
{
	asm("nop");
	asm("clrwdt");
	INTCON = 0;				//禁止中断
	OSCCON = 0X71;			//配置振荡为8M
	OPTION_REG = 0;
	
    WPUB  = 0B00000000;  //PB口上拉无效
 
	TRISA = 0B00000011;  //PORTA,0/PORTA,1--触摸按键     
	TRISB = 0B00111110;  //PORTB,1/PORTB,2--ICC通讯 //PORTB,4/PORTB,5--触摸按键  B3=AD
	TRISE = 0B00000000;  //PORTE,0--触摸电容 //PORTE,3--蜂鸣器驱动  
 
	PORTA = 0B00000000;
	PORTB = 0B00000000;	 //关闭所有输出
	PORTC = 0B00000000;
	PORTE = 0B00000000;	
	
	
	#ifdef Flag_Lcd
	TRISC = 0B00001111;	 //PORTC,0~PORTC,3--LCD-COM口 ;PORTC,4--LED-COM口
	PORTC = 0B00000000;
	#endif
			
			
	#ifdef Flag_Led
	TRISC = 0B00000000;	 //PORTC,0~PORTC,3--LCD-COM口 ;PORTC,4--LED-COM口
	PORTC = 0B00011111;
	#endif	
	 
	
	ANSEL = 0B00000000;	//数模通道
	ANSELH = 0B00000010;
	
						//延时等待电源电压稳定
	DelaySomeTime();	//上电延时

	PIE2 = 0;
	PIE1 = 2;
	PR2 = 250;				//8M下将TMR2设置为125us中断
	T2CON = 4;				//使能定时器2
	
	INTCON = 0XC0;			//使能中断
	
	Flag_buz = 1;    		//上电蜂鸣器响
	BuzTime=0;				//蜂鸣器响时间
			
}


//刷新特殊功能寄存器
void Refurbish_Sfr()
{
	ANSEL = 0;
	ANSELH = 0;  		 //均为数字口
	
    WPUB  = 0B00000000;  //PB口上拉无效		
	TRISA = 0B00000011;  //PORTA,0/PORTA,1--触摸按键     
	TRISB = 0B00111110;  //PORTB,1/PORTB,2--ICC通讯 //PORTB,4/PORTB,5--触摸按键 
	TRISE = 0B00000000;  //PORTE,0--触摸电容 //PORTE,3--蜂鸣器驱动  		
    EECON1 = 0;  		 //清此寄存器,有好处(yanglei)

	#ifdef Flag_Lcd
	TRISC = 0B00001111;	 //PORTC,0~PORTC,3--LCD-COM口 ;PORTC,4--LED-COM口
	PORTC = 0B00000000;
	#endif
			
			
	#ifdef Flag_Led
	TRISC = 0B00000000;	 //PORTC,0~PORTC,3--LCD-COM口 ;PORTC,4--LED-COM口
	PORTC = 0B00011111;
	#endif

	ANSEL = 0B00000000;	//数模通道
	ANSELH = 0B00000010;

	OPTION_REG = 0;
	
						//刷新中断相关控制寄存器
	PIE1 = 2;
	PR2 = 250;
	INTCON = 0XC0;
	if(4 != T2CON)
		T2CON = 4;
}

//键处理函数
void Kscan()
{
	static unsigned int KeyOldFlag = 0;
	unsigned int i = (unsigned int)((KeyFlag[1]<<8) | KeyFlag[0]);
	if(i)
	{
		if(i != KeyOldFlag)
		{
			KeyOldFlag = i;			//有检测到按键
			
			BuzTime=0;				//蜂鸣器响时间			
			
			switch(i)
			{						//按键处理
				case 1:	Key3_Deal();break;
				case 2:	Key1_Deal();break;
				case 4:	Key2_Deal();break;
				case 8:	Key4_Deal();break;
				default:break;
			}
		}
	}
	else
	{
		KeyOldFlag = 0;
	}
}


//键处理子函数
//----------------------
void Key1_Deal()			//开关键
{
	Flag_buz = 1;    		//鸣器响	
	secl=0;
	sech=0;
	ds_sec=0;
	ds_min=0;
	ds_hour=0;	
	
	if(Flag_Onoff == 1)
	{
		Flag_Onoff=0;
		work_mode=0;		
	}
	else
	{
		Flag_Onoff=1;		//开机以模式1工作
		work_mode=1;
		ds_hour=2;
		ds_min=0;
		Flag_SS = 0;
		secl = 0;
		sech = 0;
		ds_sec = 0;				
	}
}
//------------------------
void Key2_Deal()		//模式键
{
	if(Flag_Onoff == 1)
	{
		Flag_buz = 1;    		//鸣器响

		if(work_mode==1)
			work_mode=2;
		else if(work_mode==2)
			work_mode=1;		
	}
}
//------------------------
void Key3_Deal()		//小时
{
	if(Flag_Onoff == 1 && work_mode == 1)
	{
		if(work_mode==1)
		{		
			Flag_buz = 1;    		//鸣器响
			Flag_SS = 0;
			secl = 0;
			sech = 0;
			ds_sec = 0;
							
			if(ds_hour>=23)
				ds_hour = 0;
			else
				ds_hour++;
			if(ds_hour == 0&& ds_min == 0)		//定时最小1分钟
			{
				ds_min = 1;
			}				
		}		
	}	
}
//------------------------
void Key4_Deal()		//分钟
{
	if(Flag_Onoff == 1 && work_mode == 1)
	{
		if(work_mode==1)
		{
			Flag_buz = 1;    		//鸣器响	
			Flag_SS = 0;
			secl = 0;
			sech = 0;
			ds_sec = 0;
							
			if(ds_min>=59)
				ds_min = 0;
			else
				ds_min++;
				
			if(ds_hour == 0&& ds_min == 0)	//定时最小1分钟
			{
				ds_min = 1;
			}	
		}		
	}
}


//定时处理子函数
//----------------------
void Set_Time()
{	
		if(ds_min==0 && ds_hour==0 && Flag_Onoff == 1)
		{
			Flag_Onoff = 0;
		}
		
		else
		{		
			secl++;
			if(secl>=20)
			{
				secl=0;
				sech++;
			}
			if(sech>=10)
			{
				sech=0;
				Flag_SS=!Flag_SS;
				ds_sec++;
			}							//0.5s到
							
			if(ds_sec >= 60)
			{
				ds_sec = 0;	
							
				if(0 != ds_min)	
				{
					ds_min--;
				}
				else
				{
					if(0 != ds_hour)
					{
						ds_hour--;
						ds_min = 59;
					}
				}			
			}
		}							
}

//AD测试子函数
//----------------------
void Test_AD()
{
	if(Flag_buz)
		return;
	
	ADCON1 = 0;						//左对齐	
	ADCON0 = 0X41;
	ADCON0 |= (unsigned char)(9 << 2);//16分频  第9通道  允许AD使能		
	asm("nop");
	asm("nop");
	GODONE = 1;						//开始转换

	volatile unsigned char i = 0;

	while(GODONE)
	{
		if(0 == (--i))
			return;
	}
	
	if(0 == admax)
	{
		admax = ADRESH;				//只取高8位有效处理
		admin = ADRESH;
	}
	else if(ADRESH > admax)
		admax = ADRESH;				//AD采样最大值
	else if(ADRESH < admin)
		admin = ADRESH;				//AD采样最小值
	
	adsum += ADRESH;
	if(++adtimes >= 10)
	{
		adsum -= admax;
		adsum -= admin;
		
		adresult = adsum >> 3;		//8次平均值作为最终结果
		
		adtemper = adresult;
		adsum = 0;
		admin = 0;
		admax = 0;
		adtimes = 0;
		Flag_AD = 1;
	}	
}


//将AD转换成温度
//----------------------
void DealTemperature()
{
	volatile unsigned char Count,TempBit;

	if(Flag_AD)
	{
		Flag_AD=0;		//AD测完标志
		
		if(adtemper > 254)		//<=1度，显示1度
		{
			TempBit = 0;			
		}	
		else if(adtemper <= 102)	//>=100显示100度
		{
			TempBit = 100;
		}	
		else
		{
			Count=0x80;		//开始判断点，从最高位开始			
			TempBit=0;
			do
			{
				if((Count>C_TEMP_MAX)||((Count|TempBit)>C_TEMP_MAX))
				{
					TempBit=(~Count)&TempBit;		//最高位为0
				}
				else 
				{
					if(adtemper < TempTab[Count|TempBit])
					{
						TempBit= (Count|TempBit);
					}
					else
					{
						TempBit=(~Count)&TempBit;
					}
				}
				Count=(Count>>1);
			}while(0!=Count);
		}
		

				
		if(TempBit==TemperatureBuf)
		{
			if(++TemperatureTime>=3)		//三次相等则刷新
			{
				Temperature=TempBit;
				TemperatureTime=0;
			}
		}
		else
		{
			TemperatureBuf=TempBit;
			TemperatureTime=0;
		}	
	}
}





















