⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 do_m22.c

📁 车载GPS监控终端的完整代码,与监控中心的通讯采用GPRS.
💻 C
📖 第 1 页 / 共 5 页
字号:

/********************************************************\
*	文件名:  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 + -