📄 do_m22.c
字号:
/********************************************************\
* 文件名: Do_GSM.C
* 创建时间:2004年12月7日
* 创建人:
* 版本号: 1.00
* 功能: 针对GSM模块进行的一些操作,包括发送数据和接收数据
* 文件属性:公共文件
* 修改历史:(每条详述)
\********************************************************/
#include <msp430x14x.h>
#include "Other_Define.h"
#include "General.h"
#include "SPI45DB041.h"
#include "Define_Bit.h"
#include "D_Buffer.h"
#include "Uart01.h"
#include "M22_AT.h"
#include "Check_GSM.h"
#include "Sub_C.h"
#include "Do_Reset.h"
#include "W_Protocol.h"
#include "TA_Uart.h"
#include "Handle_Protocol.h"
#include "Do_Handle.h"
#include "Do_SRAM.h"
#include "Do_M22.h"
/*
#include "Do_Record.h"
#include "Record_Protocol.h"
#include "Main_Init.h"
#include "Disp_Protocol.h"
*/
#define Debug_GSM_COM1
void Case1_GSM_PHONE(void);
void Case1_PHONE_Out(void);
void Case2_GSM_OTHER(void);
void Case2_OTHER_Out(void);
void Case3_GSM_SMS_IN(void);
void Case3_SMSIN_Out(void);
void Case4_GSM_SMS_OUT(void);
void Case4_SMSOUT_Out(void);
void Case4_OverTime_Out(unsigned char Clear_Flag);
void Case5_LAND_GPRS_OPER(void);
void Case6_GPRS_DATA_OPER(void);
void Send_Type1_GSM_Data_One(unsigned char S_Address);
void Send_Type1_GSM_Data_Two(unsigned char S_Address);
void Send_Circle_GSM_TypeD(void);
void Send_Circle_TCP_TypeD(void);
void Send_Circle_GSM_TypeE(void);
void Send_Circle_TCP_TypeE(void);
void Case_OverTime_Return(void);
//作为音量四个档位(起作用的也就是后面的四个数,前一个数的存在是为了使数组的下标和音量值想对应上)
/********************************************************\
* 函数名:Do_G20_Out
作用域:外部文件调用
* 功能:
* 参数:
* 返回值:
* 创建人:
*
* 修改历史:(每条详述)
A,表示GSM工作方式
B,表示TCP挂起的工作方式
C,表示TCP在线的工作方式
补充说明:因为根据M22模块的特性:几个CASE的功能
1,处理与电话相关的业务(AB),
2,处理与CSQ方面的查询(AB)
3,SMS的接收(中断方式接收处理)(AB)
4,SMS的发送操作(A)
5,处理需要TCP登陆,TCP退出,TCP在线。
6,TCP在线状态下进行TCP的数据业务
根据M22的相关特性:则可以分为如下几种操作方式
正常的工作流程:
设备启动后:如果根据条件需要进行TCP登陆的话
1-2-3-4-5(登陆)--6(发送登陆信息)---等待登陆响应----(A)接收到响应(A01)6(循环处理)(A02)CSQ查询时间到(A03)+++挂起(A03)2---(A04)6(循环处理)
---
---(A011)判断有电话相关的业务(拨出号码和电话打入)--(A012)+++挂起---1()
----(B)未接收到响应(B01)6(发送登陆信息)--等待登陆响应
具体的的工作方式:
1,设备上电,启动M22,进入GSM的工作方式:
2,如果判断设备判断有报警信息(报警信息默认为30秒的周期发送),
同时IP地址有效,TCP处于开启状态,则需要在启动M22工作后,
进行TCP登陆操作,此时需要TCP一直在线,进行发送报警信息
3,如果判断设备有需要发送行车轨迹数据,同时IP地址有效,TCP处于开启状态,
则也需要在启动M22工作后,进行TCP登陆操作,此时又分两重情况
如果发送轨迹数据的周期如果小于3分钟,则属于一直在线状态),而如何
发送行车轨迹数据的周期大于等于3分钟,则在需要发送轨迹数据的时刻
才进行登陆操作,然后进行发送数据。发送完数据后,则立即退出TCP在线。
4,如果属于TCP一直在线的状态,则每间隔一定时间将TCP挂起,进行CSQ的查询
登陆TCP的工作流程:如果登陆上TCP,并且通过TCP发送登陆信息后,等待返回登陆响应
如果超过一定时间未返回登陆响应,则继续发送登陆信息。如果连续5次均为发送登陆信息后
仍无登陆响应,则退出TCPZ状态,重新进行TCP登陆
\********************************************************/
void Do_G20_Out(void)
{
switch(gGSM_Oper_Type)
{
/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1,GSM_PHONE:主要是针对电话语音方面的处理,拨号,接听,挂机,DTMF,音量调节。根据M22的特殊性,如果TCP
在线的状态下,必须要先退出TCP在线,然后才能进行相关电话业务的处理
只有在GSM的工作方式下执行这个指令
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
case GSM_PHONE:
{
Case1_GSM_PHONE();
break;
}
/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2,GSM_OTHER:没电话的时候CSQ的查询,根据M22的方式,则可以不通过查询CLCC来确定电话业务的状态
在GSM和TCP挂起的状态下执行
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
case GSM_OTHER:
{
Case2_GSM_OTHER();
break;
}
/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3,GSM_SMS_IN:因为M22的接收SMS的方式采用的是中断方式,则直接在中断处理中处理,则可以不处理这个模块
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
case GSM_SMS_IN:
{
Case3_GSM_SMS_IN();
break;
}
/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4,GSM_SMS_OUT:主要处理M22通过GSM方式发送数据包,只有在GSM工作方式下
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
case GSM_SMS_OUT:
{
Case4_GSM_SMS_OUT();
break;
}
/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5,CHECK_GPRS_LINK:专门用于进行退出TCP和登陆TCP的操作流程,或者重新执行进入TCP的操作
在GSM工作方式和TCP挂起的方式下
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
case LAND_TCP_OPER:
{
Case5_LAND_GPRS_OPER();
break;
}
/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6,GPRS_DATA_OPER:M22的TCP方式发送和接收数据(),如果需要退出的时候进行AT指令的其他操作的时候,则需要
先将TCP挂起,可以进行接收SMS,或者发送SMS。如果是电话业务,则需要挂起后,然后退出TCP登陆,才可以进行
电话方面的相关业务
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
case GPRS_DATA_OPER:
{
Case6_GPRS_DATA_OPER();
break;
}
default:
break;
}
}
/********************************************************\
* 函数名:Case1_GSM_PHONE
作用域:本地文件调用
* 功能:Do_G20_Out模块中的一个case执行模块,主要是针对电话语音方面的处理,拨号,接听,挂机,DTMF,音量调节方面的处理。
*
参数: 只有在满足能进入这个case的条件时候,才能进入执行这个模块,
* 返回值:不同的情形是需要对不同的全局变量进行重新附值
* 创建人:
*
* 修改历史:(每条详述)
补充说明: 手柄相关的AT指令存储在buffer1中的0x5D----0x7A区域。第一个字节0x5D存储0或者1,为0则表示
后面的数据已经处理,为1则表示后面的数据未处理。0x5E存储相关的AT指令的类型,如挂机,拨号等
后面如果还有数据(电话号码等)最后数据结束以0X00作为结束标志处理。
改为M22模块后,因为其特性,在这个CASE中需要增加一些处理:
1,如果有手柄或者监听对外拨号的信令,同时如果M22处于TCP在线且被挂起的状态,则需要先执行ATH指令,退出TCP
状态,然后才能进行拨号处理
\********************************************************/
void Case1_GSM_PHONE(void)
{
unsigned int i=0,j=0,k=0,n=0;
unsigned char Phone_s=0;
unsigned char Phone_e=0;
OperateSPIEnd();
//判断监听完后,是否需要恢复语音通道的处理
if( ( (gGeneral_Flag&TCP_PHONE_F_1)==0)&&(gGeneral_Flag&MONITOR_RESUME_F_1) )
{
gTimer=0;
while(gTimer<200){Check_GSM();}
Send_COM0_String((unsigned char *)AT_AUGAIN,sizeof(AT_AUGAIN));
Send_COM0_Byte('1');Send_COM0_Byte(',');
Send_COM0_Byte('5');Send_COM0_Byte(0x0d);
gInternal_Flag&=~M22_RETURN_OK_1;
Wait_OK();
if( (gInternal_Flag&M22_RETURN_OK_1)==0 );
else
{
//2,固定调节SPEKER的接收增益
gTimer=0;
while(gTimer<200){Check_GSM();}
Send_COM0_String((unsigned char *)AT_AUGAIN,sizeof(AT_AUGAIN));
Send_COM0_Byte('2');Send_COM0_Byte(',');Send_COM0_Byte(Handle_VOL[TWO]);Send_COM0_Byte(0x0d);
gInternal_Flag&=~M22_RETURN_OK_1;
Wait_OK();
if( (gInternal_Flag&M22_RETURN_OK_1)==0 );
else
{
//3,调节AT$AUVOL的接收增益
gTimer=0;
while(gTimer<200){Check_GSM();}
Send_COM0_String((unsigned char *)AT_AUVOL,sizeof(AT_AUVOL));
Send_COM0_Byte('5');Send_COM0_Byte(0x0d);
gInternal_Flag&=~M22_RETURN_OK_1;
Wait_OK();
if( (gInternal_Flag&M22_RETURN_OK_1)==0 );
else
{
gGeneral_Flag&=~MONITOR_RESUME_F_1;
P6OUT&=~SEL_MIC;
Send_COM3_Load(4,MAIN_HANG_UP,0);
gSys_Handle=MAIN_HANG_UP;
}
}
}
}
OperateSPIEnd();
//返回退出电话相关业务的CASE结构的满足条件:唯一正常的跳出此
if( (SRAM_Read(PHONE_AT_2)!=VAILD_2)
&&( (gPhone_Status==ACTIVE_HANDLE)||(gPhone_Status==ACTIVE_MONITOR)||(gPhone_Status==READY) ) )
{
if( (gGeneral_Flag&RING_F_1)==0 )
{
gGSM_Oper_Type=GSM_OTHER;
gGSM_OTHER_Step=0;gPhone_Step=0;
gTimer_GSM_AT=0;
Check_GSM();
gInternal_Flag&=~GSM_ONEAT_SUCCESS_1;
OperateSPIEnd();
return;
}
}
//如果buffer1中有相应的处理数据
if( (gInternal_Flag&GSM_ONEAT_SUCCESS_1)==0 )
{
if( gTimer_GSM_AT>600)
{
gTimer_GSM_AT=0;
SRAM_Init();
j=SRAM_Read(PHONE_AT_2);
if(j==VAILD_2)
{
i=SRAM_Read(PHONE_AT_2+1);
if (i==H_DIAL) gPhone_Step=1; //手柄拨号
else if(i==M_DIAL) gPhone_Step=5; //监听拨号
else if(i==H_ANSWER) gPhone_Step=10; //手柄接听
else if(i==H_DTMF) gPhone_Step=11; //手柄DTMF拨号
else if(i==H_VOLADJ) gPhone_Step=12; //手柄调节音量
else if(i==H_HUNGUP) gPhone_Step=13; //手柄挂机
else
{
Check_GSM();
SRAM_Init();
SRAM_Write(PHONE_AT_2,NULL_2);
SRAM_Write(PHONE_AT_2+1,0);
}
}
}
else if(gGeneral_Flag&RING_F_1)
{
//判断是否有来电显示
//+CLIP: "13670155704",129,,,,0
if( Check_GSM()!=0 )
{
if(Compare_String(gGeneral_Buffer,(unsigned char *)String_CLIP,sizeof(String_CLIP))!=0)
{
gStatus1_Flag|=PHONE_ONLINE_F_1;
j=SRAM_Read(PHONE_AT_2+0);
i=SRAM_Read(PHONE_AT_2+1);
if((i==H_HUNGUP)&&(j==VAILD_2));
else
{
i=5;
gPublic_Flag&=~ALLOW_PHONE_IN_F_1;
while(1)
{
if(gGeneral_Buffer[i]=='"') break;
i++;if(i>15) return;
}
i++;
Phone_s=i; //第一个号码的位置序号
SRAM_Init();
SRAM_Write(SHANDLE_DATA_VAILD+0,VAILD_2);
SRAM_Write(SHANDLE_DATA_VAILD+1,0x24);
SRAM_Write(SHANDLE_DATA_VAILD+2,0x14);
SRAM_Write(SHANDLE_DATA_VAILD+3,MAIN_PHONE_IN);
j=i+16;
k=0;
while(1)
{
if(gGeneral_Buffer[i]!='"')
{
SRAM_Write(SHANDLE_DATA_VAILD+4+k,gGeneral_Buffer[i]);
i++;k++;
if(i>j)
{
n=0;
break;
}
}
else
{
n=k;
break;
}
}
Phone_e=i-1; //号码最后一个位的序号
for(k=i;k<j;k++)
{
SRAM_Write(SHANDLE_DATA_VAILD+4+n+(k-i),0x20);
}
SRAM_Write(SHANDLE_DATA_VAILD+4+n+j-i,0x0d);
gPhone_Status=INCOMING;
//判断比较是否与Flash中存储的中心服务号码相同
if( ((gON_OFF_Temp0&PHONE_IN_ON)==0)
&&((gCommon_Flag&CHECK_RINGPHONE_F_1)==0 ) )
{
for(i=0;i<Phone_e-Phone_s;i++)
{
gGeneral_Buffer[i]=gGeneral_Buffer[Phone_s+i];
}
i=1;
i=Check_Allow_Phone(Phone_e-Phone_s);
//与匹配的号码不一样
if(i==1) gPublic_Flag&=~ALLOW_PHONE_IN_F_1;
//与匹配的号码一样
else gPublic_Flag|=ALLOW_PHONE_IN_F_1;
gCommon_Flag|=CHECK_RINGPHONE_F_1;
}
}
gPhone_Status=INCOMING;
}
}
}
}
/********************************************************\
\********************************************************/
//1,手柄拨号处理
if(gPhone_Step==1)
{
gPhone_Step=4;gTimer_GSM_AT=0;
}
else if(gPhone_Step==4)
{
if( gTimer_GSM_AT>400 )
{
if(gPhone_Status==READY)
{
Send_COM0_String((unsigned char *)ATD,sizeof(ATD));
//电话号码的长度
k=SRAM_Read(PHONE_AT_2+2);
for(j=0;j<k;j++)
{
Send_COM0_Byte(SRAM_Read(PHONE_AT_2+3+j));
}
OperateSPIEnd();
Send_COM0_Byte(';');
Send_COM0_Byte(0x0d);
gInternal_Flag|=GSM_ONEAT_SUCCESS_1;
gPhone_Step=14;
gTimer_GSM_AT=0;
gGeneral_Flag|=DAILING_UP_F_1;
gGeneral_Flag|=TCP_PHONE_F_1;
gHangUp_Timer=0;
gPhone_Status=DAILING;
SRAM_Init();
SRAM_Write(PHONE_AT_2+0,NULL_2);
SRAM_Write(PHONE_AT_2+1,0);
for(i=PHONE_AT_2+1;i<ECHO_SMS_2;i++)
{
SRAM_Write(i,0);
}
gStatus1_Flag|=PHONE_ONLINE_F_1;
}
else Case1_PHONE_Out();
}
else Check_GSM();
}
/********************************************************\
2,监听拨号处理()如果属于是监听处理,则先处理将麦克的增益调节最大
将,然后将SPEAKER的接收增益调节为关闭状态,然后控制模拟开关的通道转换
\********************************************************/
else if(gPhone_Step==5)
{
if( gTimer_GSM_AT>400 )
{
if(gPhone_Status==READY)
{
gTimer=0;
while(gTimer<200){Check_GSM();}
Send_COM0_String((unsigned char *)AT_AUGAIN,sizeof(AT_AUGAIN));
Send_COM0_Byte('1');Send_COM0_Byte(',');
Send_COM0_Byte('9');Send_COM0_Byte(0x0d);
gInternal_Flag&=~M22_RETURN_OK_1;
Wait_OK();
if( (gInternal_Flag&M22_RETURN_OK_1)==0 )
{
gPhone_Step=5;gTimer_GSM_AT=0;
}
else
{
//2,固定调节SPEKER的接收增益为1
gTimer=0;
while(gTimer<200){Check_GSM();}
Send_COM0_String((unsigned char *)AT_AUGAIN,sizeof(AT_AUGAIN));
Send_COM0_Byte('2');Send_COM0_Byte(',');Send_COM0_Byte('1');Send_COM0_Byte(0x0d);
gInternal_Flag&=~M22_RETURN_OK_1;
Wait_OK();
if( (gInternal_Flag&M22_RETURN_OK_1)==0 )
{
gPhone_Step=5;gTimer_GSM_AT=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -