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

📄 at.c

📁 基于STC51通过GPS自主定位导航FAT文件系统程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&AT命令处理&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//*文件名称:AT.c

//*文件作用:AT命令处理

//*文件作者:翟  鹏

//*创建日期:2004年5月
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&



#include <include.h>



//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&私有算法函数部分&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

//***********************************************************************************************************************
//函数作用:把hex串高低4位对调
//参数说明:
//注意事项:
//返回说明:
//***********************************************************************************************************************
static void swap_low4_and_high4(uchar *hex, uchar length)
{
	uchar i;
	uchar temp;
	
	if(length&0x01)length++;//修正奇偶
	length>>=1;//转化为字节数
	
	for(i=0;i<length;i++)
	{
		temp=hex[i*2];
		hex[i*2]=hex[i*2+1];
		hex[i*2+1]=temp;
	}
}

//***********************************************************************************************************************
//函数作用:把7位数据转化成8位数据
//参数说明:
//注意事项:
//返回说明:
//***********************************************************************************************************************
static uchar Char2Bcd(uchar *hex)
{
	uchar i;
	uchar j;

	if(*hex>'9')i=*hex-0x37;
	else i=*hex-0x30;
	i<<=4;
	hex++;
    
	if(*hex>'9')j=*hex-0x37;
	else j=*hex-0x30;
	i=i|(j&0x0f);
    
	return i;
}
static void  bit7_to_bit8(uchar *Src, uchar *Dec)
{
       uint i,j;
       uint MoveTemp;

       i=0;
       while(Src[2*i]!=0)
       {
           Src[i]=Char2Bcd(Src+2*i);
           i++;
       }
       Src[i]=0;

       i=0;j=0;
       do{
              if( (j%8) ==0 )
              {
                  Dec[j]=Src[i]&0x7f;
                  j++;
                  continue;
              }

              MoveTemp=Src[i]>>(8-j%8);
              Dec[j]=MoveTemp+(Src[i+1]<<(j%8));
              Dec[j]=0x7f&Dec[j];
              i++;j++;
       }while(Dec[j-1]!=0);
}

//***********************************************************************************************************************
//函数作用:把8位数据转化成7位数据
//参数说明:
//注意事项:
//返回说明:
//***********************************************************************************************************************
static void Bcd2Char(uchar *hex, uchar bcd)//bcd码转化成两个字节表示的hex
{
    uchar i;

    i=bcd>>4; // Msb 
    if(i>9)i+=0x37;
    else i+=0x30;
    *hex++=i;

    i=bcd&0x0f;  // Lsb 
    if(i>9)i+=0x37;
    else i+=0x30;
    *hex=i;
}

//***********************************************************************************************************************
//函数作用:处理PDU格式的短信息
//参数说明:PDU数据缓冲区  dst_no--对方号码  datetime--日期时间  content--短信内容
//注意事项:
//返回说明:
//***********************************************************************************************************************
static uchar dispose_PDU(uchar *buf, uchar *dst_no, uchar *datetime)
{
	uchar *buf_backup=buf;
	uchar i;
	uchar length;
	uchar data_coding;//编码类型
	
	//得到短信中心号码长度 并跳过---(0891683108200205F0)
	hex_to_char(buf,&length);//得到长度
	buf+=2;//跳过长度字节
	buf+=(length<<1);//跳过短信中心号码
	
	//跳过PDU类型---(24)
	buf+=2;

	//得到对方号码 并跳过---(0D91683108026344F0)
	hex_to_char(buf,&length);//得到长度	
	buf+=2;//跳过长度字节---(0D)
	buf+=2;//跳过类型字节---(91)
	swap_low4_and_high4(buf,length);//号码高低字节转化---(8613802036440F)
	if(buf[0]==0x38 && buf[1]==0x36)//跳过国家代码---(86)
	{
		buf+=2;
		length-=2;
	}
	mem_copy(dst_no,buf,length);//拷贝对方号码
	dst_no[length]=0;//添加结束符
	if(length&0x01)length++;//修正奇偶
	buf+=length;//跳过对方号码---(683108026344F0)

	//跳过PID和DCS  00和08
	buf+=2;//跳过PID---(00)
	hex_to_char(buf,&data_coding);//得到编码类型
	buf+=2;//跳过DCS---(08或00)
	
	
	//得到发送日期时间---(40214251029000) 定长---14字节
	swap_low4_and_high4(buf,14);//高低字节转化---(041224152009)
	for(i=0;i<6;i++)
	{
		mem_copy(datetime,buf,2);//拷贝年
		datetime+=3;buf+=2;
	}
	*(datetime-1)=0;//添加结束符
	buf+=2;//跳过毫秒
	
	//得到内容长度 并跳过
	hex_to_char(buf,&length);//得到长度
	buf+=2;//跳过长度
    	
    	//根据编码类型判断是否需要PDU字节转换
    	if(data_coding==0x00)bit7_to_bit8(buf,buf_backup);//英文---PDU编码进行7转8
    	else	str_copy(buf_backup,buf);//中文----unicode字符串直接拷贝
    	
    	return data_coding;
}



//命令消息定义
#define AT_CMD_HEAD		"AT"		//命令头
#define AT_CMD_END		"\r\n"		//命令尾
#define AT_MSG_READY		"RDY"		//模块复位成功的信息
#define AT_MSG_SIMOK		"+CPIN: READY"	//SIM卡成功的信息

#define AT_MSG_LOGINOK		"+CREG: "	//登陆成功的信息
#define AT_MSG_SMSRECEIVE	"+CMT"		//收到短信的信息
#define AT_MSG_RING		"RING"		//收到来电的信息
#define AT_MSG_NOCARR		"NO CARR"	//对方挂机
#define AT_MSG_CLIP		"+CLIP"		//收到来电显示的信息
#define AT_MSG_IPSTATE		"STATE:"	//IP致命错误提示
#define AT_MSG_OK		"OK"		//命令正确的信息
#define AT_MSG_SENDOK		"SEND OK"	//IP发送成功的信息
#define AT_MSG_CONNECTOK	"CONNECT OK"	//IP连接成功的信息
#define AT_MSG_CLOSEOK		"CLOSE OK"	//IP连接关闭成功的信息
#define AT_MSG_SHUTOK		"SHUT OK"	//移动场景关闭成功的信息
#define	AT_MSG_SIGNAL		"+CSQ"		//信号强度信息
#define AT_MSG_ERROR		"ER"		//命令错误的信息
#define AT_MSG_SENDFAIL		"SEND FAIL"	//发送失败的信息
#define AT_MSG_CONNECTFAIL	"CONNECT FAIL"	//连接失败的信息
//命令发送字符串定义
#define	AT_CMD_DISECHO		"E0"			//禁止回显命令行
#define AT_CMD_CREG		"+CREG=1"		//主动提供网络注册信息
#define	AT_CMD_SMSPDU		"+CMGF=0"		//设置短信息为PDU模式
#define	AT_CMD_SMSTOCOMM	"+CNMI=2,2,2,1,0"	//短消息直接从串口输出
#define	AT_CMD_GSMCHARSET	"+CSCS=\"GSM\""		//设置GSM字符集
#define	AT_CMD_TCPIPRECEIVEHINT	"+CIPHEAD=1"		//设置TCPIP接收数据包头提示
#define	AT_CMD_TCPIPSENDHINT	"+CIPSPRT=0"		//关闭TCPIP数据发送时的> 提示
#define AT_CMD_FIXLOCALPORT 	"+CIPFLP=0"		//取消固定本地端口
#define	AT_CMD_SIGNAL		"+CSQ"			//信号强度
#define	AT_CMD_CLOCK		"+CCLK"			//时钟
#define AT_CMD_APNSETUP		"+CSTT="		//设置APN
#define AT_CMD_IPACTIVE		"+CIICR"		//激活移动场景
#define	AT_CMD_GETLOCALIP	"+CIFSR"		//获得本地IP地址
#define	AT_CMD_CONNECT		"+CIPSTART"		//创建连接
#define	AT_CMD_IPSENDDATA	"+CIPSEND="		//发送数据
#define	AT_CMD_CONFIGDNS	"+CDNSCFG"		//配置DNS
#define	AT_CMD_DISCONNECT	"+CIPCLOSE"		//关闭连接
#define	AT_CMD_SHUTDOWN		"+CIPSHUT"		//关闭移动场景
#define AT_CMD_SMSCENTERNO	"+CSCA"			//短消息中心号
#define	AT_CMD_SENDSMS		"+CMGS="		//发送短信
#define AT_CMD_DIAL		"D"			//拨号
#define AT_CMD_SENDDTMF		"+VTS="			//双音频拨号
#define AT_CMD_PLAYDTMF		"+CLDTMF="		//播放双音频
#define AT_CMD_ANSWER		"A"			//应答电话
#define AT_CMD_HANGUP		"H"			//挂断电话
#define AT_CMD_SWITCHAUDIO	"+CHFA="		//切换音频通道
#define AT_CMD_VOLUME		"+CLVL="		//音量控制
#define AT_CMD_MIC		"+CMIC="		//MIC增益控制
//回应字定义
#define AT_ACK_OK		0x80
#define AT_ACK_ERROR		0xA0
//缓冲区定义
uchar xdata at_receive_buffer[AT_RECEIVE_BUF_SIZE];//接收缓冲区
static uint  xdata at_buf_point=0;//接收缓冲区指针
static uchar xdata at_ack=0;//回应字
static uchar xdata sms_coding=0;//短信息编码类型
static uchar xdata sms_no[16];//短信对方号码
static uchar xdata sms_datetime[18]="00/00/00,00:00:00";//短信日期时间
static uchar xdata clip_no[21]="???????????";//来电显示号码
//状态位定义
static bit   at_reset=1;//需要复位 第一次需要复位
static bit   simok=0;//sim卡准备好
static bit   loginok=0;//登陆网络标志
static bit   smsin=0;//收到短消息
static bit   ring=0;//来电话
static bit   calling=0;//是否通话状态



//***********************************************************************************************************************
//函数作用:接收消息
//参数说明:
//注意事项:
//返回说明:如果接受到了完整包 返回1
//***********************************************************************************************************************
static uchar at_get_msg(void)
{	
	uchar temp;
	
	//接收直到没有数据
	while(AT_RECEIVE_CHAR(&temp))
	{
		dog();			
		if(temp=='\r')//判断结束符号
		{
			//如果缓冲区有内容
			if(at_buf_point)
			{
				at_receive_buffer[at_buf_point]=0;//添加结束符
				at_buf_point=0;//清缓冲区指针
				return 1;
			}
		}
		else if(temp=='\n')//过滤垃圾字符
		{

		}
		else		//正常字符
		{
			at_receive_buffer[at_buf_point++]=temp;//向缓存送数据		
			if(at_buf_point>=AT_RECEIVE_BUF_SIZE-1)at_buf_point=0;//判断是否超长
		}
	}
	return 0;
}

//***********************************************************************************************************************
//函数作用:等待数据包---用于接收短消息内容
//参数说明:
//注意事项:
//返回说明:如果接受到了完整包 返回1
//***********************************************************************************************************************
static uchar at_wait_packet(void)
{
	uchar over_flag=0;
	uchar temp;
	uint wait_time=30000;//超时3s
	
	while(wait_time--)
	{	
		dog();
		
		//接收数据
		if(AT_RECEIVE_CHAR(&temp))
		{			
			if(temp=='\r')//判断结束符号
			{
				//如果缓冲区有内容
				if(at_buf_point)
				{
					at_receive_buffer[at_buf_point]=0;//添加结束符
					at_buf_point=0;//清缓冲区指针
					if(over_flag)return 0;
					return 1;
				}
			}
			else if(temp=='\n')//过滤垃圾字符
			{

			}
			else		//正常字符
			{
				at_receive_buffer[at_buf_point++]=temp;//向缓存送数据			
				if(at_buf_point>=AT_RECEIVE_BUF_SIZE-1)
				{
					at_buf_point=0;//判断是否超长
					over_flag=1;
				}
			}
		}	
	}
	at_buf_point=0;//清缓冲区指针
	return 0;
}




//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&消息列表处理函数&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&



//函数作用:收到OK
static void receive_ok(void)
{
	at_ack=AT_ACK_OK;
}
//函数作用:收到ERROR
static void receive_error(void)
{
	at_ack=AT_ACK_ERROR;
}
//函数作用:收到SEND OK
static void receive_sendok(void)
{
	at_ack=AT_ACK_OK;
}
//函数作用:收到短信息到达提示
static void receive_smsreceive(void)
{	
	if(!at_wait_packet())return;//读取数据
	sms_coding=dispose_PDU(at_receive_buffer,sms_no,sms_datetime);//解析PDU
	smsin=1;//送标志
	//if(at_debug==1)//调试信息
	//{
	//	print_line(sms_no);
	//	print_line(at_receive_buffer);
	//}
}
//函数作用:收到来电提示
static void receive_ring(void)
{
	ring=1;
	calling=1;
}
//函数作用:收到来电显示
static void receive_clip(void)
{	
	//送标志
	ring=1;
	calling=1;
	//纪录来电号码
	if(at_receive_buffer[7]!='\"')return;//判断是否开通了来电显示
	if(at_receive_buffer[8]=='\"')return;//判断是否开通了来电显示
	str_char_copy(clip_no,&at_receive_buffer[8],'\"');
}
//函数作用:收到对方挂机的信息
static void receive_nocarr(void)
{
	//送标志
	ring=0;
	calling=0;//通话标志
	//清号码
	str_copy(clip_no,"???????????");
}
//函数作用:收到CSQ
static void receive_signal(void)
{
	at_ack=AT_ACK_OK;
}
//函数作用:收到注册网络成功的提示
static void receive_loginok(void)
{
	if(at_receive_buffer[7]=='1' || at_receive_buffer[7]=='5')loginok=1;//送标志
	else if(at_receive_buffer[7]=='0')if(loginok)at_reset=1;//中途脱网 送复位标志
}
//函数作用:收到SIM卡准备好
static void receive_smsok(void)
{
	if(simok)at_reset=1;
	simok=1;	
}


//命令列表
typedef struct
{
	uchar *cmdstr;
	void  (*callback)(void);
}at_msglist_t;//消息列表数据结构
static at_msglist_t code at_msglist[]=
{

	{AT_MSG_OK,receive_ok},
	{AT_MSG_ERROR,receive_error},
	{AT_MSG_SENDOK,receive_sendok},
	{AT_MSG_SMSRECEIVE,receive_smsreceive},	
	{AT_MSG_RING,receive_ring},
	{AT_MSG_CLIP,receive_clip},
	{AT_MSG_NOCARR,receive_nocarr},
	{AT_MSG_SIGNAL,receive_signal},
	{AT_MSG_LOGINOK,receive_loginok},
	{AT_MSG_SIMOK,receive_smsok},

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -