📄 main12.c
字号:
/*
当给模块主电源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 + -