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

📄 main12.c

📁 透明传输的DTU。实现配置:microchip 18F6520,协议DL/T645。 全部C源码文件。
💻 C
📖 第 1 页 / 共 5 页
字号:
  
/*
当给模块主电源VBAT 上电3S 后,通过按键或者是MCU 拉低
模块的POWERKEY 引脚(34PIN 脚)一段时间(大约2S),可以让
模块开机。模块一旦开机,可以检测到VDD-EXT 输出大约2.9V 的
电压,通过这个电压可以判断模块是否开启成功。
*/
  	PassSeconds(3);		//

  	p = 0000;
  	if(PWRUP55AA != 0x55AA)
  	{
  		for(ClearNum = 0x5FF;ClearNum>0;ClearNum--) 	
  		{
 			*p = 0;
			p ++;
  		}
  	}
	InitPeriph();
  	UART1_setup ();
  	UART2_setup ();
  	Timer1_setup();
  	PWM_setup();
  	ConfigInt();				//中断配置
    SPI_setup();
	PowerOffModule();
	PowerOnModule();
	PWRKeyOn();
	Module_Init();
    ConnectIP();
  	if(PWRUP55AA != 0x55AA)
  	{
  		FirstTimeInitial();
 	//  Read DTU NO
		R_eeprom((char *)DTU_Number,DTUNO,4);
 		PWRUP55AA = 0x55AA;
  	}
  	T1DELAY = T1_TICK;
  	t1use = OneMinute;
//read parameters from eeprom  
	R_eeprom((char *)Link_Mode,LinkMode,2);
//read heart beating's time	
	EEADRH = 0x00;
	EEADR = lobyte(BeatTime);
	EECON1bits.EEPGD = 0;	// Point to DATA memory
	EECON1bits.CFGS = 0;
	INTCONbits.GIE = 0; 

	EECON1bits.RD = 1;
	BT = EEDATA;
	if(BT > 20)
		BT = 7;

//  读出总连接表数
	EEADRH = hibyte(AllMeters);
	EEADR = lobyte(AllMeters);
	EECON1bits.EEPGD = 0;	// Point to DATA memory
	EECON1bits.CFGS = 0;
	INTCONbits.GIE = 0; 
	EECON1bits.RD = 1;
	MetersNum = EEDATA;
	INTCONbits.GIE = 1; 

  	ReadTime();
	Load645Header();
    Load_SigQua();
  while(1)
  {
	CLRWDT();
//	SoftDog = 0x00;
	
	if(OtherFlags.Bit.TimerOver == 0x01)		//到定时的时间?
		Proc_TimerOver();
// ------------------------------------------------------------    
	if(ModulFlags.Bit.EchoModule == 1)
	{
  	  	if(strncmppgm2ram((char *)RecvFromMS,(const far rom char *)CLOSED,L_CLOSED) == 0)
	  	{//主站因故断了连接,关闭即可
			OtherFlags.Bit.TCPLink = 0;
			OnlineLed = HIGH;			//关闭在线灯

			Close_Shut();
	  		ModulFlags.Bit.EchoModule = 0 ;
   	  		ByteRecvUART2 = 0;
			ClearGPRSREG();
	  	}//END of if(cRet == 0)
// ------------------------------------------------------------    
//比较收到的是否短信通知 +CMTI: 	  
		else if(strncmppgm2ram((char *)RecvFromMS,(const far rom char *)PLUSCMTI,L_PLUSCMTI) == 0)
  	  	{
  	    	Proc_SMS();
			ModulFlags.Bit.EchoModule = 0 ;
  			ByteRecvUART2 = 0;
  	  	}
		else if(strncmppgm2ram((char *)RecvFromMS,(const far rom char *)Module_RDY,RDY_SIZE) == 0)
  	  	{//对module进行了复位
 			Module_Init();	//只复位不掉电,module是否还是UCS编码?
			ClearGPRSREG();
  	  	}
		else if(strncmppgm2ram((char *)RecvFromMS,(const far rom char *)PDP_DEACT,L_DEACT) == 0)
  	  	{//module主动上报:与网络失去连接.
			OtherFlags.Bit.TCPLink = 0;
			OnlineLed = HIGH;			//关闭在线灯
  			LoadCMD_CIPSHUT();
  			WaitReturn = 0;
  			SendToModule (CIPSHUT_SIZE);
			DelaySeconds(8);
//
			Module_Init();
			ClearGPRSREG();
  	  	}
		else if(strncmppgm2ram((char *)RecvFromMS,(const far rom char *)ANS_ERROR513,L_ERROR513) == 0)
		{//有未读短信	
			LoadCMD_CMGR();		//读所有未读信息
			WaitReturn = 0;
			SendToModule (CMGL_SIZE);
			DelaySeconds(4);
			ClearGPRSREG();
			
			Index1 = _CR;
			for(k=1;k<10;k++)
			{
				Index0 = k +0x30;	//删除1~9条短信
				LoadCMD_CMGD();
				WaitReturn = 0;
 				SendToModule (CMGL_SIZE);
				DelaySeconds(4);
				ByteRecvUART2 = 0;
				if(ModulFlags.Bit.EchoModule == 1)
					ModulFlags.Bit.EchoModule = 0;
			}
		}
		ModulFlags.Bit.EchoModule = 0 ;
  	}//END of if(ModulFlags.Bit.EchoModule)

//********************************************************************
//改成:cRet = strncmppgm2ram()

	if(GPRSComm.Bit.CMD_Frame == 0x01)
	{	
		OnLineTime = 0;
		for(j=0;j<Length;j++)
		{//赶紧腾空RecvFromMS,好接收主站的下一个命令
  			YC_CMD_BUF[j] = RecvFromMS[IPDHead + j]; 	//将主站的接收缓冲区的数据
		}												//转送到遥采的发送数据缓冲区
//
		for(tt=0;tt<4;tt++)	//找到第一个68H,定位帧头
		{
			if(YC_CMD_BUF[tt] == 0x68)
				break;
		}
//YC_CMD_BUF[8]=命令字,YC_CMD_BUF[9]=长度,YC_CMD_BUF[0x0A]=DI0,YC_CMD_BUF[0x0B]=DI1
  	    if(YC_CMD_BUF[tt+8]==0x04 && YC_CMD_BUF[tt+0x0B]==0x32)		//0x32=(0xFF+0x33)
  	    {//主站专门发给DTU的命令处理。
			GPRSComm.Bit.CMD_Frame = 0;
			ClearGPRSREG();
			CMDtoDTU();
  	    }
  	    else if(YC_CMD_BUF[tt+8] == 0x04 && YC_CMD_BUF[tt+0x0A] == (0x1F+0x33) && YC_CMD_BUF[tt+0x0B] == (0xC0+0x33))
		{//专门对采集器的命令:C01F 校准时间和日期
//设置日期时间,BCD编码的秒分时日月年:YC_CMD_BUF[0x0C],0D,0E,0F,10H,11H
     		SetDateTime();
			Text1 = tt+4+0x11;	//0x11:年
			k = 0x09;
			for(j=6;j>0;j--)
			{
			//高四位
				temp1 = (YC_CMD_BUF[Text1] - 0x33) & 0xF0;
				temp2 = temp1 >> 4;
				TranToMS[k] = temp2 + 0x30;
				k++;
			//低四位
				temp1 = (YC_CMD_BUF[Text1] - 0x33) & 0x0F;
				TranToMS[k] = temp1 + 0x30;
				k +=2;
				Text1 -=1;
			}
  			SendToModule (SetCCLK_SIZE);
			DelaySeconds(2);

  			if(ModulFlags.Bit.EchoModule == 1)
  			{
				ModulFlags.Bit.EchoModule = 0 ;
				Second = (YC_CMD_BUF[tt+0x0C] - 0x33);
				Minute = (YC_CMD_BUF[tt+0x0D] - 0x33);		//分,BCD码
				Hour = (YC_CMD_BUF[tt+0x0E] - 0x33);		//时,BCD码
				Date = (YC_CMD_BUF[tt+0x0F] - 0x33);		//日,BCD码
  			}
  			ByteRecvUART2 = 0;
		}  	    
		else
		{//国标规约,转给电表
			ClearGPRSREG();
			BUFFER_ID = 1;
			SendCMDtoMeter(j);			
		}
	}

//********************************************************************
	if(MeterComm.Bit.aFrame == 0x01)
	{
  	    Nop();
  	    if(BUF_METER[8] == 0x09 && BUF_METER[0x0A] == 0x00)	//掌机命令
  	    {								//BUF_METER[0x0A] = DI0
			HanderCMD();
			ClearMeterREG();			//清除电表标志
  	    	Nop();
  	    }
		else	//:电表回送数据上传
		{
			UploadData();
			ClearMeterREG();			//清除电表标志
  	    	Nop();
		}
	}//END if(MeterComm.Bit.aFrame == 1)
  }//END while (1)
}//END of main()

// *******    子函数   ***************
void B2ASC(void)
{
	if(temp2>=0 && temp2<=9)	//如果字符是十进制数字,返回非0
	{
		temp2 += 0x30;						
	}
	else
	{
		temp2 += 55;
	}
}

void Load645Header(void)
{
	BUF_METER[0] = 0xFE;
	BUF_METER[1] = 0xFE;
	BUF_METER[2] = 0xFE;
	BUF_METER[3] = 0x68;
	BUF_METER[4] = 0x99;
	BUF_METER[5] = 0x99;
	BUF_METER[6] = 0x99;
	BUF_METER[7] = 0x99;
	BUF_METER[8] = 0x99;
	BUF_METER[9] = 0x99;
	BUF_METER[10] = 0x68;
	BUF_METER[11] = 0x01;
	BUF_METER[12] = 0x02;

	YC_CMD_BUF[0] = 0xFE;
	YC_CMD_BUF[1] = 0xFE;
	YC_CMD_BUF[2] = 0xFE;
	YC_CMD_BUF[3] = 0x68;
	YC_CMD_BUF[4] = 0x99;
	YC_CMD_BUF[5] = 0x99;
	YC_CMD_BUF[6] = 0x99;
	YC_CMD_BUF[7] = 0x99;
	YC_CMD_BUF[8] = 0x99;
	YC_CMD_BUF[9] = 0x99;
	YC_CMD_BUF[10] = 0x68;
	YC_CMD_BUF[11] = 0x01;
	YC_CMD_BUF[12] = 0x02;

	SMS_CMD_BUF[0] = 0xFE;
	SMS_CMD_BUF[1] = 0xFE;
	SMS_CMD_BUF[2] = 0xFE;
	SMS_CMD_BUF[3] = 0x68;
	SMS_CMD_BUF[4] = 0x99;
	SMS_CMD_BUF[5] = 0x99;
	SMS_CMD_BUF[6] = 0x99;
	SMS_CMD_BUF[7] = 0x99;
	SMS_CMD_BUF[8] = 0x99;
	SMS_CMD_BUF[9] = 0x99;
	SMS_CMD_BUF[10] = 0x68;
	SMS_CMD_BUF[11] = 0x01;
	SMS_CMD_BUF[12] = 0x02;
}

void ASC2B(void)
{
		if(isdigit(temp2))	//如果字符是十进制数字,返回非0
		{
			temp2 -=0x30;						
		}
		else if(isalpha(temp2))
		{
    		switch (temp2)
    		{
      			case 'A':
      			case 'a':
              		temp2 = 0x0A;
              		break;
      			case 'B':
      			case 'b':
              		temp2 = 0x0B;
              		break;
      			case 'C':
      			case 'c':
              		temp2 = 0x0C;
              		break;
      			case 'D':
      			case 'd':
              		temp2 = 0x0D;
              		break;
      			case 'E':
      			case 'e':
              		temp2 = 0x0E;
              		break;
      			case 'F':
      			case 'f':
              		temp2 = 0x0F;
              		break;
      			default:  
              	return;
    		}    
		}
}
void Proc_SMS(void)
{
	unsigned char ii,DotCounter;
	unsigned int cSum = 0;

	SMS_Start = 0x10;
	
	Index0 = RecvFromMS[15];	//取得这个短信的INDEX
	Index1 = RecvFromMS[16];	//INDEX不能大于99
	LoadCMD_CMGR();
	WaitReturn = 4;
	SendToModule (CMGR_CMGD_SIZE);
	DelaySeconds(4);

	if(ModulFlags.Bit.EchoModule == 1)
	{
		ClearGPRSREG();
  	}
  	else
  	{
		ErrorMSG();
		return;
  	}

	ErrorMSG();							//删除该短信

//加上超时判断,除法改为移位    			
//取出 Address_Length
	temp3 = CMGR_Echo+MGHeader-2;
	if(RecvFromMS[temp3]>='A' && RecvFromMS[temp3]<'G')
	  temp1 = RecvFromMS[temp3]-0x41+0x0A;
	else if(RecvFromMS[temp3]>='0' && RecvFromMS[temp3]<='9')
	  temp1 = RecvFromMS[temp3]-0x30;
	else
	  	return;
	  
	temp3 += 1;
	if(RecvFromMS[temp3]>='A' && RecvFromMS[temp3]<'G')
	  temp2 = RecvFromMS[temp3]-0x41+0x0A;
	else if(RecvFromMS[temp3]>='0' && RecvFromMS[temp3]<='9')
	  temp2 = RecvFromMS[temp3]-0x30;
	else
	  	return;

	Address_Length = temp1 << 4;	//  *16+temp2
	Address_Length = Address_Length + temp2;
	temp3 = Address_Length & 0x01;
	if(temp3 == 1)	//奇数,0DH,要加填充位
	  Address_Length++;
	  
//定位 TP_UDL
	IndexOfTP_UDL = CMGR_Echo + MGHeader + 2 + Address_Length + 18;//18=(1+1+7)*2
	IndexOfTP_DCS = IndexOfTP_UDL - 16;

//解析出TP_DCS:=00 text mode;=08:PDU mode	
	temp1 = RecvFromMS[IndexOfTP_DCS]-0x30;
	temp2 = RecvFromMS[IndexOfTP_DCS + 1]-0x30;
	TP_DCS = temp1 << 4;
	TP_DCS = TP_DCS + temp2;

//解析出TP_UDL
	if(RecvFromMS[IndexOfTP_UDL]>='A' && RecvFromMS[IndexOfTP_UDL]<'G')
	  temp1 = RecvFromMS[IndexOfTP_UDL]-0x41+0x0A;
	else if(RecvFromMS[IndexOfTP_UDL]>='0' && RecvFromMS[IndexOfTP_UDL]<='9')
	  temp1 = RecvFromMS[IndexOfTP_UDL]-0x30;
	else
	  	return;
	  
	if(RecvFromMS[IndexOfTP_UDL + 1]>='A' && RecvFromMS[IndexOfTP_UDL + 1]<'G')
	  temp2 = RecvFromMS[IndexOfTP_UDL + 1]-0x41+0x0A;
	else if(RecvFromMS[IndexOfTP_UDL + 1]>='0' && RecvFromMS[IndexOfTP_UDL + 1]<='9')
	  temp2 = RecvFromMS[IndexOfTP_UDL + 1]-0x30;
	else
	  	return;

	TP_UDL = temp1 << 4;	//  (*16+temp2)/2;
	TP_UDL = TP_UDL + temp2;
	if(TP_DCS == 0x08)	//PDU mode
	{
		TP_UDL = TP_UDL >> 1;
	}
	DataAddr = IndexOfTP_UDL + 2;
//15个字节长的IP地址+port=2020(9个字节长)

/*收到 DL(电量),UDL=04,意指0044 004C,但实际发送过来是8个字节:
30 30 34 34 30 30 34 43
TP_UDL除以2后=2
RecvFromMS[72]、[73]是UDL:30 34
*/
	if(TP_UDL == 0x01)	
	{//短信采集数据
  		if(TP_DCS == 0x08)
	  	{//PDU模式
			temp1 = RecvFromMS[DataAddr+2];	//+2:跳过30 30
			temp2 = RecvFromMS[DataAddr+3];
  		}
  		else
  		{//GSM模式
			temp1 = RecvFromMS[DataAddr];	//GSM模式没30
			temp2 = RecvFromMS[DataAddr+1];
  		}
	 	if(temp1 < '0' || temp1 > '9')	//发过来的是字母:41H~5AH,所以高位是数字
	  		return;

		ASC2B();
		temp3 = (temp1-0x30)<<4 ;
		SMS_CMD = temp3 + temp2;		//D
		if(isalpha(SMS_CMD))	//如果不是字母
		{
			Nop();
		}
		else
		{
			Nop();
	  		return;
		}
//命令解析
// ---------------------------------------------------
		if(SMS_CMD == 'C' || SMS_CMD == 'c')		//C:主站请求连接		{
			OK_Data();
			Close_Shut();
			ConnectIP();
			SendSMS();
		}
		else if(SMS_CMD == 'D' || SMS_CMD == 'd')	//D:当前有功电量、剩余金额采集
		{
// -------   先取回来剩余金额  -----------------
			SMS_CMD_BUF[13] = 0x11 + 0x33;	//DI0
			SMS_CMD_BUF[14] = 0xC9 + 0x33;	//DI1,0x90+0x33=0xC3
			SMS_CHECKSUM();
			BUFFER_ID = 2;
			SendCMDtoMeter(17);
			for(ii = 80;ii > 0;ii--) 	//延时4秒
			{
				if(MeterComm.Bit.aFrame == 0x01)
					break;
  				delay50ms ();
			}
			if(MeterComm.Bit.aFrame == 0x00)
				return;
			MeterComm.Bit.aFrame = 0x00;
			
			for(tt=0;tt<5;tt++)	//找到第一个68H,定位帧头
			{
				if(BUF_METER[tt] == 0x68)
					break;
			}
			leftedM_Addr = tt + 0x0C;
			LeftedMoney[0] = BUF_METER[leftedM_Addr] - 0x33;
			LeftedMoney[1] = BUF_METER[leftedM_Addr+1] - 0x33;
			LeftedMoney[2] = BUF_METER[leftedM_Addr+2] - 0x33;
			LeftedMoney[3] = BUF_METER[leftedM_Addr+3] - 0x33;
			ClearMeterREG();			//清除电表标志
// ------------------------------------------------
			SMS_CMD_BUF[13] = 0x1F + 0x33;	//DI0
			SMS_CMD_BUF[14] = 0x90 + 0x33;	//DI1,0x90+0x33=0xC3
			EnergyOfMonth = 0;
			
			SMS_CHECKSUM();
			BUFFER_ID = 2;
			SendCMDtoMeter(17);
			for(ii = 80;ii > 0;ii--) 	//延时4秒
			{
				if(MeterComm.Bit.aFrame == 0x01)
					break;
  				delay50ms ();
			}
			if(MeterComm.Bit.aFrame == 0x00)
				return;
			MeterComm.Bit.aFrame = 0x00;
			SMS_Energy();
		}
		else if(SMS_CMD == 'J' || SMS_CMD == 'j')	//J:用短信检测是否死机
		{
			OK_Data();
			//发送短信
			SendSMS();
		}
		else if(SMS_CMD == 'R' || SMS_CMD == 'r')	//R:module复位命令
		{
			OtherFlags.Bit.TCPLink = 0;
			OnlineLed = HIGH;			//关闭在线灯
			OK_Data();
			Close_Shut();
			ReInitial();
			SendSMS();		//发送短信
		}
		else if(SMS_CMD == 'S' || SMS_CMD == 's')	//S:上月电量
		{
			SMS_CMD_BUF[13] = 0x1F + 0x33;	//DI0
			SMS_CMD_BUF[14] = 0x94 + 0x33;	//DI1,0x94+0x33=0xC7
			EnergyOfMonth = 1;
			
			SMS_CHECKSUM();
			BUFFER_ID = 2;
			SendCMDtoMeter(17);
			for(ii = 80;ii > 0;ii--) 	//延时4秒
			{
				if(MeterComm.Bit.aFrame == 0x01)
					break;
  				delay50ms ();
			}
			if(MeterComm.Bit.aFrame == 0x00)
				return;
			MeterComm.Bit.aFrame = 0x00;
			SMS_Energy();
		}
		else if(SMS_CMD == 'T' || SMS_CMD == 't')	//T:读module时间
		{
			LoadCMD_CCLK();
			WaitReturn = 2;
			SendToModule (CCLK_SIZE);
			DelaySeconds(2);
//
  			if(ModulFlags.Bit.EchoModule == 1)

⌨️ 快捷键说明

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