⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 采用华邦79E834+HT1380+24C04实现全自动抽水将置的源程式。如要疑问可发Email到nwm-2003@163.com。
💻 C
字号:
/******************************************************************************

*******************************************************************************/
#include "all_func.h"
#include "main_func.h"


bit key_f;
bit kcont_f;
bit key_nf;
bit key_first_f;
bit MainMenuEnable_f;
bit Flash_f;
bit UP_f;
bit Flash_H_f;
bit Flash_M_f;
bit Adjust_f;
bit Menu_f;
bit SlaveMenu_f;
bit Motor_On_f;
bit Motor_Check_F;
bit No_Water__Flash_f;
bit Time_Err_F;
bit Re_time_check_F;
bit Re_Start_F;
struct Clock
{
	unsigned char Min;
	unsigned char Hou;
};
struct Clock CurrentClock,OnClock,OffClock,ClockBuf;
unsigned int C_CLK,ON_CLK,OFF_CLK;
unsigned char time_ms[4];
unsigned char idata time_s[2];
unsigned char HT1380_check;
unsigned char Sec_time=0;
unsigned char Re_Run_CNT;
unsigned char keybuf;
unsigned char keyCont;
unsigned char idata dis_buffer[4];
unsigned char MainMenu=0;
unsigned char SlaveMenu=0;
unsigned char time_read_CNT;
void InitialCPU();
void DelayXms(unsigned char);
void ButtonDetec(void);
void Motor_Control(void);
void Time_Mem(void);
void Time_init(void);
void Time_Calculation(void);
void main()
{
	unsigned char i=0x01;
	unsigned char key;
	unsigned char *p;
	Motor_PIN=0;
	Motor_On_f=0;
	time_ms[2]=1;
	time_ms[1]=1;
	for(i=0;i<4;i++)
	{
		dis_buffer[i]=0x3b;
	}
	InitialCPU();
	_nop_();
	LED_CLK_PIN=1;
	Motor_Check_F=1;
	P24=0;
	P1=0xff;
	P0=0xff;
	Motor_PIN=0;
	DelayXms(_500ms);
	init_HT1380();
	_nop_();
	EN2IC_PIN=1;
	DelayXms(_500ms);
	Time_init();
	Adjust_f=0;
	Menu_f=1;
	Flash_M_f=0;
	Flash_H_f=0;
	Off_LED=0;
	On_LED=0;
	Motor_PIN=0;
	Current_LED=1; 
	Motor_PIN=0;
	Motor_On_f=0;
	while(1)
	{	
		if((Adjust_f==0)&&(time_read_CNT==0))
		{
			Multi_Read_HT1380();
			time_read_CNT=9;
			CurrentClock.Min=Minute;
			CurrentClock.Hou=Hour;
			Print_Time(CurrentClock.Hou,CurrentClock.Min);
		}
		Time_Calculation();
		if(OFF_CLK>ON_CLK)
		{
			Motor_On_f=0;
			if ((C_CLK>=ON_CLK)&&(C_CLK<OFF_CLK))
			{
				Motor_On_f=1;
			}
			
		}
		if(OFF_CLK<ON_CLK)
		{
			Motor_On_f=1;
			if ((C_CLK>=OFF_CLK)&&(C_CLK<ON_CLK))
			{
				Motor_On_f=0;
			}
			
		}
		if(time_s[1]==0)
		{
			Flash_M_f=0;
			time_s[1]=t1s;
			Flash_H_f=0;
			Adjust_f=0;
			MainMenu=CURRENT_TIME;
			Current_LED=1;   /*点亮指示当前时间的LED*/
			Off_LED=0;
			On_LED=0;
			SlaveMenu=TIME_OK;
			if(SlaveMenu_f==1)
			{
				SlaveMenu_f=0;
				Time_Mem();
			}

		}
		
		Motor_Control();
		ButtonDetec();
		if (key_f==1)
		{
			for(i=0;i<4;i++)
				{
					if (keybuf==keyTAB[i][0])
					key=keyTAB[i][1];
					
				}

			_nop_();
			switch(key)
			{
				case MAIN_KEY:
					MainMenu_Adjust();break;
				case SLAVE_KEY:
					SlaveMenu_Adjust();break;
				case UP_KEY:
					UP_f=0;
					Time_Adjust();break;
				case DOWN_KEY:
					UP_f=1;
					Time_Adjust();break;
				default:break;
			}
			key_f=0;
			kcont_f=0;

		}
	}
}
void ButtonDetec(void)
{	
	unsigned char b;
	key_f=0;
	kcont_f=0;
	key_nf=0;
	Main_Key=1;
	Slave_Key=1;
	Up_Key=1;
	Down_Key=1;
	if(Main_Key==0)
	{
		DelayXms(_20ms);
		if(Main_Key==0)
		{
			key_nf=1;
			keybuf=MAIN_KEY;
		}
	}
	else if(Slave_Key==0)
	{
		DelayXms(_20ms);
		if(Slave_Key==0)
		{
			key_nf=1;
			keybuf=SLAVE_KEY;
		}
	}
	else if(Up_Key==0)
	{
		DelayXms(_20ms);
		if(Up_Key==0)
		{
			key_nf=1;
			keybuf=UP_KEY;
		}
	}
	else if(Down_Key==0)
	{
		DelayXms(_20ms);
		if(Down_Key==0)
		{
			key_nf=1;
			keybuf=DOWN_KEY;
		}
	}
	if (key_nf==1)    //key pressed,check key is new or continued
	{

		if (keyCont==0)
		{
			key_f=1;    //new Key pressed
			kcont_f=0;
			keyCont=0x15;  
			key_first_f=0;               

		}
		else if (keyCont!=0)
		{
			keyCont=0x15;
			key_f=0;
			kcont_f=1;   //old key continued pressing
		}
		else;
	}
	
}
/***********************************************************
功能说明:	时间调整。
			当“+”或“-”键被按下时,调用此函数。
			根据MainMenu的值判断需要调整的是当前时间还是定时开机的时间,
			或者定时关机的时间。
建立:		宁卫明
************************************************************/
void Time_Adjust(void)
{
	unsigned char k;
	unsigned char max;
if (Adjust_f==1)
{
	switch (MainMenu)
	{
		case CURRENT_TIME:	
				if(SlaveMenu==TIME_M){k=CurrentClock.Min;max=60;}
				else if(SlaveMenu==TIME_H){k=CurrentClock.Hou;max=24;}
				ClockBuf.Min=CurrentClock.Min;
				ClockBuf.Hou=CurrentClock.Hou;
				break;
		case ON_TIME:	
				if(SlaveMenu==TIME_M){k=OnClock.Min;max=60;}
				else if(SlaveMenu==TIME_H){k=OnClock.Hou;max=24;}
				ClockBuf.Min=OnClock.Min;
				ClockBuf.Hou=OnClock.Hou;
				break;
		case OFF_TIME:	
				if(SlaveMenu==TIME_M){k=OffClock.Min;max=60;}
				else if(SlaveMenu==TIME_H){k=OffClock.Hou;max=24;}
				ClockBuf.Min=OffClock.Min;
				ClockBuf.Hou=OffClock.Hou;
				break;
		default:	break;
	}
	k=BCD_to_HEX(k); /*所有时间都是BCD码存储,为便于判断,将其转为十六进制*/
	_nop_();
	if(UP_f==1)	k++; 	
	else if(UP_f==0) k--;
	if (k>=max)k=0;  /*调整后如果超出了范围,就将其复位为“0”*/
	_nop_();
	k=Hex_to_BCD(k); /*将调整后的值转成BCD码,暂时存储*/
	_nop_();
	if(SlaveMenu==TIME_M)ClockBuf.Min=k;
	else if(SlaveMenu==TIME_H)ClockBuf.Hou=k;
	switch (MainMenu)
		{
		case CURRENT_TIME:	/*如果主菜单指向当前时间,更新当前时间*/
				Minute=ClockBuf.Min;
				Hour=ClockBuf.Hou;
				CurrentClock.Min=ClockBuf.Min;
				CurrentClock.Hou=ClockBuf.Hou;
				Multi_Write_HT1380(); 
				Print_Time(Hour,Minute);
				break;
		case ON_TIME:	/*如果主菜单指向开机时间,更新开机时间*/
				OnClock.Min=ClockBuf.Min;
				OnClock.Hou=ClockBuf.Hou; 
				Print_Time(ClockBuf.Hou,ClockBuf.Min);
				break;
		case OFF_TIME:	/*如果主菜单指向关机时间,更新关机时间*/
				OffClock.Min=ClockBuf.Min;
				OffClock.Hou=ClockBuf.Hou;
				Print_Time(ClockBuf.Hou,ClockBuf.Min);
				break;
		default:	break;
		}
	time_s[1]=t2s;
	if (SlaveMenu==TIME_H)	Flash_H_f=1;/*时分菜单指向小时,使小时显示值闪烁*/
	if (SlaveMenu==TIME_M)	Flash_M_f=1;/*时分菜单指向分钟,使分钟显示值闪烁*/
	}
}
/****************************************************
功能说明:	时分菜单调整
			每按压一次时分菜单按键,此菜单的值改变一次,指向调整小时,
			或者分钟,或都确认调整OK
建立:		宁卫明
********************************************************/
void SlaveMenu_Adjust(void)
{
	SlaveMenu++;
	if(SlaveMenu>=3)SlaveMenu=0;
	ReadStop_f=1;
	time_s[1]=t5s;
	Adjust_f=1;
	EN2IC_PIN=0;
	SlaveMenu_f=1;
	Menu_f=0;
	if (SlaveMenu==TIME_H)
	{
		Flash_H_f=1;/*时分菜单指向小时,使小时显示值闪烁*/
		Flash_M_f=0;
	}
	
	if (SlaveMenu==TIME_M)	
	{
		Flash_M_f=1;/*时分菜单指向分钟,使分钟显示值闪烁*/
		Flash_H_f=0;
	}

	if(SlaveMenu==TIME_OK)/*时分菜单指向确认,清除闪烁*/
	{
		Flash_M_f=0;
		Flash_H_f=0;
		Adjust_f=0;
	}
	Re_Run_T_Min=0;
	Re_time_check_F=0;
	Motor_Check_F=1;
	Re_Start_F=0;
}
/****************************************************
功能说明:	主菜单调整
			每按压一次主菜单按键,此菜单的值改变一次,指向调整当前时间,
			或指向调整开机时间,或者指向调整关机时间。
建立:		宁卫明
********************************************************/
void MainMenu_Adjust(void)
{
	MainMenu++;
	if(MainMenu>=3)MainMenu=0;
	time_s[1]=t5s;
	SlaveMenu=0;
	Menu_f=1;
	Flash_M_f=0;
	Flash_H_f=0;
	Adjust_f=1;
	EN2IC_PIN=0;
	Re_Run_T_Min=0;
	Re_time_check_F=0;
	Motor_Check_F=1;
	Re_Start_F=0;
}
/****************************************************
功能说明:	更新显示
建立:		宁卫明
********************************************************/
void Display_Menu_Process(void)
{
	if(Menu_f==1)
	{
		switch (MainMenu)
		{
		case CURRENT_TIME:	
				Off_LED=0;   
				On_LED=0;
				Current_LED=1;   /*点亮指示当前时间的LED*/
				Print_Time(CurrentClock.Hou,CurrentClock.Min);
				break;
		case ON_TIME:	
				Off_LED=0;
				On_LED=1;		/*点亮指示开机时间的LED*/
				Current_LED=0;
				Print_Time(OnClock.Hou,OnClock.Min);
				break;
		case OFF_TIME:	
				Off_LED=1;		/*点亮指示关机时间的LED*/
				On_LED=0;
				Current_LED=0;
				Print_Time(OffClock.Hou,OffClock.Min);
				break;
		default:	break;
		}
	}
	else if(Menu_f==0)
		{
		switch (MainMenu)
		{
		case CURRENT_TIME:	
				Print_Time(CurrentClock.Hou,CurrentClock.Min);
				break;
		case ON_TIME:	
				Print_Time(OnClock.Hou,OnClock.Min);
				break;
		case OFF_TIME:	
				Print_Time(OffClock.Hou,OffClock.Min);
				break;
		default:	break;
		}
	}
}
/****************************************************
功能说明:	更新显示缓冲区
			!!显示缓冲区被更新后,LED屏的显示也会立即被更新!!!
			这种更新是由定时器0里面的显示扫描程式决定的。
建立:		宁卫明
********************************************************/
void Print_Time(unsigned char H,unsigned char M)
{
	unsigned char *p,i;
	p=digTAB;
	i=M&0x70;
	i>>=4;
	dis_buffer[1]=*(p+i);
	i=M&0x0f;
	dis_buffer[0]=*(p+i);
		
	i=H&0x70;
	i>>=4;
	if (i==0)dis_buffer[3]=0xff;
	else
	dis_buffer[3]=*(p+i);
	i=H&0x0f;
	dis_buffer[2]=*(p+i);
}
/****************************************************
功能说明:	BCD码转为十进制。
建立:		宁卫明
********************************************************/
unsigned char BCD_to_HEX(unsigned char BCData)
{
	unsigned char i,k,j;
	i=BCData&0x70;
	i>>=4;
	k=i*10;
	i=BCData&0x0f;
	j=k+i;
	return j;
}
/****************************************************
功能说明:	十六进制码转为BCD码。
建立:		宁卫明
********************************************************/
unsigned char Hex_to_BCD(unsigned char HexData) 
{
	unsigned char va;
	unsigned char i;
	unsigned char *p;
	unsigned char BCD_buffer[3];
    va = 100;                               
    for  (i=2;i>0;i--) 
    {
        BCD_buffer[i] = 0;                
        while ((HexData>=va)&&(va>9)) 
        {
            HexData -= va;                    
            BCD_buffer[i]++;              
        }
        va /= 10;                           
    }
    BCD_buffer[0]=HexData;
	i=BCD_buffer[1]&0x07;
	i<<=4;
	HexData&=0x0f;
	return(i+HexData);
}
/****************************************************
功能说明:	抽水电机控制。
建立:		宁卫明
********************************************************/
void Motor_Control(void)
{
	if ((Motor_On_f==0)||(Adjust_f==1))
	{
		Motor_PIN=0;
		No_Water__Flash_f=0;
		Re_Run_T_Min=0;
		Re_time_check_F=0;
		Motor_Check_F=1;
		Re_Start_F=0;
		P11=0;
	}
	else if((Motor_On_f==1)&&(Adjust_f==0))
	{
		if(FullWater_PIN==0)
		{
			Motor_PIN=0;
			Motor_Check_F=1;
		}
		else if(FullWater_PIN==1)
		{
		/*****检查水是否低于最低水位*****************/
			if(NoWater_PIN==1)
			{
				if((Motor_Check_F==1)&&(Re_Run_T_Min==0))
				{
					S_Scnt=0;
					Motor_PIN=1;
					P11=1;
					Motor_Check_F=0;
					Re_Start_F=0;
					No_Water__Flash_f=0;
					if (Re_time_check_F==0)
					{
						Re_Run_T_Min=1;
						S_Scnt=0;
						Re_Run_CNT=0;
					}
					
				}
			}
		/*************************************************************************
			在开机时间刚到,第一次起动电机后的Re_Run_T_Min时间内将不检查是否有水,
			以便于等待水被抽到水塔进水口
		**************************************************************************/
			if(Re_Run_T_Min==0)
			{
				No_Water__Flash_f=0;
				if((HasWater_PIN==1)&&(Re_Run_CNT==0))
				{
					Motor_PIN=0;
					No_Water__Flash_f=1;
					S_Scnt=0;
					Re_Start_F=1;
					Re_Run_T_Min=2; /*20分钟后再重新起动电机,检查是否有水*/
					Re_Run_CNT=1;
					Motor_Check_F=1;
					Re_time_check_F=1;
				}
				if((Re_Run_CNT==1)&&(Re_Run_T_Min==0))
				{
					Re_time_check_F=0;
					Motor_Check_F=1;
				}
			}
		}
	}
}
void Time_init(void)
{
	I2C_Read_Buf (0x00, 0x06);
	if(I2C_Data_buf[0]==0xff)	Minute=0x00;
	else Minute=I2C_Data_buf[0];
	if(I2C_Data_buf[1]==0xff)	Hour=0x00;
	else Hour=I2C_Data_buf[1];
	if(I2C_Data_buf[2]==0xff)	OnClock.Min=0x00;
	else OnClock.Min=I2C_Data_buf[2];
	if(I2C_Data_buf[3]==0xff)	OnClock.Hou=0x19;
	else OnClock.Hou=I2C_Data_buf[3];
	if(I2C_Data_buf[4]==0xff)	OffClock.Min=0x02;
	else OffClock.Min=I2C_Data_buf[4];
	if(I2C_Data_buf[5]==0xff)	OffClock.Hou=0x08;
	else OffClock.Hou=I2C_Data_buf[5];
}
void Time_Mem(void)
	{
		DelayXms(_100ms);
		I2C_Data_buf[0]=Minute;
		I2C_Data_buf[1]=Hour;
		I2C_Data_buf[2]=OnClock.Min;
		I2C_Data_buf[3]=OnClock.Hou;
		I2C_Data_buf[4]=OffClock.Min;
		I2C_Data_buf[5]=OffClock.Hou;
		I2C_Write_Buf(0x00,I2C_Data_buf,0x06);
		DelayXms(_50ms);
		EN2IC_PIN=1;
	}
void Time_Calculation(void)
{
	unsigned int i=0x0000,j=0x0000;
	i= BCD_to_HEX(CurrentClock.Hou);
	i= i<<8;
	j= BCD_to_HEX(CurrentClock.Min);
	C_CLK=i|j;
	i= BCD_to_HEX(OnClock.Hou);
    i= i<<8;
	j= BCD_to_HEX(OnClock.Min);
	ON_CLK=i|j;
	_nop_();
	ON_CLK=i|j;
	i= BCD_to_HEX(OffClock.Hou);
	i= i<<8;
	j= BCD_to_HEX(OffClock.Min);
	OFF_CLK=i|j;
	_nop_();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -