?? at.c
字號:
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&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 + -