📄 gprs003.c
字号:
{
User_Data[j]=Temp_cArray[29+j];//直接提取数据到User_Data[]中
}
PDU_Len=Temp_cArray[28];
goto Cotinue0;
}
if((Temp_cArray[20]&0x08)==0X08)//短信是16bit编码
{
SMS_Mode=2;
for(j=0;j<Temp_cArray[28]/2;j++)
{
User_Data[j]=Temp_cArray[30+2*j]; //将16bit数据转换成8bit数据,放到User_Data[].
PDU_Len=Temp_cArray[28]/2;
}
}
//检测是否为手机设置命令
Cotinue0:;
if((User_Data[0]=='*')&&(User_Data[1]=='S')&&(User_Data[2]=='E')&&(User_Data[3]=='T'))
{
for(j=0;j<=11;j++)
{
Center_SIM[j]=Temp_Sim[j];
}
Mobile_SMS_Set(PDU_Len);//手机短信设置、处理、返回正确应答。
}
if((User_Data[0]=='*')&&(User_Data[1]=='G')&&(User_Data[2]=='E')&&(User_Data[3]=='T'))
{
for(j=0;j<=11;j++)
{
Center_SIM[j]=Temp_Sim[j];
}
Mobile_SMS_Get(PDU_Len); //手机短信读取、处理、返回相应数据。
}
if((User_Data[0]==0x68)&&(User_Data[7]==0x68))
{
for(j=0;j<=11;j++)
{
Center_SIM[j]=Temp_Sim[j];
}
ZheJiang_Protocol_Down(PDU_Len); //浙江规约SMS传输数据
}
}
if((DSR==0)&&(Rx1_Data_Buffer[i]==0x68)&&((Rx1_Data_Buffer[i+3]==0x68)||(Rx1_Data_Buffer[i+7]==0x68)))//接收到IEC102规约:转发。
{
//while(Tx0_Snd_Lenth);
Data_Cmnd_Snd(Rx1_Lenth,&Rx1_Data_Buffer[i],0,20);//将串口1接收到的数据转发给串口0。
Beat_Rcv_Fail=0;//心跳接收失败次数复位。
Heart_Beat_Interval=600;//心跳信号时间间隔复位。
Heart_Beat_Flag=0;
Read_SMS_Time=60000;//10分钟。
Minute2_Interval=12000;//2分钟通信测试间隔。
Minute2_Interval_Flag=0;
Beat_Test_Start=0;
Second=0;
Minute=0;
Heart_Flag=0;
break;
}
}
}
//================================
//函数:Rx0Data_Judge_Trasmit();
//功能:将串口0接收到的数据转发给串口1
//输入参数:发送长度、发送缓冲区。
//输出参数:
//=================================
void Rx0Data_Judge_Trasmit(void)
{
char i,j;
Uint Temp2;
DSR=P3IN&0X08; //P3.3:命令状态/数据状态。
for(i=0;i<Rx0_Pointer;i++)//检测是否为设置命令
{
WDTCTL=WDTPW+WDTCNTCL;
if(Rx0_Data_Buffer[i]==0x2F)
{
if((Rx0_Data_Buffer[i+2]==90)&&(Rx0_Data_Buffer[i+5]==0xFD))
{ //寻找数据头、判断,若为设置命令。
Cal_Crc(&Rx0_Data_Buffer[i+1],88);//计算CRC
Temp2=Rx0_Data_Buffer[i+89];//比较CRC
Temp2=Temp2<<8;
Temp2=Temp2+Rx0_Data_Buffer[i+90];
if(CRC==Temp2)//若CRC相等,则为设置命令
{
Terminal_Addr_Low=Rx0_Data_Buffer[i-10];//取出终端地址低位
Terminal_Addr_High=Rx0_Data_Buffer[i-9];//取出终端地址高位
for(j=0;j<=90;j++)
{
Temp_iArray[j]=Rx0_Data_Buffer[i+j]; //将字符型数据转换成整型->保存。
}
Wr_Data(Estart_Addr,91,Temp_iArray);//将设置数据写到EEPROM中:0~90
Wr_Data(Estart2_Addr,91,Temp_iArray);//将设置数据写到EEPROM中:0~90
Echo_Rx0(Echo_Array,8);//串口0正确设置应答、构造转发命令。
Read_Parameters_Initial(Estart_Addr);
if(Read_Flag==0)//重新设置参数。
Read_Parameters_Initial(Estart2_Addr);
return;
}
}
if((Rx0_Data_Buffer[i+2]==7)&&(Rx0_Data_Buffer[i+5]==0xFC))
{ //寻找数据头、判断,若为抄读命令。
Cal_Crc(&Rx0_Data_Buffer[i+1],5);//计算CRC
Temp2=Rx0_Data_Buffer[i+6];//比较CRC
Temp2=Temp2<<8;
Temp2=Temp2+Rx0_Data_Buffer[i+7];
if(CRC==Temp2)//若CRC相等,则为设置命令
{
Terminal_Addr_Low=Rx0_Data_Buffer[i-10];//获取终端地址低位
Terminal_Addr_High=Rx0_Data_Buffer[i-9]; //获取终端地址高位
Rd_Data(Estart_Addr,91,Temp_iArray);//将数据备份。100~190
for(j=0;j<=90;j++)
{
Temp_cArray[j]=Temp_iArray[j];
}
Temp_cArray[5]=0XFC;//功能码。
Cal_Crc(&Temp_cArray[1],88);
Temp_cArray[89]=CRC>>8;//校验码。
Temp_cArray[90]=CRC;
Echo_Rx0(Temp_cArray,91);//串口0抄读返回。
return;
}
}
}
if((DSR!=0)&&(Work_Mode==1))//若接收到终端数据时处于命令状态,则主动连接主站
{
Heart_Beat_Flag=1;
Terminal_Request_Flag=1;
return;
}
if((DSR==0)&&(Rx0_Data_Buffer[i]==0x68)&&((Rx1_Data_Buffer[i+3]==0x68)||(Rx0_Data_Buffer[i+7]==0x68))) //转发IEC102规约数据
{
Tx_Head=Rx0_Data_Buffer[i];
Data_Cmnd_Snd(Rx0_Pointer-1,&Rx0_Data_Buffer[i+1],1,10);//将串口0接收到的数据转发给串口1
DSR=P3IN&0X08; //P3.3:命令状态/数据状态。
_3NOP();
if(Minute2_Interval_Flag==1)//数据状态下,若2分钟未数据通信,发送2个心跳测试琏路是否通畅。
{
Beat_Test_Start=1;
Beat_Test_Interval=2000;//
Beat_Test_Fail=0;
Beat_Rcved_Flag=0;
}
return;
}
if((Rx0_Data_Buffer[i]==0x68)&&((Rx0_Data_Buffer[i+3]==0x68)||(Rx0_Data_Buffer[i+7]==0x68)))//浙江规约上行数据
{
ZheJiang_Protocol_Up(Rx0_Pointer);
break;
}
}
}
//===============================
//函数: Echo_Rx0()
//功能:串口0正确设置应答
//输入:
//输出:
//===============================
void Echo_Rx0(char *Dpointer,char Dlenth)
{
char i,CheckSum=0;
WDTCTL=WDTPW+WDTCNTCL;
User_Data[0]=User_Data[3]=0x68;//数据头
User_Data[1]=User_Data[2]=Dlenth+11;//数据长度
User_Data[4]=0x08; //控制字
User_Data[5]=Terminal_Addr_Low; //获取终端地址低位
User_Data[6]=Terminal_Addr_High; //获取终端地址高位
User_Data[7]=0x05;//类型
User_Data[8]=0x00;//可变结构限定词
User_Data[9]=0x05;//传送原因
User_Data[10]=0x10;//数据单元标识L
User_Data[11]=0x30;//数据单元标识H
User_Data[12]=0x00;//记录地址
User_Data[13]=0x00;//串口号
User_Data[14]=Dlenth;//转发长度
for(i=0;i<Dlenth;i++)
{
User_Data[15+i]=*(Dpointer+i);//转发数据。
}
for(i=0;i<11+Dlenth;i++)//计算102规约校验和
{
CheckSum+=User_Data[4+i];
}
User_Data[15+Dlenth]=CheckSum;//校验码
User_Data[16+Dlenth]=0x16;//结束码
Data_Cmnd_Snd(Dlenth+17,User_Data,0,5);//向串口0发送要转发的数据,发送长度Dlenth+17
_NOP();
}
//===============================
//函数:Gprs_AT_Command()
//功能:测试GPRS是否存在
//输入参数:数据长度、命令、等待时间。
//返回参数:
//===============================
void Gprs_At_Command(Uint Lenth,char *Pcommand,Uint WTime)
{
Wait_Result_TimeOut=0;
Retry_Counter=3;//失败重试三次。
Retry0:;
AT_Set_Ok=0;
Tx_Head=*Pcommand;
Data_Cmnd_Snd(Lenth-1,&Pcommand[1],1,WTime);//检测GPRS是否存在并正确响应。
while(AT_Set_Ok==0)//等待结果码
{
WDTCTL=WDTPW+WDTCNTCL;
if((Rx1_TimeOut_Flag==1)&&(Rx1_Pointer>2))//接收超时且接收到数据。
Rx1Data_Judge_Trasmit();
if(Wait_Result_TimeOut==1)
{
Wait_Result_TimeOut=0;
Retry_Counter--;
if(Retry_Counter!=0)//若没有接收正确的结果码,则重试3次。
{
Rx1_Pointer=0;
goto Retry0;
}
else
break;
}
}
}
//==========================
//函数:
//功能:初始化TIMERA
//输入参数:
//输出参数
//============================
void Timer_Initial(void)
{
Heart_Beat_Interval=6000;//自动检测IP连接的间隔时间:30s
TACTL|=TASSEL1+ID1+TACLR;//定时器A时钟源选系统主时钟,1/4分频,清除定时器。(1M)
CCTL0|=CCIE; //允许定时器A比较中断
CCTL1|=CCIE;
CCR0=1250; //设置比较值
CCR1=1250; //设置定时器比较值。
TACTL|=MC0; //启动连续计数模式
Flash_Timer_Len=0; //CPU正常运行指示灯。
Led1_Flash=0;
Heart_Beat_Flag=0; //自动检测标志
Minute2_Interval=12000;//若3分钟未通信,则重新检测。
Minute2_Interval_Flag=0;
}
//==========================
//函数:Port_Initiale()
//功能:初始化端口
//输入参数:无
//返回参数:无
//==========================
void Port_Initial(void)
{
P1DIR|=0XF7;//CS:P1.0; SK:P1.1; DI: P1.2; DO: P1.3(IN)
//LED1:P1.4; LED2:P1.5;LED3:P1.6;LED4:P1.7
P1OUT|=0XF0;
P1OUT&=0X6F;
P2DIR=0XFB;//P2.0:LED5;P2.1:LED6;p2.2--ring
P2OUT|=0X0B;
P3SEL&=0XF7;//P3.3: C/D STATUS.
P3DIR&=0XF7;//P3.3(IN):DSR
DSR=P3IN&0X08;//读取当前在线状态。
P4SEL=0X00;
P4DIR|=0X02;//P4.1 DTR输出
P4OUT&=0XFD;//进入READY状态。
P5SEL&=0X00;
P5DIR|=0XEF;//1110,1111
//P5OUT=0XFF;
//P5OUT&=0XDF;
VIO=P5IN&0X10;//VIO=P5.4
}
//=======================================
//函数:USART0_Initial()
//功能:初始化串口0
//输入参数:Parity(0-none,1-odd,2-even),BaudRate
//输出参数:无。
//=======================================
void USART1_Initial(void)
{
UCTL1|=SWRST; //SWRST置位
UCTL1&=~PENA; //无校验
UCTL1|=CHAR; //字符长度为8位
UTCTL1|=SSEL0+URXSE; //选择辅助时钟ACLK,接收到数据,请求接收中断服务
P3SEL |= 0xC0; // P3.6,7 = USART0 TXD/RXD
P3DIR |= 0x40; // P3.6 output direction
UBR01 = 0xA0;//默认波特率为9600
UBR11 = 0x01;//
UMCTL1= 0xB5;//波特率调整系数:10110101
UCTL1&=~SWRST; //SWRST复位,USARTY允许
ME2 |= UTXE1 + URXE1; // Enable USART0 TXD/RXD
IE2 |= URXIE1+UTXIE1;
Rx1_Start_Flag=0; //串口接收开始标志
Rx1_Time_Counter=0;//串口接收时间长度
Rx1_TimeOut_Flag=0;//接收超时标志
Rx1_Led=0x00;
Tx1_Led=0x00;
}
//================================
//函数:USART0_Initial()
//功能:初始化串口0
//输入参数:Parity(0-none,1-odd,2-even),BaudRate
//输出参数:无。
//=================================
void USART0_Initial(void) //串行口0初始化
{
UCTL0|=SWRST; //SWRST复位,USARTY允许
UTCTL0|=SSEL0+URXSE; //选择辅助时钟ACLK,接收到数据,请求接收中断服务
P3SEL |= 0x30; // P3.4,5 = USART0 TXD/RXD
P3DIR |= 0x10; // P3.4 output direction
UCTL0&=~PENA; //无校验
UCTL0|=CHAR; //字符长度为8位
UBR00 = 0xA0;//默认波特率为9600
UBR10 = 0x01;//
UMCTL0= 0xB5;//波特率调整系数:10110101
UCTL0&=~SWRST; //SWRST复位,USARTY允许
ME1 |= UTXE0 + URXE0; // Enable USART0 TXD/RXD
IE1 |= URXIE0+UTXIE0; // Enable USART0 RX interrupt
Rx0_Start_Flag=0; //串口接收开始标志
Rx0_Time_Counter=0;//串口接收时间长度
Rx0_TimeOut_Flag=0;//接收超时标志
}
//===============================
//函数:Turn_Off_Gprs()
//功能:打开GPRS电源
//输入参数:无
//输出参数:无
//===============================
void Turn_Off_Gprs(void)
{
//P5OUT|=0X20;
//Delay(2500);
//P5OUT&=~0X20;
//Delay(1000);
for(;;)//模块复位,重新启动。
{
_5NOP();
}
}
//===============================
//函数:Turn_on_Gprs()
//功能:打开GPRS电源
//输入参数:无
//输出参数:无
//===============================
void Turn_On_Gprs(void)
{
P5OUT|=0X20;
Delay(200);
P5OUT&=~0X20;
Delay(4500);//等待45秒信号正常.
}
//=============================
//函数:Delay()
//功能:软延时
//输入参数:Delay_Len延时长度
//返回参数:
//==============================
void Delay(Uint Delay_Len)
{
Uint i;
while(Delay_Len--)
{
i=1000;
WDTCTL=WDTPW+WDTCNTCL;
while(i--); //4000*0.25US=1ms
}
}
//================================
//函数:TimerA_Int()
//功能:定时器A比较0中断
//输入参数:
//输出参数:
//================================
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer0_A (void)
{
Flash_Timer_Len++;
if(Flash_Timer_Len==100)
{
CCR0=1250;
Flash_Timer_Len=0;
Led1_Flash^=0x10;//只改变1位.
P1OUT&=0XEF;
P1OUT|=Led1_Flash; //每秒钟LED1 FLASH 一次。
}
if(Rx1_Start_Flag==1)//串口1接收计时
{
Rx1_Time_Counter++;
if(Rx1_Time_Counter>=(Rx1_Time_Interval+1))//CHANGED 11.5
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -