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

📄 main12.c

📁 透明传输的DTU。实现配置:microchip 18F6520,协议DL/T645。 全部C源码文件。
💻 C
📖 第 1 页 / 共 5 页
字号:

		T2CON = 0B00000100;		//1:1 prescale, 1:1 postscale, TMR2 on
}

void SendToModule(unsigned int num)
{
  unsigned int cSendData;

	RCSTA2bits.CREN = 0;				//连续接收数据禁止

	ByteRecvUART2 = 0;
	ModulFlags.Bit.EchoModule = 0;
	ModulFlags.Bit.RecvEcho = 0;
	GPRSComm.Bit.RecvUART2 = 0;
	GPRSComm.Bit.RecvGPRS = 0;
	ReceivedReturn = 0;
  
	TXSTA2bits.TXEN = 1;				//发送允许
   	for(cSendData=0;cSendData<num;cSendData++)
   	{	
		TXREG2 = TranToMS[cSendData];	
   		while(1)
   		{
		  if(PIR3bits.TX2IF == 1) break;
		}
		delay4ms();			//!这个延时必须有,且不能缩短!
	}//END of for(cSendData=0;cSendData<num;cSendData++)
	RCSTA2bits.CREN = 1;		//连续接收数据允许
	delay4ms();
}


void Proc_0HourData(void)
{
	unsigned int address;
	unsigned char cnt_meters;
	unsigned char PerMeterDataSize;
	unsigned char DataStart;

	cnt_meters = 32;
	PerMeterDataSize = 32;	
	DataStart = 32;

	TranToMS[0] = 0x68;
	TranToMS[1] = _T;
	TranToMS[2] = _PLUS;
	TranToMS[3] = _C;
	TranToMS[4] = _I;
	TranToMS[5] = _I;
	TranToMS[6] = _C;
	TranToMS[7] = _R;
	TranToMS[8] = _CR;		
	
	for (j=0;j<cnt_meters;j++)
	{
		address = NO1Area + NO1Area*PerMeterDataSize; 
		SPIRX(address,TranToMS,PerMeterDataSize);
		Nop();
		SendToModule(PerMeterDataSize);
		Nop();
		for (k = 0; k < 32; k++)	//清除发送区
		{
			TranToMS[k] = 0;
		}
		Nop();
	}
	
}

void UploadData(void)
{
//指定CIPSEND要发送的字节长度
	LoadCMD_CIPSEND();
	ModulFlags.Bit.CMGSSent = 0x01;	//等待回车 换行 大于号 空格
	WaitReturn = 0;
	dLength = ByteReceived;
	ByteReceived = 0;
	if(dLength>=100)
	{
		tempArr[0] = dLength / 100;						//求百位
		temp2 = dLength-(dLength / 100) * 100;	
		tempArr[1] = temp2 / 10;						//求十位
		tempArr[2] = temp2-(temp2 / 10) * 10;			//求个位
		TranToMS[CIPSEND_SIZE] = _EQUAL;
		TranToMS[CIPSEND_SIZE + 1] = tempArr[0]+0x30;	//转换成字符
		TranToMS[CIPSEND_SIZE + 2] = tempArr[1]+0x30;	//转换成字符
		TranToMS[CIPSEND_SIZE + 3] = tempArr[2]+0x30;	//转换成字符
		TranToMS[CIPSEND_SIZE + 4] = _CR;	
		SendToModule (CIPSEND_SIZE + 5);
	}  
	else if(dLength >= 10)
	{
		tempArr[0] = dLength/10;						//求十位
		tempArr[1] = dLength-(dLength/10)*10;			//求个位
		TranToMS[CIPSEND_SIZE] = _EQUAL;
		TranToMS[CIPSEND_SIZE + 1] = tempArr[0]+0x30;	//转换成字符
		TranToMS[CIPSEND_SIZE + 2] = tempArr[1]+0x30;	//转换成字符
		TranToMS[CIPSEND_SIZE + 3] = _CR;	
		SendToModule (CIPSEND_SIZE + 4);
	}	
	else		//dLength<10
	{
		TranToMS[CIPSEND_SIZE] = _EQUAL;
		TranToMS[CIPSEND_SIZE + 1] = dLength + 0x30;	//转换成字符
		TranToMS[CIPSEND_SIZE + 2] = _CR;	
		SendToModule (CIPSEND_SIZE + 3);
	}	
//等待回传大于号和空格 0D 0A 3E 20
	DelaySeconds(5);
	if(ModulFlags.Bit.EchoModule)	//GPRS模块对CIPSENDd的应答
	{
		for(k=0;k<dLength;k++)
		{
			TranToMS[k] = BUF_METER[k]; 
		}				
		WaitReturn = 0;
		SendToModule (dLength);		//把从电表那收到的回送上传给主站
		DelaySeconds(30);		//30秒等send ok
		if(ModulFlags.Bit.EchoModule == 1)
		{
			if(RecvFromMS[0]==0x0D && RecvFromMS[1]==0x0D)
				cRet = strncmppgm2ram(((char *)RecvFromMS+1),(const far rom char *)SEND_OK,L_SEND_OK);
			else
				cRet = strncmppgm2ram((char *)RecvFromMS,(const far rom char *)SEND_OK,L_SEND_OK);
			if(cRet == 0)						//发送成功
			{
				//SignalLed = LOW;			//打开信号强度灯
				ClearMeterREG();			//清除电表标志
				ClearGPRSREG();
				MinCounter = 0;
				for (k = 0; k < 48; k++)				//clear module 应答区
				{
					RecvFromMS[k] = 0;
				}
				return;
			}
		}
	}
	//SignalLed = HIGH;			//关闭信号强度灯

	Close_Shut();
 	PowerOffModule();
	PowerOnModule();
	PWRKeyOn();
	Module_Init();
}//END of else:电表回送数据上传

void SendBeatPack(void)
{
	for (k = 0; k < 32; k++)	//clear module 应答区
  	{
  		RecvFromMS[k] = 0;
	}
	LoadCMD_CIPSEND();
	ModulFlags.Bit.CMGSSent = 0x01;	//等待回车 换行 大于号 空格
	WaitReturn = 0;
	TranToMS[CIPSEND_SIZE] = _EQUAL;
	TranToMS[CIPSEND_SIZE+1] = _1;
	TranToMS[CIPSEND_SIZE+2] = _CR;	
	SendToModule(CIPSEND_SIZE+3);
//等待回传大于号和空格 0D 0A 3E 20
	DelaySeconds(5);
	if(ModulFlags.Bit.EchoModule)	//GPRS模块对CIPSENDd的应答
	{
  	  	cRet = strncmppgm2ram((char *)RecvFromMS,(const far rom char *)ERROR,L_ERROR);
  	  	if(cRet == 0)	//对CIPSEND的应答为ERROR,说明主站已经断开连接
  	  	{
			OnlineLed = HIGH;			//关闭在线灯
			//SignalLed = HIGH;			//关闭信号强度灯
			OtherFlags.Bit.TCPLink = 0;
			Close_Shut();
			ClearGPRSREG();

			return;
		}

  		TranToMS[0] = _0;				//_B;
  		SendToModule (1);				//发送心跳包,就一个字节
		DelaySeconds(30);		//30秒等send ok
		if(ModulFlags.Bit.EchoModule == 1)
		{
			if(RecvFromMS[0]==0x0D && RecvFromMS[1]==0x0D)
				cRet = strncmppgm2ram(((char *)RecvFromMS+1),(const far rom char *)SEND_OK,L_SEND_OK);
			else
				cRet = strncmppgm2ram((char *)RecvFromMS,(const far rom char *)SEND_OK,L_SEND_OK);
			if(cRet == 0)						//发送成功
			{
			//	SignalLed = LOW;			//打开信号强度灯
				ClearGPRSREG();
				MinCounter = 0;
				for (k = 0; k < 48; k++)				//clear module 应答区
				{
					RecvFromMS[k] = 0;
				}
				return;
			}
		}
	}
	OnlineLed = HIGH;			//关闭在线灯
	//SignalLed = HIGH;			//关闭信号强度灯
	OtherFlags.Bit.TCPLink = 0;

	Close_Shut();
 	PowerOffModule();
	PowerOnModule();
	PWRKeyOn();
	Module_Init();
}
void FirstTimeInitial(void)
{
	Nop();
//	R_eeprom((char *)tempArr,VirginTime,2);
	EEADRH = 0x00;
	EEADR = 0x08;
	EECON1bits.EEPGD = 0;	// Point to DATA memory
	EECON1bits.CFGS = 0;

	EECON1bits.RD = 1;
	temp1 = EEDATA;
	EEADR++;
	EECON1bits.RD = 1;
	temp2 = EEDATA;
	Nop();

	if(temp1 != 0x55 || temp2 != 0xAA)
	{//是终端的第一次上电
		for (k = 0; k < 16; k++)	//清除EEPROM中的要使用的一片区域。
		{
			RecvFromMS[k] = 0;
		}
		for (j = 0; j < 8; j++)		//清除EEPROM中的前128字节。
		{
			W_eeprom((char *)RecvFromMS,j*0x10,16);
		}
//写入默认终端号:实际上=00000000

// ------- write a byte to EEPROM ------------------
  			BT = 0x07;
  			EEADRH = 0x00;
			EEADR = lobyte(BeatTime);
			EECON1bits.EEPGD = 0;
			EECON1bits.CFGS = 0;
			EECON1bits.WREN = 1;
			INTCONbits.GIE = 0; 
	
			EEDATA = BT;
			EECON2 = 0x55;
			EECON2 = 0xAA;
			EECON1bits.WR = 1;
			while (!PIR2bits.EEIF)
			;
			PIR2bits.EEIF = 0;
  			
  			EECON1bits.WREN = 0;
			INTCONbits.GIE = 1; 

//写入APN默认值:CMNET		
/*
		RecvFromMS[0] = _X;
		RecvFromMS[1] = _M;
		RecvFromMS[2] = _D;
		RecvFromMS[3] = _L;
		RecvFromMS[4] = _DOT;
		RecvFromMS[5] = _F;
		RecvFromMS[6] = _J;
		W_eeprom((char *)RecvFromMS,APNAddr,7);
*/
		RecvFromMS[0] = _C;
		RecvFromMS[1] = _M;
		RecvFromMS[2] = _N;
		RecvFromMS[3] = _E;
		RecvFromMS[4] = _T;
		W_eeprom((char *)RecvFromMS,APNAddr,5);
//写入默认IP地址:219.232.44.101
		RecvFromMS[0] = _2;
		RecvFromMS[1] = _1;
		RecvFromMS[2] = _9;
		RecvFromMS[3] = _DOT;
		RecvFromMS[4] = _2;
		RecvFromMS[5] = _3;
		RecvFromMS[6] = _2;
		RecvFromMS[7] = _DOT;
		RecvFromMS[8] = _4;
		RecvFromMS[9] = _4;
		RecvFromMS[0x0A] = _DOT;
		RecvFromMS[0x0B] = _1;
		RecvFromMS[0x0C] = _0;
		RecvFromMS[0x0D] = _1;
		W_eeprom((char *)RecvFromMS,IPAddress,14);	
//写入默认端口
		RecvFromMS[0] = _2;
		RecvFromMS[1] = _0;
		RecvFromMS[2] = _0;
		RecvFromMS[3] = _5;
		W_eeprom((char *)RecvFromMS,PortAddr,4);	

//最后写上已上过电标志
		DTU_Number[0] = 0x55;
		DTU_Number[1] = 0xAA;
		W_eeprom((char *)DTU_Number,VirginTime,2);
	}
}

void Module_Init(void)
{
	unsigned char count;
  
	ModulFlags.ModuleBYTE = 0 ;
  	WaitReturn = 0;

/* 在实际应用中,RESET 和ON/~OFF 可由MCU 控制,MCU 通过对ON/~OFF 和RESET 的控制
可以实现模块的关机,具体程序为:MCU 先发命令(AT+CFUN=0,1),模块开始注销网络登
记,然后使ON/~OFF 信号为反向有效(0FF 有效)200ms,再使RESET 有效(低电平维持100ms 以
上),这样就可以关掉模块。模块关机后的电流为50uA。
*/
	LoadCMD_AT();
	SendToModule (3);
	PassSeconds(5);
  	ModulFlags.Bit.EchoModule = 0;
   	ModulFlags.Bit.RecvEcho = 0;
	ClearGPRSREG();

  MaxTry = 0;	
  while(1)
  {
	LoadCMD_AT();
	SendToModule (3);
	DelaySeconds(5);

  	if(ModulFlags.Bit.EchoModule == 1)
  	{
  		ModulFlags.Bit.EchoModule = 0;
   		ModulFlags.Bit.RecvEcho = 0;
		break;
  	}//END if(ModulFlags.Bit.EchoModule == 1)
  	else
  	{
		ClearGPRSREG();
		MaxTry++;
		if(MaxTry > 1)
		{
			PowerOnModule();
  			Nop();
			PWRKeyOn();
  			Nop();
			MaxTry = 0;
		}
	}
  }//END 

//在这先发ATE0命令,设置为命令无ECHO
	Nop();
  	LoadCMD_ATE0();
  	SendToModule (ATE0_SIZE);
	delay200ms ();				//如果只延时20ms,就只能收到回送15个字节
  	if(ModulFlags.Bit.EchoModule == 1)
  	{
  	  	if(RecvFromMS[2]==_O && RecvFromMS[3]==_K)
  	  	{
	    	ModulFlags.Bit.RecvEcho = 0;
  	  	}//END if(ModulFlags.Bit.EchoModule == 1)
  	}

//默认是CMGF=0 PDU模式,再初始化成UCS2编码
	LoadCMD_CSCS();
	SendToModule (AT_CSCS_SIZE);
	delay200ms ();

  		if(ModulFlags.Bit.EchoModule == 1)
  		{
			cRet = strncmppgm2ram((char *)RecvFromMS,(const far rom char *)OK,L_OK);
  	  		if(cRet == 0)
  	  		{
	    		ModulFlags.Bit.EchoModule = 0;
	    		ModulFlags.Bit.RecvEcho = 0;
  	  		}//END if(cRet == 0)
			PassSeconds(2);
  		}//END if(ModulFlags.Bit.EchoModule == 1)

  	LoadCMD_CIPHEAD();	//设at+ciphead=1,远端发来的数据自动加上报头 +IPDn
	MaxTry = 0;	
  	while(1)
  	{
	 	ByteRecvUART2 = 0;
  		SendToModule (CIPHEAD_SIZE);
		delay50ms ();				//如果只延时20ms,就只能收到回送15个字节
  		if(ModulFlags.Bit.EchoModule == 1)
  		{
  	  		if(RecvFromMS[2]==_O && RecvFromMS[3]==_K)
  	  		{
	    		ClearGPRSREG();
  	    		break ;
  	  		}//END if(ModulFlags.Bit.EchoModule == 1)
  		}
		MaxTry++;
		if(MaxTry > 2)
			break;
  	}//END while(1)

	Nop();
	ThreeCommand();
	Nop();
//	ConnectIP();	不在此处调用,否则会嵌套。
	Nop();
}//END Module_Init()

void ThreeCommand(void)
{
  	WaitReturn = 0;

	Read_APN();
	SendToModule (temp2);
	DelaySeconds(8);
  	if(ModulFlags.Bit.EchoModule == 1)
  	{
  	  	cRet = strncmppgm2ram((char *)RecvFromMS,(const far rom char *)ERROR,L_ERROR);
  	  	if(cRet == 0)
  	  	{
			Close_Shut();
			ClearGPRSREG();
//重发
			Read_APN();
			SendToModule (temp2);
			DelaySeconds(8);
		}
		else
		{
			ModulFlags.Bit.EchoModule = 0;
   			ModulFlags.Bit.RecvEcho = 0;
		}
  	}
	else
	{
		Nop();
		//RESET();
		//设置无卡标志并闪烁灯而且建立连接前,先调用ThreeCommand进行初始化。
	}
	PassSeconds(1);
	LoadCMD_CIICR();
	SendToModule (9);
	DelaySeconds(8);
  	if(ModulFlags.Bit.EchoModule == 1)
  	{
		for(tt=0;tt<3;tt++)	//找到第一个68H,定位帧头
		{
			if(RecvFromMS[tt] == 0x0A)
				break;
		}

  	if(RecvFromMS[tt+1]==_O && (RecvFromMS[tt+2]==_K || RecvFromMS[tt+2]==_H))
  	  	{
	    	ModulFlags.Bit.RecvEcho = 0;
			ModulFlags.Bit.EchoModule = 0;
  	  	}//END if(ModulFlags.Bit.EchoModule == 1)
		else
		{
		Nop();
		//RESET();
		//设置无卡标志并闪烁灯而且建立连接前,先调用ThreeCommand进行初始化。
		}
  	}
	else
	{
		Nop();
		//RESET();
		//设置无卡标志并闪烁灯而且建立连接前,先调用ThreeCommand进行初始化。
	}
	LoadCMD_CIFSR();
  	WaitReturn = 0;
	SendToModule (9);
	DelaySeconds(10);
	ModulFlags.Bit.EchoModule = 0;
   	ModulFlags.Bit.RecvEcho = 0;
}

void ClearMeterREG(void)
{
	ByteReceived = 0;
	MeterComm.Comm1Byte = 0;
	RCSTA2bits.FERR = 0;
	RCSTA2bits.OERR = 0;
	OverTimeMeter = 0;
}

void ClearGPRSREG(void)
{
	ByteRecvUART2 = 0;
	GPRSComm.Comm2Byte = 0;
	WaitReturn = 0;
	ReceivedReturn = 0;
	OverTimeGPRS = 0;
	Length = 0;
	ModulFlags.ModuleBYTE = 0;
}

void SendCMDtoMeter(unsigned char num)
{
	EN485 = EnTransport;
	delay20ms();
	PIE1bits.TMR1IE = 0;			//关闭定时中断
	TXSTA1bits.TXEN = 1;			//*发送允许
	RCSTA1bits.CREN = 0;			//禁止接收
	PIR1bits.TX1IF = 0;
	
   	for(k = 0;k < num;k++)
   	{	
		if(BUFFER_ID == 0)
			temp1 = BUF_METER[k];
		else if(BUFFER_ID == 1)
			temp1 = YC_CMD_BUF[k];
		else
			temp1 = SMS_CMD_BUF[k];

		GenParity(temp1);
		if(parity == 1)
	  	  TXSTA1bits.TX9D = 1;
		else
	  	  TXSTA1bits.TX9D = 0;

		TXREG1 = temp1;	
   		while(1)
   		{
		  if(PIR1bits.TX1IF == 1) break;
		}
		delay10ms();//字节间延时至少10ms!!!
	}	
	while(1)
	{
		if(TXSTA1bits.TRMT == 1) break;	//最后一个字节也发完
	}
//	delay10ms();	//江苏表回送很快,不能加延时

⌨️ 快捷键说明

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