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

📄 communicate.c

📁 基于单片机的多费率电能表源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
		case CLEAR0_PASSWORD:
			if(RecBuf[10]!=RecBuf[14])
				return 0;
			SetClear0Password();			
			break;
		case PROGRAM_PASSWORD:
			if(RecBuf[10]!=RecBuf[14])
				return 0;
			SetProgramPassword();
			break;
		default:
			return 0;	
	}
	SendBuf[9]=4;
	_ProgramRecord=1;
	return 1;									
}
void SetProgramPassword(void)
{
	INT8U i;
	INT8U *Pnt;
	Pnt=&RecBuf[14];
	for(i=0;i<4;i++)
	{
		ProgramPassWord[i]=*Pnt;				
		SendBuf[10+i]=*Pnt;
		Pnt++;
	}
	WriteEepromData(PROGRAM_PASSWORD_ID,&RecBuf[14]);
	_ProgramRecord=1;
}
void SetClear0Password(void)
{
	INT8U i;
	INT8U *Pnt;
	Pnt=&RecBuf[14];
	for(i=0;i<4;i++)
	{
		Clear0PassWord[i]=*Pnt;				
		SendBuf[10+i]=*Pnt;
		Pnt++;
	}	
	WriteEepromData(CLEAR_ZERO_PASSWORD_ID,&RecBuf[14]);
	_ProgramRecord=1;	
}

/*返回0表示表址错误,返回其他表示地址正确*/
INT8U CheckDeviceNumber(INT8U *PDeviceNumber)
{
	INT8U i;
	_Broadcast_=1;
	for(i=0;i<6;i++)//广播桢判断
	{
		if(*(PDeviceNumber+i)!=0x99)
		{
			_Broadcast_=0;
			break;
		}	
	}
	if(_Broadcast_)
		return 1;
	else
	{
		for(i=0;i<6;i++)
		{
			if(*PDeviceNumber!=0xaa)
			{
				if(*PDeviceNumber!=UserNumber[i])
					return 0;				
			}
			PDeviceNumber++;
		}
		return 2;
	}
}
void DataReceive(void)
{
	INT8U ReceiveData;
	ReceiveData=HB_RDR;	
	switch(RecState)
	{
		case 0:
			if(ReceiveData==0x68)
			{				
				RecState=1;
				RecPnt=1;
				RecBuf[0]=0x68;
				RecTmr=50;		
			}
			break;
		case 1:
			RecBuf[RecPnt]=ReceiveData;
			RecPnt++;
			if(RecPnt==7)
				RecState=2;	
			break;
		case 2:
			if(ReceiveData==0x68)
			{
				RecBuf[7]=ReceiveData;
				RecPnt++;
				RecState=3;
			}
			else 
				RecState=0;
			break;			
		case 3:
			RecBuf[RecPnt]=ReceiveData;
			RecPnt++;
			RecState=4;				
			break;
		case 4:
			if(ReceiveData<60)
			{
				RecBuf[RecPnt]=ReceiveData;
				RecPnt++;
				ReceiveCnt=ReceiveData+1;
				RecState=5;	
			}
			else
				RecState=0;
			break;
		case 5:
			RecBuf[RecPnt]=ReceiveData;
			RecPnt++;
			ReceiveCnt--;
			if(ReceiveCnt==0)
				RecState=6;
			break;
		case 6:
			if(ReceiveData==0x16)//回车键
			{
				RecBuf[RecPnt]=0x16;
				UartReceiveDisable;
				RecTmr=0;
				_DatagramDeal=1;				
			}
			else
				RecState=0;
			break;
		default:
			RecState=0;
			break;
						
	}
}
void DatagramDealTask(void)
{
	INT8U i;	
	INT8U *Pnt;
	_DatagramDeal=0;
	if(!CheckDeviceNumber(&RecBuf[1]))
	{
		_CommunicateReceiveEnableTask=1;
		return;
	}
	if((_Broadcast_)&&(RecBuf[8]!=0x08)&&(RecBuf[8]!=0x0a)&&(RecBuf[8]!=0xaa)&&(RecBuf[8]!=0xad))			
	{
		_CommunicateReceiveEnableTask=1;
		return;	
	}		
	i=RecBuf[9]+10;		
	if(RecBuf[i]!=AddCRC(RecBuf,i))//校验码校验
	{
		_CommunicateReceiveEnableTask=1;
		return;	
	}	
	Pnt=&RecBuf[10];							//获得数据域首址
	i=RecBuf[9];								//获得数据域长度
	while(i--)
	{
		*Pnt-=0x33;
		Pnt++;
	}	
	switch(RecBuf[8])
	{
		case 0x01:
		case 0x03:					
			if(!CommunicateReadData())
			{
				_CommunicateReceiveEnableTask=1;
				return;	
			}			
			break;
		case 0x04:			
			if(!CommunicateWriteData())
			{
				_CommunicateReceiveEnableTask=1;
				return;	
			}
			break;
		case 0x08:
			if(_Broadcast_)
			{
				if(Is_ProGramPermit)
				{
					BroadcastSetTime();
				}
				else if(_BroadCalibrateTimeAllow_)	
					{
						if(CheckTimeErrorOfMeter())
						{
							MeterRunningState&=0xf7;//时钟正常
							BroadcastSetTime();			
						}
						else
							MeterRunningState|=0x08;//时钟异常
					}							
			}
			_CommunicateReceiveEnableTask=1;
			return;
		case 0x0a:
			if((_Broadcast_==0)||(Is_ProGramDisable))			
			{
				_CommunicateReceiveEnableTask=1;
				return;	
			}
			CommunicateWriteUserID();			
			break;
		case 0x0f:
			if(!CommunicateChangePassword())
			{
				_CommunicateReceiveEnableTask=1;
				return;	
			}
			break;
		case 0xaa://初始化表数据
			InitNewEeprom();	
			MultiRateInit();
			EnergyDataPowerOnInit();
			DisplayInit();
			_CommunicateReceiveEnableTask=1;
			return;
		case 0xad://读eeprom数据
			if(!CommunicateReadEeromPageData())
			{
				_CommunicateReceiveEnableTask=1;
				return;	
			}			
			break;		
		default:
			_CommunicateReceiveEnableTask=1;
			return ;
	}
	SendBuf[0]=SendBuf[7]=0x68;
	SendBuf[8]=(RecBuf[8]|0x80);		
	for(i=0;i<6;i++)
		SendBuf[i+1]=UserNumber[i];
	for(i=0;i<SendBuf[9];i++)
		SendBuf[10+i]+=0x33;
	i=SendBuf[9]+10;
	SendBuf[10+SendBuf[9]]=AddCRC(SendBuf,i);
	SendBuf[11+SendBuf[9]]=0x16;
	SendPnt=0x00;
	SendLen=SendBuf[9]+0x0c;
	CommunicateSendEnable();
	CommunicateCnt=2;
	_Communicate_=1;	
}
INT8U CheckTimeErrorOfMeter(void)
{
	union Union_WordDef DataTemp;	
	if(RecBuf[15]==CurrentTime.Year)
	{
		if(RecBuf[14]==CurrentTime.Month)
		{
			if(RecBuf[13]==CurrentTime.Day)
			{
				if(RecBuf[12]==CurrentTime.Hour)
				{
					if((RecBuf[11]>CurrentTime.Minute)||((RecBuf[11]==CurrentTime.Minute)&&(RecBuf[10]>=CurrentTime.Second)))
					{
						DataTemp.WORD=((RecBuf[11]&0x0f)+(RecBuf[11]>>4)*10)*60;
						DataTemp.WORD+=(RecBuf[10]&0x0f);
						DataTemp.WORD+=(RecBuf[10]>>4)*10;
						DataTemp.WORD-=((CurrentTime.Minute&0x0f)+(CurrentTime.Minute>>4)*10)*60;
						DataTemp.WORD-=(CurrentTime.Second&0x0f);
						DataTemp.WORD-=(CurrentTime.Second>>4)*10;
						if(DataTemp.WORD<300)
							return 1;
					}
					else
					{
						DataTemp.WORD=((CurrentTime.Minute&0x0f)+(CurrentTime.Minute>>4)*10)*60;
						DataTemp.WORD+=(CurrentTime.Second&0x0f);
						DataTemp.WORD+=(CurrentTime.Second>>4)*10;
						DataTemp.WORD-=((RecBuf[11]&0x0f)+(RecBuf[11]>>4)*10)*60;
						DataTemp.WORD-=(RecBuf[10]&0x0f);
						DataTemp.WORD-=(RecBuf[10]>>4)*10;
						if(DataTemp.WORD<300)
							return 1;
					}
				}
				else//跨小时的时候广播校时
				{
					DataTemp.BYTE[0]=(RecBuf[12]&0x0f)+(RecBuf[12]>>4)*10;
					DataTemp.BYTE[1]=(CurrentTime.Hour&0x0f)+(CurrentTime.Hour>>4)*10;
					if(DataTemp.BYTE[0]==(DataTemp.BYTE[1]+1))
					{
						if((RecBuf[11]<0x05)&&(CurrentTime.Minute>=0x55))
						{
							DataTemp.WORD=RecBuf[11]*60;
							DataTemp.WORD+=(RecBuf[10]&0x0f);
							DataTemp.WORD+=(RecBuf[10]>>4)*10;
							DataTemp.WORD+=600;
							DataTemp.WORD-=(CurrentTime.Minute&0x0f)*60;
							DataTemp.WORD-=(CurrentTime.Second&0x0f);
							DataTemp.WORD-=(CurrentTime.Second>>4)*10;
							if(DataTemp.WORD<300)
								return 1;
						}	
					}
					else if(DataTemp.BYTE[1]==(DataTemp.BYTE[0]+1))
						{
							DataTemp.WORD=CurrentTime.Minute*60;
							DataTemp.WORD+=(CurrentTime.Second&0x0f);
							DataTemp.WORD+=(CurrentTime.Second>>4)*10;
							DataTemp.WORD+=600;
							DataTemp.WORD-=(RecBuf[11]&0x0f)*60;
							DataTemp.WORD-=(RecBuf[10]&0x0f);
							DataTemp.WORD-=(RecBuf[10]>>4)*10;
							if(DataTemp.WORD<300)
								return 1;
						}
				}			
			}
		}
	}
	return 0;
}       
void WriteProgramRecord(void)
{
	_ProgramRecord=0;
	IncBcd(ProgramTimes,2);
	TempBufOfMain[0]=CurrentTime.Minute;
	TempBufOfMain[1]=CurrentTime.Hour;
	TempBufOfMain[2]=CurrentTime.Day;
	TempBufOfMain[3]=CurrentTime.Month;
	WriteEepromData(LAST_PROGRAM_TIME_ID,TempBufOfMain);
	TempBufOfMain[0]=ProgramTimes[0];
	TempBufOfMain[1]=ProgramTimes[1];
	WriteEepromData(TOTAL_PROGRAM_TIMES_ID,TempBufOfMain);
}       
  
INT8U CommunicateReadEeromPageData(void)  
{
	INT16U EepromAddress;
	if((RecBuf[11]<=0x07)&&((RecBuf[10]&0x0f)==0x00))
	{
		EepromAddress=RecBuf[11];
		EepromAddress<<=8;
		EepromAddress+=RecBuf[10];
		ReadEeprom(EepromAddress,&SendBuf[12],16);
		SendBuf[9]=18;
		SendBuf[10]=RecBuf[10];
		SendBuf[11]=RecBuf[11];	
		return 1;
	}
	return 0;
}    
INT8U IsBroadCalibrateTimePermit(void)  
{
	INT16U TempVar;
	if(ReadEepromData(LAST_BROADCAST_TIME_ID,TempBufOfMain))
	{
		if((EepromReadWriteBuf[0]==0)&&(EepromReadWriteBuf[1]==0)&&(EepromReadWriteBuf[2]==0)&&(EepromReadWriteBuf[3]==0))
		{	
			return 1;
		}
		TempVar=CalDayNumOfDate(CurrentTime.Month,CurrentTime.Day,CurrentTime.Year);
		TempVar-=CalDayNumOfDate(TempBufOfMain[2],TempBufOfMain[1],TempBufOfMain[3]);
		if((TempVar==25)&&(CurrentTime.Hour>=EepromReadWriteBuf[0]))
			return 1;
		else if(TempVar>25)
				return 1;
	}
	return 0;	
}  
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        

⌨️ 快捷键说明

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