📄 main.c
字号:
{
/* AT+CIPSTART只有在IP_INITIAL、IP_CLOSE、IP_STATUS状态下
才可以进行连接的建立,连接建立成功后的状态为CONNECT OK;
连接失败,则处在失败的状态上。
*/
for(k=0;k<AT_CMGS_SIZE;k++)
{
TranToMS[k] = AT_CMGS_buf[k];
}
}
void LoadCMD_CIPCLOSE(void)
{
for(k=0;k<CIPCLOSE_SIZE;k++)
{
TranToMS[k] = Ip_close_buf[k];
}
}
void LoadCMD_CIPSHUT(void)
{
for(k=0;k<CIPSHUT_SIZE;k++)
{
TranToMS[k] = Ip_shut_buf[k];
}
}
void ConfigInt(void)
{
RCONbits.IPEN = 0;
PIE1bits.RC1IE=1; // USART1 receive interrupt enable
PIE3bits.RC2IE=1; // USART2 receive interrupt enable
PIE1bits.TMR1IE=1;
INTCONbits.PEIE=1; //Peripheral interrupt enable
INTCONbits.GIE=1;
}
void Timer1_setup(void)
{
TMR1H = hibyte(T1DELAY);
TMR1L = lobyte(T1DELAY);
T1CONbits.T1CKPS0 = 1;
T1CONbits.T1CKPS1 = 1; //八分频
T1CONbits.T1OSCEN = 0; //不使用内部振荡
T1CONbits.TMR1CS = 0; //fOSC/4=TCYC
T1CONbits.TMR1ON = 1; //启动TMR1
}
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 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。
*/
MaxTry = 0;
while(1)
{
LoadCMD_AT();
SendToModule (3);
DelaySeconds(5);
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;
break;
}//END if(cRet == 0)
PassSeconds(1);
}//END if(ModulFlags.Bit.EchoModule == 1)
ResetModule();
ClearGPRSREG();
MaxTry++;
if(MaxTry > 2)
break;
}//END
//在这先发ATE0命令,设置为命令无ECHO
LoadCMD_ATE0();
MaxTry = 0;
while(1)
{
SendToModule (ATE0_SIZE);
delay200ms (); //如果只延时20ms,就只能收到回送15个字节
if(ModulFlags.Bit.EchoModule == 1)
{
if(RecvFromMS[2]==_O && RecvFromMS[3]==_K)
{
ModulFlags.Bit.RecvEcho = 0;
break;
}//END if(ModulFlags.Bit.EchoModule == 1)
}
MaxTry++;
if(MaxTry > 2)
break;
}//END while(1)
//at+creg=1 enable network registration unsolicited result code +CREG:
//<stat>
MaxTry = 0;
while(1)
{
LoadCMD_CREG();
SendToModule (CREG_SIZE);
DelaySeconds(2);
if(ModulFlags.Bit.EchoModule == 1)
{
cRet = strncmppgm2ram((char *)RecvFromMS,(const far rom char *)OK,L_OK);
if(cRet == 0)
{
ModulFlags.Bit.EchoModule = 0;
break ;
}//END if(FrameFlag.Bit.EchoModule == 1)
}
ResetModule();
PassSeconds(10);
ClearGPRSREG();
//在这再次发ATE0命令,设置为命令无ECHO
LoadCMD_ATE0();
SendToModule (ATE0_SIZE);
PassSeconds(1);
ModulFlags.Bit.EchoModule = 0;
MaxTry++;
if(MaxTry > 9)
break;
}//END of while(1)
/*at+creg?: 检查DTU有没有登陆(附着attach)GPRS网络
如返回的是1则表示进入GPRS 网络,如返回的是0 则表示还未登入GPRS 网络。
*/
MaxTry = 0;
while(1)
{
LoadCMD_CREGAsk();
WaitReturn = 2;
SendToModule (CREG_ASK_SIZE);
DelaySeconds(4);
if(ModulFlags.Bit.EchoModule == 1)
{
cRet = strncmppgm2ram((char *)RecvFromMS,(const far rom char *)CREGSta_buf,L_CREGSta);
if(cRet == 0)
{
ModulFlags.Bit.EchoModule = 0;
WaitReturn = 0;
break ;
}//END if(ModulFlags.Bit.EchoModule == 1)
}
PassSeconds(2);
MaxTry++;
if(MaxTry > 2)
break;
}//END of while(1)
//默认是CMGF=0 PDU模式,再初始化成UCS2编码
LoadCMD_CSCS();
MaxTry = 0;
while(1)
{
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;
break;
}//END if(cRet == 0)
PassSeconds(2);
}//END if(ModulFlags.Bit.EchoModule == 1)
MaxTry++;
if(MaxTry > 2)
break;
}
LoadCMD_CIPSPRT(); //设at+cipsprt=0 之后,发完cipsend后,不需大于号和空格
MaxTry = 0;
while(1)
{
SendToModule (CIPSPRT_SIZE);
delay50ms (); //如果只延时20ms,就只能收到回送15个字节
if(ModulFlags.Bit.EchoModule == 1)
{
if(RecvFromMS[2]==_O && RecvFromMS[3]==_K)
{
ModulFlags.Bit.EchoModule = 0;
ModulFlags.Bit.RecvEcho = 0;
break ;
}//END if(ModulFlags.Bit.EchoModule == 1)
}
MaxTry++;
if(MaxTry > 2)
break;
}//END while(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)
R_eeprom((char *)Link_Mode,LinkMode,2);
//at+cdnsorip=1:connect with domain name
//at+cdnsorip=0:connect with ip address
MaxTry = 0;
while(1)
{
if(Link_Mode[0] ==_I && Link_Mode[1] ==_P)
{
LoadCMD_CIPLINK();
}
else
{
LoadCMD_CDNSLINK();
}
SendToModule (AT_CDNSORIP_SIZE);
DelaySeconds(2);
if(ModulFlags.Bit.EchoModule == 1)
{
cRet = strncmppgm2ram((char *)RecvFromMS,(const far rom char *)OK,L_OK);
if(cRet == 0)
{
ModulFlags.Bit.EchoModule = 0;
break ;
}//END if(FrameFlag.Bit.EchoModule == 1)
}
PassSeconds(2);
MaxTry++;
if(MaxTry > 2)
break;
}//END of while(1)
//config DNS
MaxTry = 0;
while(1)
{
LoadCMD_CDNSCFG();
SendToModule (AT_CDNSCFG_SIZE);
DelaySeconds(2);
if(ModulFlags.Bit.EchoModule == 1)
{
cRet = strncmppgm2ram((char *)RecvFromMS,(const far rom char *)OK,L_OK);
if(cRet == 0)
{
ModulFlags.Bit.EchoModule = 0;
break ;
}//END if(FrameFlag.Bit.EchoModule == 1)
}
PassSeconds(2);
MaxTry++;
if(MaxTry > 2)
break;
}//END of while(1)
MaxTry = 0;
while(1)
{
LoadCMD_CIPDPDP();
SendToModule (L_Cipdpdp);
DelaySeconds(2);
if(ModulFlags.Bit.EchoModule == 1)
{
cRet = strncmppgm2ram((char *)RecvFromMS,(const far rom char *)OK,L_OK);
if(cRet == 0)
{
ModulFlags.Bit.EchoModule = 0;
break ;
}//END if(FrameFlag.Bit.EchoModule == 1)
}
PassSeconds(2);
MaxTry++;
if(MaxTry > 2)
break;
}//END of while(1)
}//END Module_Init()
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;
IPDHead = 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++)
{
GenParity(BUF_METER[k]);
if(parity == 1)
TXSTA1bits.TX9D = 1;
else
TXSTA1bits.TX9D = 0;
TXREG1 = BUF_METER[k];
while(1)
{
if(PIR1bits.TX1IF == 1) break;
}
delay10ms();//字节间延时至少10ms!!!
}
while(1)
{
if(TXSTA1bits.TRMT == 1) break; //最后一个字节也发完
}
// delay10ms(); //江苏表回送很快,不能加延时
// delay4ms();
EN485 = EnReceive;
TXSTA1bits.TXEN = 0; //发送禁止
RCSTA1bits.CREN = 1; //接收数据允许
RCSTA1bits.FERR = 0;
PIE1bits.TMR1IE = 1; //打开定时中断
}
void GenParity(unsigned char DataWillSend)
{
unsigned char gp,tt;
gp = DataWillSend;
parity = 0;
tt = gp & 0x01;
if(tt != 0)
parity ^=0x01;
tt = gp & 0x02;
if(tt != 0)
parity ^=0x01;
tt = gp & 0x04;
if(tt != 0)
parity ^=0x01;
tt = gp & 0x08;
if(tt != 0)
parity ^=0x01;
tt = gp & 0x10;
if(tt != 0)
parity ^=0x01;
tt = gp & 0x20;
if(tt != 0)
parity ^=0x01;
tt = gp & 0x40;
if(tt != 0)
parity ^=0x01;
tt = gp & 0x80;
if(tt != 0)
parity ^=0x01;
}
void CHECKSUM(void)
{
unsigned int CXOR = 0;
for(k=0;k<10+BUF_METER[12];k++)
{
CXOR = CXOR + BUF_METER[3+k];
}
BUF_METER[3+10+BUF_METER[12]] = (unsigned char)CXOR;
BUF_METER[3+10+BUF_METER[12]+1] = 0x16;
}
void PowerDownModule(void)
{
ONOFF = LOW; //power down
PassSeconds(6);
ONOFF = HIGH;
PassSeconds(3);
}
void ResetModule(void)
{
/* 怎么将 modem 复位?
软件:通过使用指令 AT+CFUN=0,然后,再输入 AT+CFUN=1
硬件:将 reset 脚接地,至少300 毫秒。平时不用的时候,将它空置。
*/
ClearGPRSREG();
RSTModule = 0; //复位信号低电平有效,低电平脉冲宽度应不小于100mS
PassSeconds(2);
RSTModule = 1;
WaitReturn = 0;
DelaySeconds(10);
// while(!ModulFlags.Bit.EchoModule);
PassSeconds(1);
ClearGPRSREG();
for (k = 0; k < 32; k++) //clear module 应答区
{
RecvFromMS[k] = 0;
}
}
void W_eeprom(char *pData,unsigned int addr,unsigned char DataLen)
{
EEADRH = hibyte(addr);
EEADR = lobyte(addr);
EECON1bits.EEPGD=0;
EECON1bits.CFGS=0;
EECON1bits.WREN=1;
INTCONbits.GIE = 0;
for (k = 0; k < DataLen; k++)
{
EEDATA=pData[k];
EECON2=0x55;
EECON2=0xAA;
EECON1bits.WR=1;
while (!PIR2bits.EEIF)
;
PIR2bits.EEIF=0;
EEADR++;
}
EECON1bits.WREN = 0;
INTCONbits.GIE = 1;
}
void R_eeprom(char *pData,unsigned int addr,unsigned char DataLen)
{
EEADRH = hibyte(addr);
EEADR = lobyte(addr);
EECON1bits.EEPGD=0; // Point to DATA memory
EECON1bits.CFGS=0;
INTCONbits.GIE = 0;
for (k = 0; k < DataLen; k++)
{
EECON1bits.RD=1;
temp1 = EEDATA;
pData[k] = temp1;
EEADR++;
}
INTCONbits.GIE = 1;
}
void Proc_err(void)
{
/* 连接未建立或已被断开, 返回 ERROR
如果数据发送成功, 返回 SEND OK
如果数据发送失败, 返回 SEND FAIL
*/
if(strncmppgm2ram((char *)RecvFromMS,(const far rom char *)ERROR,L_ERROR) == 0)
{//server软件未启动TCP服务
Close_Shut();
}//END of if(strncmppgm2ram((char *)RecvFromMS,ERROR,L_ERROR) == 0)
else if(strncmppgm2ram((char *)RecvFromMS,(const far rom char *)CLOSED,L_CLOSED) == 0)
{//假链接
Close_Shut();
}
else if(strncmppgm2ram((char *)RecvFromMS,(const far rom char *)SEND_FAIL,L_SEND_FAIL) == 0)
{//发送失败,可能尚未建立连接
Close_Shut();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -