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

📄 pdu手机采老威胜电量成功 main.c

📁 PIC18F6520+SIM300做的透明传输的DTU
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// GPRS data terminal unit
// MPLAB6.30 + C18 2.40.01
// MPLAB7.10 + C18 2.42
//
#include <p18f6520.h>  /* for the special function register declarations */
#include <usart.h> 
#include <string.h> 
#include <ctype.h>
#include "Parameters.h"
#include "always.h"
#include "delay.h"

#include "FuntionPin.h"

/* Set configuration bits for use with ICD2 / PICDEM2 PLUS Demo Board:
 *  - set HS oscillator
 *  - disable watchdog timer
 *  - disable low voltage programming
 *  - enable background debugging
 */
#pragma config CP0 = ON
#pragma config CP1 = ON
#pragma config CP2 = ON
#pragma config OSC = HS		////XT
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config DEBUG = ON


#define STRING_TABLE_SIZE 6
#define MAX_ARRAY_SIZE 100
#define CMGR_Echo 16
#define MGHeader 22	//从短信的第一个字符08截至到目的号码长度
//#define MGHeader 29*2		//字符用ASCII码表示


//unsigned static word *SERIALBUFFER=0x01A0;
//unsigned char * tBuffer =0x60;
//char *str1;

#pragma udata mydata2 =0x0200		//初始化了的数据放到idata
unsigned char RecvFromMS[178];		//AT+CMGR的回送最长142,再加上port=2020(9x4=36)
unsigned char Ip_start_buf2[15];	//MAX:15
unsigned char EnergyData[4],EnergyDataUCS2[36];
//unsigned char MeterNumber[6];
unsigned char delayus_variable;
unsigned char WaitReturn;		//=0:发送的是初始化帧,接受到除了起始符外的回车即收到一帧
						//=3:发送的是cipstart,需要接收3个回车,相当于两帧
						//=4:发送的是cmgr,需要接收4个回车,相当于3帧
unsigned char SEPosition,PEPosition,DEPosition,LEPosition;
unsigned int IPAddressSeted;

#pragma udata mydata3 =0x0300
//每一个section的空间不能超过256个,利用对数组的初始化就可以把它定义到别的section。
unsigned char BUF_METER[256];		//

#pragma udata mydata4 =0x0400		//短信数据
//短信最长140+15=155(还有一个长度字节,则数组定义为156)
unsigned char SMS_Return[DataLength];

//!!注意用法:#pragma udata access MY_ACS_DATA
//	    	near unsigned char root, square;
//		#pragma udata  /* continue allocating static data in non-access ram */

#pragma udata access my_access		//放入ACCESS BANK
//定义一个数组存储发送数据
near unsigned int RevWaitDelay,RWDTemp;
near unsigned int OverTimeMeter,OverTimeGPRS;
near unsigned int cMinute,t1use,PWRUP55AA;
near unsigned char k,j,tt,cRet,ByteReceived,ByteRecvUART2,DataAddr,parity;
near unsigned char LengthCipstart,LengthCipsend,LengthBUF2,LengthIP;
near unsigned char dLength,tempArr[3];
near unsigned char Address_Length,IndexOfTP_UDL,TP_UDL,CMGR_CMGD_SIZE,Index0,Index1;
near unsigned char MinCounter,temp1,temp2,temp3;
near unsigned char SMS_CMD[2],NOAddr,NOLength;
near unsigned char EnergyDataAddr,UDLAddr,UDLLength,SMS_Start,AllLength;
near volatile unsigned int T1DELAY;
near volatile unsigned char ReceivedReturn;
near volatile unsigned char RevTemp,IPDHead,Length;
near volatile unsigned char CMDLengthLow,CMDLengthHigh;


//*********    位域定义    ***********
near union
{		//用法:if (Flags.Bit.Timeout == 1)
  struct
  {
    unsigned RecvUART2:1;
    unsigned RecvEcho:1;		//收到module的应答 or 主动上报的状态
    unsigned RecvGPRS:1;		//收到主站从GPRS信道传过来的命令
    unsigned :2;
    unsigned RX9D_copy:1;
    unsigned :2;
  } Bit;
  unsigned char fCOMM;
} Flags;

near union
{		//用法:if (Flags.Bit.Timeout == 1)
  struct
  {
    unsigned CMD_IP:1;		//主站用GPRS信道发来的命令
    unsigned EchoModule:1;	// 初始化module,module的应答
    unsigned REV_Meter:1;	//收到电表回送的一帧
    unsigned CMD_Frame:1;	//收到主站的命令帧
    unsigned :4;
  } Bit;
  unsigned char FrameBYTE;
} FrameFlag;

near union
{		
  struct
  {
    unsigned TCPLink:1;
    unsigned Error:1;
    unsigned LinkClosed:1;
    unsigned Recved16H:1;
    unsigned Recved0DH:1;
    unsigned :3;
  } Bit;
  unsigned char ModuleBYTE;
} ModuleSta;

near union
{		
  struct
  {
    unsigned TimerOver:1;
//    unsigned minute:1;
    unsigned :7;
  } Bit;
  unsigned char fTime;
} TimeFlag;

near union
{		
  struct
  {
	unsigned f0:1;
	unsigned f1:1;
	unsigned GPRS_CMD:1;
	unsigned SMS_GetData:1;
	unsigned CMGSSent:1;
    unsigned RecvMeter:1;
	unsigned isWEISHENG:1;
    unsigned :1;
  } Bit;
  unsigned char tTemp;
} TempFlag;


#pragma udata my_data1 = 0x0100
unsigned char TranToMS[DataLength];
#pragma udata datatest = 0x0060
unsigned char DepNOLow,DepNOHigh;
unsigned long EnergyValue=0,LeftLong=0,MidLong=0;
unsigned long LargeValueHigh=0,LargeValueLow=0;

// *****************************************************************
//funtion prototype
void INT_Procedure (void);   /* prototype needed for 'goto' below */

void LoadCMD_AT(void);
void LoadCMD_CSCS(void);
void LoadCMD_ATE0(void);
void LoadCMD_CIPSPRT(void);
void LoadCMD_CGATT(void);
void LoadCMD_CIPHEAD(void);
void LoadCMD_CIPSTATUS(void);
void LoadCipstartBuf(void);
void LoadCMD_CIPSEND(void);
void LoadCMD_CMGS(void);
void LoadCMD_DATA(void);
void LoadCMD_CIPCLOSE(void);
void LoadCMD_CIPSHUT(void);
void LoadCMD_CMGR(void);
void LoadCMD_CMGD(void);

void ClearCommREG(void);
void GenParity(unsigned char DataWillSend);
void CHECKSUM(void);
void SendCMDtoMeter(unsigned char num);
void Proc_SMS(void);
void RetSMS(void);
void WS_RetSMS(void);
void HandleData(unsigned char ei);
void ConvertToUCS2(void);
void ASC2B(void);
void B2ASC(void);
void Load645Header(void);
void ErrorMSG();

void Timer1_setup(void);
void Proc_TimerOver(void);
void Proc_min(void);
void ConfigInt(void);
void Module_Init(void);
void PowerDownModule(void);
void PowerOnModule(void);
void ResetModule(void);


void W_eeprom(char *pData,unsigned int addr,unsigned char DataLen);
void R_eeprom(char *pData,unsigned int addr,unsigned char Datalen);

void ReadDynamicIP(void);
void ReLink(void);
void Proc_err(void);

void InitPeriph(void);
void UART1_setup(void);
void UART2_setup(void);
void SendToModule(unsigned int num);

/* delay10ms is found in an assembly file */
extern void delay4ms (void);
extern void delay10ms (void);
extern void delay20ms (void);
extern void delay50ms (void);
extern void delay200ms (void);
// ************************************************************************

#pragma code LOW_INTERRUPT_VECTOR = 0x08
void low_ISR (void) 
{
  _asm
    goto INT_Procedure
  _endasm
}

#pragma code  /* allow the linker to locate the remaining code */

//*************   中断处理程序   ****************
#pragma interrupt INT_Procedure
void INT_Procedure (void) 
{
  volatile unsigned char tLength,arr;
  if(PIR1bits.TMR1IF)		//250ms中断一次
  { 
  		T1CONbits.TMR1ON = 0;	//关闭TMR1
		TMR1H = hibyte(T1DELAY);
		TMR1L = lobyte(T1DELAY);	
		T1CONbits.TMR1ON = 1;	//启动TMR1
  		PIR1bits.TMR1IF = 0;
	
		TimeFlag.Bit.TimerOver = 1;

		RevWaitDelay++;
  }//END if(PIR1bits.TMR1IF)
  
// -------------------------------------------------------------
// 在这里处理从电表收到的应答。
  if(PIR1bits.RC1IF)		//串口 1 与电表连接,加超时处理
  {							//1200bps,8,E
  	RevTemp = RCREG1;		//读RCREG1清PIR1bits.RCIF
	OverTimeMeter = 0;	//清零防止接收超时
//是与威胜表通信?
	if(TempFlag.Bit.isWEISHENG == 1)
	{
		BUF_METER[ByteReceived]=RevTemp;
		ByteReceived++;
		if(RevTemp == _CR)
		{
			FrameFlag.Bit.REV_Meter = 1;
			ByteReceived = 0;
		}
	}
  else
  {
	if(!TempFlag.Bit.RecvMeter)
	{//未收到68H
		if(RevTemp == 0x68)
		  TempFlag.Bit.RecvMeter = 1;
		else
		  return;
	}
// 读出接收到的第9位数据
  	if(RCSTA1bits.RX9D==1)
  	  Flags.Bit.RX9D_copy=1;
  	else
  	  Flags.Bit.RX9D_copy=0;
  
// 计算偶校验位,与RX9D_copy比较 ......
// 清除OERR
	RCSTA1bits.OERR=0;
	if(ByteReceived<=9)
	{  
	  switch (ByteReceived)
    	  {
      		case 0:
      		case 7:
				if(RevTemp==0x68)
	     	  	{  
	     	  		BUF_METER[ByteReceived]=RevTemp;
	     	     	ByteReceived++;
	     	  	}
                break;

      		case 8:
//                  if((RevTemp & 0x80)==0)		//上海规约 BIT7=0:电表回送数据
//	     	  {  								//DL/T645国标 BIT7=1:电表回送数据
				BUF_METER[ByteReceived]=RevTemp;	
	     	   	ByteReceived++;
//	     	  }
                break;
      		case 9:
				if(RevTemp > 250)	//大于最大长度
                {
		     		ByteReceived = 0;
                    break;
		  		}
		  //否则往下执行
      		default:  
		  		BUF_METER[ByteReceived]=RevTemp;
		  		ByteReceived++;
                break;
    	  }//end switch  
	}//end if(ByteReceived<=9)
	else
	{  
		arr=BUF_METER[9]+11;		//DI0,DI1记入长度L,此处对两个规约的处理一样
	   	if(ByteReceived >= arr)
	   	{
	   		if(RevTemp == 0x16)
	   		{  
	   	   		BUF_METER[ByteReceived] = RevTemp;
	   	   		FrameFlag.Bit.REV_Meter = 1;
	   	   		TempFlag.Bit.RecvMeter = 0;
	   		}
			ByteReceived = 0;
	   }
	   else
	   {
	     	BUF_METER[ByteReceived]=RevTemp;
	     	ByteReceived++;
	   }
	}
   }
  }//END if(PIR1bits.RCIF)

//--------------------------------------------------
  if(PIR3bits.RC2IF)		//串口 2 与module连接
  {							//9600bps,8,N
/////////////////////////////////////////////////////////
//	RecvFromMS[ByteRecvUART2]=RCREG2;
//	ByteRecvUART2++;
/////////////////////////////////////////////////////////

  	RevTemp=RCREG2;			//读RCREG2清PIR3bits.RCIF
	OverTimeGPRS = 0;

	if(Flags.Bit.RecvUART2 == 0)
	{//未收到0D 起始符
		if(RevTemp == _CR)
		{
		  Flags.Bit.RecvEcho = 1 ;
		  Flags.Bit.RecvUART2 = 1;
		  RecvFromMS[ByteRecvUART2]=RevTemp;
	 	  ByteRecvUART2++;
		}
		else if(RevTemp == _PLUS)	//=+:远端(主站)数据
		{
		  Flags.Bit.RecvGPRS = 1 ;
		  Flags.Bit.RecvUART2 = 1;
		  RecvFromMS[ByteRecvUART2]=RevTemp;
	 	  ByteRecvUART2++;
		}
		else
		  return;
	}
	else if(RevTemp == _CR && ByteRecvUART2 == 1)	//连续收到两个回车
	{//在发送ate0之前,echo回来的命令以回车结束
		Nop();		//同样的回车不用存,直接退出就行了
	}
//已收到CR 起始符
	else
	{
		RecvFromMS[ByteRecvUART2]=RevTemp;
		ByteRecvUART2++;

		if(Flags.Bit.RecvEcho == 1)
		{
		  if(TempFlag.Bit.CMGSSent == 1)
		  {
		  	if(RevTemp == _SPACE)
		  		FrameFlag.Bit.EchoModule = 1;
		  }
		  if(RevTemp == _CR)
		  {
		  	if(WaitReturn == 3)
		  	{
		  		ReceivedReturn++;
		  		if(ReceivedReturn == 3) 
				{
		  	  		FrameFlag.Bit.EchoModule = 1 ;
			  		ReceivedReturn = 0;
				}
		  	}
		  	else if(WaitReturn == 4)
		  	{
		  		ReceivedReturn++;
		  		if(ReceivedReturn == 4) 
				{
		  	  		FrameFlag.Bit.EchoModule = 1 ;
			  		ReceivedReturn = 0;
				}
		  	}
		  	else FrameFlag.Bit.EchoModule = 1 ;
		  }
		}//END of if(Flags.Bit.RecvEcho == 1)
//=+:远端(主站)数据
		if(Flags.Bit.RecvGPRS == 1)
		{
//从DL/T645协议帧包里取出真正的长度,因为多功能表的前导符FE是0~4个字节长
		  if(RevTemp == _COLON && ByteRecvUART2 >4  && ByteRecvUART2 <8)	
//收到:后就可以取出长度
		  {
				CMDLengthLow = RecvFromMS[ByteRecvUART2-2];
				CMDLengthLow -= 0x30;
				if(RecvFromMS[ByteRecvUART2-3] == _D)	// || RecvFromMS[ByteRecvUART2-2] == _d)
				{
	  				Length = CMDLengthLow;
				}
				else
				{
					CMDLengthHigh = RecvFromMS[ByteRecvUART2-3];
	  				CMDLengthHigh -= 0x30;
					tLength = CMDLengthHigh;
	  				Length = tLength <<3;
//转换成10进制	  				
	  				Length = Length + CMDLengthHigh + CMDLengthHigh + CMDLengthLow;
					
				}
				IPDHead = ByteRecvUART2;
		  }//BED of if(RevTemp == _COLON && ByteRecvUART2 >4  && ByteRecvUART2 <8)	
	  	  if(ByteRecvUART2 == IPDHead + Length)//+IPDxx:FE.. 68 NO 68 CMD L CHECKSUM 16
	  	  {
			FrameFlag.Bit.CMD_Frame =1;
			TempFlag.Bit.GPRS_CMD = 1;
	  	  }
		}//END of if(Flags.Bit.RecvGPRS == 1)
	}//END of else
  	if(ByteRecvUART2 > 199)
  		ByteRecvUART2 = 0;	//从模块收到的应答超过200字节,可能是超长短信
  }//END if(PIR3bits.RCIF)

}//END void INT_Procedure (void)


void main (void) 
{
  unsigned char *p;
  near unsigned int ClearNum;
  
  p = 0000;
  if(PWRUP55AA != 0x55AA)
  {
  	for(ClearNum = 1280;ClearNum>0;ClearNum--) 	
  	{
 		*p = 0;
		p ++;
  	}
  }
  
  for(k=20;k>0;k--) 	//延时1秒
  {
 	delay50ms ();
  }
  
  InitPeriph();
  UART1_setup ();
  UART2_setup ();
  Timer1_setup();
  ConfigInt();				//中断配置

  if(PWRUP55AA != 0x55AA)
  {
/*
	for(k=80;k>0;k--) 	//延时16秒
  	{
 		delay200ms ();
  	}
*/
 	Module_Init();
 	PWRUP55AA = 0x55AA;
  }
  T1DELAY = T1_TICK;
  t1use = OneMinute;

  while (1)
  {
	CLRWDT();
	
	if(TimeFlag.Bit.TimerOver == 1)		//到定时的时间?
	{
	  Proc_TimerOver();
	}

// ------------------------------------------------------------    
	if(FrameFlag.Bit.EchoModule)
	{
  	  	if(strncmppgm2ram(RecvFromMS,CLOSED,L_CLOSED) == 0)
	  	{
//=0:TCP链接已断开(但移动场景没关闭),重建
  			ModuleSta.Bit.LinkClosed = 1;	//主站因故断了连接,每分钟重连一次
			ModuleSta.Bit.TCPLink = 0;

	  		FrameFlag.Bit.EchoModule = 0 ;
	  		Flags.fCOMM = 0;
   	  		ByteRecvUART2 = 0;
	  	}//END of if(cRet == 0)
// ------------------------------------------------------------    

⌨️ 快捷键说明

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