📄 单字节短信采集 main.c
字号:
//
// GPRS data terminal unit
// MPLAB6.30 + C18 2.40.01
//
#include <p18f6520.h> /* for the special function register declarations */
//#include <portb.h> /* for the RB0/INT0 interrupt */
#include <usart.h>
#include <string.h>
#include <ctype.h>
//#include <stdlib.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];
#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 RecvMeter:1;
unsigned RX9D_copy:1;
unsigned :1;
} 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 :4;
} Bit;
unsigned char tTemp;
} TempFlag;
#pragma udata my_data1 = 0x0100
//SECTION NAME=my_data RAM=gpr1;
unsigned char TranToMS[DataLength];
unsigned char delayus_variable;
unsigned char WaitReturn; //=0:发送的是初始化帧,接受到除了起始符外的回车即收到一帧
//=3:发送的是cipstart,需要接收3个回车,相当于两帧
//=4:发送的是cmgr,需要接收4个回车,相当于3帧
unsigned int IPAddressSeted;
// *****************************************************************
//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_CIPSTART(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 ConvertToUCS2();
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(!Flags.Bit.RecvMeter)
{//未收到68H
if(RevTemp == 0x68)
Flags.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 > DataLength) //大于最大长度
{
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;
}
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(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 SEPosition,PEPosition,DEPosition,LEPosition;
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)
// ------------------------------------------------------------
//比较收到的是否短信通知 +CMTI:
else if(strncmppgm2ram(RecvFromMS,PLUSCMTI,L_PLUSCMTI) == 0)
{
Proc_SMS();
FrameFlag.Bit.EchoModule = 0 ;
Flags.fCOMM = 0;
ByteRecvUART2 = 0;
}
else if(strncmppgm2ram(RecvFromMS,Module_RDY,RDY_SIZE) == 0)
{//对module进行了复位
Module_Init(); //只复位不掉电,module是否还是UCS编码?
ClearCommREG();
}
else
{//收到的不是短信,错误处理
ClearCommREG();
}
}//END of if(FrameFlag.Bit.EchoModule)
//********************************************************************
//改成:cRet = strncmppgm2ram()
if(FrameFlag.Bit.CMD_Frame == 1)
{
for(j=0;j<Length;j++)
{
BUF_METER[j] = RecvFromMS[IPDHead + j]; //将主站的接收缓冲区的数据
} //转送到电表的通讯缓冲区
SendCMDtoMeter(j);
ClearCommREG();
}
//********************************************************************
if(FrameFlag.Bit.REV_Meter == 1)
{
if(TempFlag.Bit.SMS_GetData == 1)
{//短信采数
for(tt=0;tt<SMS_Header1_SIZE;tt++)
{
SMS_Return[tt] = SMS_Header1[tt];
}
NOAddr = SMS_Start + 0x18;
for(tt=0;tt<Address_Length;tt++)
{
//对方号码
SMS_Return[SMS_Header1_SIZE+tt] = RecvFromMS[NOAddr+tt];
}
for(tt=0;tt<SMS_Header2_SIZE;tt++)
{
SMS_Return[SMS_Header1_SIZE+Address_Length+tt] = SMS_Header2[tt];
}
UDLAddr = SMS_Header1_SIZE+Address_Length+SMS_Header2_SIZE;
//计算出UDL...
//总:---------------------------------------------------
EnergyDataAddr = UDLAddr+2;
for(tt=0;tt<TotalE_Length;tt++)
{
SMS_Return[EnergyDataAddr+tt] = TotalE[tt]; //装载 有功总:
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -