资源描述
//=====GPRS MODULE PROGRAM=============
//==FROM 2003.9.=======================
//=======by cfj========================
#include<msp430x12x2.h>
//#include<intrinsics.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include<math.h>
#define Uint unsigned int
#define _3NOP() _NOP();_NOP();_NOP();
#define _4NOP() _NOP();_NOP();_NOP();_NOP();
#define _5NOP() _NOP();_NOP();_NOP();_NOP();_NOP();
#define Estart_Addr 0 //0 EEprom起始地址
#define Work_Mode_Addr Estart_Addr+6 //6 工作模式设置:1字节
#define MAPN_Addr Work_Mode_Addr+1 //7 移动网关接入点名称:20字节ASCI#define DSC_Ip_Addr MAPN_Addr+20 //27 数据服务中心IP地址:12字节ASC#define DSC_Port_Addr DSC_Ip_Addr+12 //39 数据中心端口:5字节ASCII#define Net_Protocol_Addr DSC_Port_Addr+5 //44 网络数据传输协议
#define Terminal_SIM_Addr Net_Protocol_Addr+1 //45 终端SIM
#define Beat_Addr Terminal_SIM_Addr+11 //56 心跳周期地址
#define PassWord_Addr Beat_Addr+1 //57 设置密码
#define SCA_SIM_Addr PassWord_Addr+6 //63 短信服务中心号码
#define DSC_SIM_Addr SCA_SIM_Addr+11 //74 数据中心号码
#define BackUp_Addr DSC_SIM_Addr+11 //85 备用
#define Set_Crc BackUp_Addr+4 //89 CRC校验码
#define Estart2_Addr Estart_Addr+100
//******************************************************************
//函数:main()
//功能:主函数
//输入参数:
//输出参数:
//==============================================================================//常量定义
//==============================================================================char *AT="AT\r";//AT命令用于检测GPRS是否存在或开机。
char AT_Echo[12]={'A','T','E','=','0','V','=','1','&','D','1',0X0D};//命令码不返回。//char *AT_Echo="ATE=0V=1&D1\r";//命令码不返回。
char *AT_O="ATO\r";//从命令状态返回到数据状态。
char *AT_3Plus="+++AT\r";
char *AT_W="AT&W\r"; //保存设置。
char *AT_ActivateIp="AT*E2IPA=1,1\r";
char OpenIp[11]={'A','T','*','E','2','I','P','O','=','1',',',};
char *AT_CloseIp="AT*E2IPC\r";//关闭GPRS通道
char *AT_CMGF="AT+CMGF=0\r";//短信PDU MODE
char Terminal_Command[19]={0x68,0x0d,0x0d,0x68,0x4a,0x99,0x99,0x07,0x00,0x0b,0x80,0x30char Echo_Array[]={0X2F,0X00,0X07,0XFF,0XFF,0XFD,0XA3,0X03};//设置正确信号
char Alarm_Switch_Echo[]={0X2F,0X00,0X08,0XFF,0XFF,0XCE,0XEC,0X8F,0X14};
char Data_Switch_Echo[]={0X2F,0X00,0X08,0XFF,0XFF,0XCD,0XEC,0XDA,0X47};
//==============================================================================//函数定义
//==============================================================================void Port_Initial(void);
void Delay(Uint);
void First_Wr_EEprom(void);
void Variable_Initial(void);
void Turn_On_Gprs(void);
void Turn_Off_Gprs(void);//打开GPRS电源
void USART0_Initial(void);
void USART1_Initial(void);
void Timer_Initial(void);
void Data_Cmnd_Snd(Uint L,char *Temp_Pointer,char Sport,Uint);void Gprs_At_Command(Uint,char *Pcommand,Uint WTime);
void Rx1Data_Judge_Trasmit(void);
void Rx0Data_Judge_Trasmit(void);
//extern void EWEN_93lc66(void);
extern void Start_93lc66(char Op_Code);
extern char Rd_Data(char Start_Addr,char Data_Len,Uint *Pointer);extern void Wr_Data(char Start_Addr,char Data_Len,Uint *Pointer);void Cal_Crc(char *Pointer,Uint L);//计算返回CRC值。
char Read_Parameters_Initial(char);//从EEPROM中读取工作参数、初始化。void WorkMode_Initial_Log(void);
extern void Construct_PDU_SMS(char UDL,char *User_Data);//构造SMS内容。extern void Echo_SMS_Master(char);
void Asci_To_Hex(char *Pointer,Uint);
extern void Echo_Sms_Mobile(void);
void Echo_Rx0(char *Pointer,char Lenth);
extern void Mobile_SMS_Get(char);
extern void Mobile_SMS_Set(char);
extern void Encode7Bit(char);
extern void Decode8Bit(char);
extern char ReturnHex(char);
void Heart_Beat(void);
void Read_Delete_SMS(void);
void Feed_WatchDog(void);
void Gprs_Mode_SMS(Uint);
void Judge_SMS_Counter(void);
void Data_Status(void);
void Connect_Master_Station(void);
extern void Waiting_Result(Uint Wresult_Time);
extern void ZheJiang_Protocol_Down(Uint);
extern void ZheJiang_Protocol_Up(Uint);
void Inqury_Signal(void);
//============================
//全局变量定义
//============================
char VIO;
Uint Tx1_Snd_Lenth,Tx1_Pointer,Rx1_Pointer; //发送长度、发送指针、接收指针Uint Tx0_Snd_Lenth,Tx0_Pointer,Rx0_Pointer; //发送长度、发送指针、接收char *Pointer0,*Pointer1;
char Command_Data_Status;
char Rx1_Start_Flag; //串口接收开始标志
Uint Rx1_Time_Counter;//串口接收时间长度
char Rx1_TimeOut_Flag;//接收超时标志
char Rx0_Start_Flag; //串口接收开始标志
char Rx0_Time_Counter;//串口接收时间长度
char Rx0_TimeOut_Flag;//接收超时标志
Uint Wait_Result_Time;
char Wait_Result_TimeOut;
char Flash_Timer_Len; //CPU正常运行指示灯。
char Led1_Flash;
Uint Heart_Beat_Interval;//自动检测IP连接的间隔时间
char Heart_Beat_Flag; //自动检测标志
char nMinute_Beat_Flag;
char Heart_Beat_Time;
char AT_OpenIp0[35];
char Rx1_Data_Buffer[360];//GPRS串口数据缓冲区char Rx0_Data_Buffer[256];//终端数据缓冲区char Terminal_SIM[12];//终端手机号码。char Center_SIM[12]; //短信通信手机号码。char Data_Center_Sim[12];//数据中心手机号码。char SCA_SIM[4]; //短信服务中心号码Uint Temp_iArray[100];//临时缓冲区:整数char Temp_cArray[200];//临时缓冲区:字符char SMS_TPDU[300];
char User_Data[140];
char PassWord[6];
char AT_CGDCONT[40];
char AT_Set_Ok;
Uint PDU_Len;
char Retry_Counter;
char AT_Test_Flag;
char IpConnect_Flag;
char Rx1_Led,Tx1_Led;//串口1收发指示灯Uint CRC;//CRC校验值。
char Signal_Val;//信号强度
Uint Beat_Rcv_Fail;//心跳未接收到次数(若连续发送三次未收到,则重新连接)Uint Read_SMS_Time;
char Work_Mode;//模块工作模式
char ,Tx1_Pointer,Rx1_Pointer; //发送长度、发送指针、接收指针char Msg_Snd_Flag;
char Tx_Head; //发送引导头
char SMS_Mode;
char Terminal_Addr_High;
char Terminal_Addr_Low;
char Read_SMS_Flag;
char SIM_SMS_Flag;
char Received_Read_Msg_Flag;
char DSR;
Uint SMS_Index;//连接失败次数。
char Read_Flag;
char Ring_Counter;
char Beat_Rcved_Flag;//心跳接收到标志。char Beat_Test_Start;//心跳测试标志。char Beat_Test_Fail;
Uint Beat_Test_Interval;
char First_Connect_Flag;//上电第一次连接标志。Uint Minute2_Interval;
char Minute2_Interval_Flag;
char Inqury_Signal_Flag;
char Terminal_Request_Flag;
char ii;//清缓冲区指针。
Uint Second;
Uint Signalmscnt;
char Minute;
char Connect_Counter;
Uint Rx1_Time_Interval;
char extern Msg_Snd_Success;
Uint Tel_Ring_Counter;
char Ring_Start_Flag;
Uint Ring_Time;
char Zj_Protocol_Flag;
char SMS_Counter;
char Load_Master_Flag;
char Heart_Flag;
char No_Carrier_Flag;
//===========================
//主程序
//============================
void main(void)
{
char i;
_3NOP();
//WDTCTL=WDTPW+WDTHOLD;
BCSCTL1|=XT2OFF+XTS; //启动LFTX1 4M高速晶振,关闭XT2晶振 BCSCTL2|=SELM1+SELM0; //LFTTX1CLK:4M-->MCLK
do
{
IFG1&=~OFIFG;
for(i=0xFF;i>0;i--);
}while((IFG1&OFIFG)!=0);//等待时钟源转换完。P2DIR|=0X08;//P2.0:LED5;P2.1:LED6;p2.2--ring P2OUT&=0XF7;
P1DIR|=0X10;
P1OUT&=0XEF;
WDTCTL=WDTPW+WDTSSEL;//看门狗开启。Delay(20000);
Port_Initial();//初始化P1、P2、P3口等while(VIO==0X00) //若GPRS尚未开机,则打开GPRS电源{
Turn_On_Gprs();
VIO=P5IN&0X10; //VIO=P5.4
_3NOP();
}
Variable_Initial();//变量初始化。Delay(10);
//EWEN_93lc66();//EEPROM擦、写使能 Rd_Data(254,1,Temp_iArray);//检测是否为第一次运行程序if(Temp_iArray[0]!=0X555C)
First_Wr_EEprom();//写入出厂默认数据Read_Parameters_Initial(Estart_Addr);if(Read_Flag==0)//从EEPROM中读取工作参数、初始化CPU。 Read_Parameters_Initial(Estart2_Addr);//初始化时,若原始数据不对,则从备分区读取。_3NOP();
Read_Delete_SMS();//上电时,读取删除短信息。for(;;)//***主循环*****
{
_3NOP();
VIO=P5IN&0X10; //VIO=P5.4
WDTCTL=WDTPW+WDTCNTCL;
DSR=P3IN&0X08; //P3.3:显示系统命令状态/数据状态。 if(DSR!=0) //
{
P1OUT|=0X40;//P1.6: 命令状态。 //Load_Master_Flag=0;
}
else
P1OUT&=~0X40;//数据状态。
if(Rx1_TimeOut_Flag==1)//RX1若接收超时,进行判断。
{
Rx1_TimeOut_Flag=0;
Rx1_Start_Flag=0;
Rx1_Time_Counter=0;
Rx1Data_Judge_Trasmit();//串口1数据判断转发给终端。
}
if(Rx0_TimeOut_Flag==1)//RX0若接收超时,进行判断。
{
Rx0_TimeOut_Flag=0;
Rx0_Start_Flag=0;
Rx0_Time_Counter=0;
Rx0Data_Judge_Trasmit();//串口0数据转发给主站。
}
if(Command_Data_Status==1)//GPRS连接上,则发2个心跳,有关变量复位。
{
Data_Status();
}
if((DSR!=0X00)&&(Inqury_Signal_Flag==1))//
{
Inqury_Signal_Flag=0;
Inqury_Signal();
}
if((DSR!=0X00)&&(((Minute+1)%30)==0))//每隔周期检测是否有新的短信接收到。
{
Minute++;
SIM_SMS_Flag=0;
Read_SMS_Flag=0;
Read_Delete_SMS();
}
if((DSR==0)&&(Heart_Flag==1)&&(Work_Mode==1))//for zhejiang test
{
Heart_Beat();
Heart_Flag=0;
Beat_Test_Start=1;
Beat_Test_Interval=2000;//20秒钟自动检测心跳
Beat_Test_Fail=0;
Beat_Rcved_Flag=0;
}
if((Work_Mode==1)&&(nMinute_Beat_Flag==1)&&(Heart_Beat_Time!=0)) //每隔?分钟心跳周期发 {
nMinute_Beat_Flag=0;
Heart_Beat();
Beat_Test_Start=1;
Beat_Test_Interval=2000;//20秒钟自动检测心跳
Beat_Test_Fail=0;
Beat_Rcved_Flag=0;
}
if((Tel_Ring_Counter>=1)||(First_Connect_Flag==1)||(Terminal_Request_Flag==1)||(Beat_Te {
if((Work_Mode==1)&&(Heart_Beat_Flag==1))
{
Heart_Beat_Flag=0;
Heart_Beat_Interval=6000;
Connect_Master_Station();
if(Connect_Counter++>=30)
Turn_Off_Gprs();//复位GPRS
}
}
if(VIO==0)//判断是否有异常关机。
{
_5NOP();_5NOP();
VIO=P5IN&0X10; //确认 VIO=P5.4
_5NOP();_5NOP();
if(VIO==0)
Turn_On_Gprs();
}
}
}
//=============================================//函数:Variable_Initial(void)
//功能:有关变量初始化
//输入:
//输出:
//==============================================void Variable_Initial(void)
{
Signalmscnt=0;
Ring_Counter=0;
Received_Read_Msg_Flag=0;
nMinute_Beat_Flag=0;
Connect_Counter=0;
Command_Data_Status=0;
Beat_Rcv_Fail=2;
First_Connect_Flag=1;//第一次连接标志
Inqury_Signal_Flag=0;
Terminal_Request_Flag=0;
Beat_Test_Fail=0;
Beat_Test_Start=0;
Beat_Test_Interval=2000;//心跳等待时间间隔。 Heart_Beat_Interval=6000;
Second=0;
Minute=0;
Rx1_Time_Interval=4;
Msg_Snd_Flag=0;
Msg_Snd_Success=0;
Tel_Ring_Counter=0;
Ring_Start_Flag=0;
Ring_Time=0;
Zj_Protocol_Flag=1;//浙江规约
SMS_Counter=0;
Load_Master_Flag=0;
Heart_Flag=0;
No_Carrier_Flag=0;
Signal_Val=13;
}
//==============================================//函数:Data_Status(void)
//功能:数据状态时有关变量状态。
//输入:
//输出:
//==============================================void Data_Status(void)
{
char i;
char CheckSum=0;
char Temp_Load[]={0X68,0X91,0X01,0X07,0X1A,0X1E,0X00,0X68,
0XA1,0X03,0X00,0X11,0X11,0X11,0X00,0X16};
Command_Data_Status=0;
Heart_Beat_Interval=6000;
Ring_Counter=0;
First_Connect_Flag=0;
Beat_Test_Fail=0;
Beat_Test_Start=0;
Minute2_Interval=12000;
Minute2_Interval_Flag=0;
Terminal_Request_Flag=0;
nMinute_Beat_Flag=0;
Connect_Counter=0;
Tel_Ring_Counter=0;
Second=0;
Minute=0;
Heart_Flag=0;
No_Carrier_Flag=0;
if((Work_Mode==0x01)&&(Zj_Protocol_Flag==0))
{
_NOP();
Heart_Beat();
Delay(50);
Heart_Beat();
}
if((Work_Mode==0x01)&&(Zj_Protocol_Flag==1) && (Load_Master_Flag==0))//浙江规约登陆请求 {
Load_Master_Flag=0;
Delay(50);
for(i=0;i<=15;i++)
{
Temp_cArray[i]=Temp_Load[i];
}
/*
for(i=0;i<=3;i++)//终端地址
{
Temp_cArray[i+1]=((Terminal_SIM[i*2+1]-0x30)<<4)+(Terminal_SIM[i*2]-0x3 }
*/ // hunter term address
for(i=0;i<=13;i++)//校验和
{
CheckSum+=Temp_cArray[i];
}
Temp_cArray[14]=CheckSum;
Delay(100);
Tx_Head=Temp_cArray[0];
Data_Cmnd_Snd(15,&Temp_cArray[1],1,5);
/*Delay(200);
Tx_Head=Temp_cArray[0];
Data_Cmnd_Snd(15,&Temp_cArray[1],1,5);*/
Beat_Test_Start=1;
Beat_Test_Interval=12000;//20秒钟自动检测心跳
Beat_Test_Fail=0;
Beat_Rcved_Flag=0;
_NOP();
}
}
//==============================================
//函数:Inqury_Signal()
//功能:查询当前GSM信号强度
//输入:
//输出:
//==============================================
void Inqury_Signal(void)
{
char *AT_CSQ="AT+CSQ\r";//检测信号强度。
char i,CheckSum=0;
char Inqury_Counter=3;
char Temp;
Inqury_Again:;
Temp=Signal_Val;
Inqury_Signal_Flag=0;
AT_Set_Ok=0;
Rx1_Pointer=0;
Rx1_TimeOut_Flag=0;
Tx_Head=AT_CSQ[0];
Data_Cmnd_Snd(6,&AT_CSQ[1],1,40); //查寻信号强弱命令
Delay(200);
for(i=0;i<Rx1_Pointer;i++)//检测信号强弱等级。
{
if((Rx1_Data_Buffer[i]=='+')&&(Rx1_Data_Buffer[i+1]=='C')&&(Rx1_Data_Buffer[i+2]=='S' {
if((Rx1_Data_Buffer[i+4]==':')&&(Rx1_Data_Buffer[i+5]==32)) //冒号 空格 {
if(Rx1_Data_Buffer[i+7]!=',')//信号强度无
{
if(((Rx1_Data_Buffer[i+6]-48)==9)&&((Rx1_Data_Buffer[i+7]-48)==9))//没有检测 {
AT_Set_Ok=1;
P1OUT|=0X90;//LED4、LED5、LED6全黑(=99)
P2OUT|=0X01;
Signal_Val=0;//信号强度为0。
goto Signal000;
}
if(((Rx1_Data_Buffer[i+6]-48)>=2)&&((Rx1_Data_Buffer[i+7]-48)<=9))//信号强度 {
AT_Set_Ok=1;
P1OUT&=0X7F;//LED4亮、强。(>20)
P2OUT|=0X01;
P1OUT|=0X10;
Signal_Val=Rx1_Data_Buffer[i+6]-48;//十位BCD码
Signal_Val=Signal_Val<<4;//左移8位。
Signal_Val+=Rx1_Data_Buffer[i+7]-48;//个位BCD码
if(Signal_Val>0x31)
Signal_Val=0x31;
goto Signal000;
}
if(((Rx1_Data_Buffer[i+;//接收超时标志6]-48)==
{
AT_Set_Ok=1;
P2OUT&=0XFE;//LED5亮、中。(>10<20) P1OUT|=0X90;
Signal_Val=Rx1_Data_Buffer[i+6]-48;//十位BCD码 Signal_Val=Signal_Val<<4;//左移8位。 Signal_Val+=Rx1_Data_Buffer[i+7]-48;//个位BCD码 if(Signal_Val>0x19)
Signal_Val=0x19;
goto Signal000;
}
}
if(Rx1_Data_Buffer[i+7]==',')//信号强度小于10 {
AT_Set_Ok=1;
P1OUT&=0XEF;//LED6亮、低。(<10) P2OUT|=0X01;
P1OUT|=0X80;
Signal_Val=Rx1_Data_Buffer[i+6]-48;//BCD码 if(Signal_Val>9)
Signal_Val=0x09;
goto Signal000;
}
}
}
}
Signal000:
if(AT_Set_Ok==0)
Signal_Val=0x00;
AT_Set_Ok=0;
if(Signal_Val==0x00)
{
if((Inqury_Counter--)!=0)
{
for(i=0;i<20;i++)
{
Rx1_Data_Buffer[i]=0;
}
goto Inqury_Again;
}
}
if(Signal_Val==0x00)
{
if(Temp%2==0)
Temp+=1;
else
Temp-=1;
Signal_Val=Temp;
}
/*
User_Data[0]=User_Data[3]=0x68;//数据头
User_Data[1]=User_Data[2]=11;//数据长度
User_Data[4]=0x5A; //控制字
User_Data[5]=0x99; //获取终端地址低位
User_Data[6]=0x99; //获取终端地址高位
User_Data[7]=0x06; //类型
User_Data[8]=0x82; //可变结构限定词
User_Data[9]=0x05; //传送原因
User_Data[10]=0x55; //数据单元标识L
User_Data[11]=0x30; //数据单元标识H
User_Data[12]=0x00; //记录地址
User_Data[13]=(Signal_Val&0X0F)+0X30; //信号强度 User_Data[14]=((Signal_Val>>4)&0X0F)+0X30; for(i=0;i<=10;i++)//计算102规约校验和
{
CheckSum+=User_Data[4+i];
}
User_Data[15]=CheckSum;
User_Data[16]=0x16;
*/
User_Data[0] = 0x68;
User_Data[1] = 0x99;
User_Data[2] = 0x99;
User_Data[3] = 0x99;
User_Data[4] = 0x99;
User_Data[5] = 0x5E;
User_Data[6] = 0x00;
User_Data[7] = 0x68;
User_Data[8] = 0x0F;
User_Data[9] = 0x09; // 自定义数据帧数据区长度 User_Data[10]= 0x00;
User_Data[11] = 0x1A;
User_Data[12] = 0x82;
User_Data[13] = 0x20;
User_Data[14] = 0x99;
User_Data[15] = 0x12;
User_Data[16] = 0x34;
User_Data[17] = 0x56;
User_Data[18] = 0x78;
User_Data[19]=(Signal_Val&0X0F)+0X30; //信号强度 User_Data[20]=((Signal_Val>>4)&0X0F)+0X30; for(i=0;i<=20;i++)//计算校验和
{
CheckSum+=User_Data[i];
}
User_Data[21]=CheckSum;
User_Data[22]=0x16;
Data_Cmnd_Snd(22,User_Data,0,5);//向串口0发送信号强度数据,发送长度22 P5OUT|=0x80;//接收指示灯灭。
Rx1_TimeOut_Flag=0;
}
//==============================================//函数:Rd_Parameter_Initial()
//功能:从EEPROM中读取工作参数、IP地址、端口、SMS号码等// 初始化波特率、定时器等
//输入参数:
//输出参数:
//==============================================char Read_Parameters_Initial(char Address){
char i,j;
Uint Temp2;
char *Cgdcont="AT+CGDCONT=1,"; //设置PDP通道 WDTCTL=WDTPW+WDTCNTCL;
Rd_Data(Address,91,Temp_iArray);//读取0x06通讯口配置参数。
if(Temp_iArray[0]==0x2f)//寻找数据头
{
if((Temp_iArray[2]==90)&&(Temp_iArray[5]==0xfd))//判断数据长度、功能码是否为设置命 {
for(i=0;i<=90;i++)
{
Temp_cArray[i]=Temp_iArray[i];
}
Cal_Crc(&Temp_cArray[1],88);//计算CRC
Temp2=Temp_cArray[89];//比较CRC
Temp2=Temp2<<8;
Temp2=Temp2+Temp_cArray[90];
if(CRC==Temp2)//若CRC相等,则读出的数据正确。 {
Read_Flag=1; //从EEPROM中读取的数据正确。 Work_Mode=Temp_cArray[6];//工作模式
for(i=0;i<=12;i++)//读取APN名称.
{
AT_CGDCONT[i]=*(Cgdcont+i);//="AT+CGDCONT=1, }
AT_CGDCONT[13]=AT_CGDCONT[16]=0X22; AT_CGDCONT[14]='I';
AT_CGDCONT[15]='P';
AT_CGDCONT[17]=',';
AT_CGDCONT[18]=0X22;
for(i=0;i<=19;i++)/
展开阅读全文