这个程序搞了我很久,尤其是对如何提高响应速度上,程序流程很简单,大概就是:
发送AT指令->等待模块响应->一旦响应了,立即返回,并处理掉。
这个程序不一定只能用在GU906上,程序框架在任何GPRS模块上都能用,只要修改相应的AT指令,按照对应模块的AT指令流程,做下流程上的修改,就没啥问题,框架很简单,不像某宝上店家的那些代码一样,那些代码反正我是看的头晕,程序接口我都留着,只要按照相应的流程调用接口就好。
下面是模块的代码gu906.c文件
// _ooOoo_
// o8888888o
// 88" . "88
// (| -_- |)
// O\ = /O
// ____/`---'\____
// . ' \\| |// `.
// / \\||| : |||// \
// / _||||| -:- |||||- \
// | | \\\ - /// | |
// | \_| ''\---/'' | |
// \ .-\__ `-` ___/-. /
// ___`. .' /--.--\ `. . __
// ."" '< `.___\_<|>_/___.' >'"".
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
// \ \ `-. \_ __\ /__ _/ .-` / /
// ======`-.____`-.___\_____/___.-`____.-'======
// `=---='
//
// .............................................
// 佛祖保佑 永无BUG
// 佛曰:
// 写字楼里写字间,写字间里程序员;
// 程序人员写程序,又拿程序换酒钱。
// 酒醒只在网上坐,酒醉还来网下眠;
// 酒醉酒醒日复日,网上网下年复年。
// 但愿老死电脑间,不愿鞠躬老板前;
// 奔驰宝马贵者趣,公交自行程序员。
// 别人笑我忒疯癫,我笑自己命太贱;
// 不见满街漂亮妹,哪个归得程序员?
//
#include <string.h>
#include <stdlib.h>
#include "stdio.h"
#include "delay.h"
#include "config.h"
#include "usart4.h"
#include "gu906.h"
#define DEBUG_EN 1
//接收缓存
#define MAXRECVBUFF USART4_BUFF
#define AT "AT\r\n" //测试命令
#define ATE(x) ((x)?("ATE1\r\n"):("ATE0\r\n")) //开回显、关回显
#define ATESIM "AT+ESIMS?\r\n" //检测卡是否存在
#define ATCNMI "AT+CNMI=2,1\r\n" //设置这组参数来了新信息存储起来
#define ATCMGD "AT+CMGD=1,4\r\n" //删除当前存储器中全部短信
#define ATCMGF "AT+CMGF=1\r\n" //0设置短消息为PDU模式, 1设置短消息为txet模式
#define ATCSMP "AT+CSMP=17,167,2,25\r\n" //设置文本模式的参数
#define ATUCS2 "AT+CSCS=\"UCS2\"\r\n" //设置为 UCS2 编码字符集
#define ATGB2312 "AT+CSCS=\"GB2312\"\r\n" //设置GB2312编码
#define ATATD "ATD%s;\r\n" //对指定手机拨号
#define ATATH "ATH\r\n" //挂机
#define ATGSM "AT+CSCS=\"GSM\"\r\n" //设置GSM字符集
#define ATCPMS "AT+CPMS=\"SM\",\"SM\",\"SM\"\r\n" //设置短信存储单元为SIM卡
#define ATCSQ "AT+CSQ\r\n" //获取信号强度
#define ATCREG "AT+CREG?\r\n" //确保模块以及注册到GSM网络
#define ATCIICR "AT+CIICR\r\n" //让模块激活 GPRS 网络,在需要反复建立 TCP 链接的场合可提高速度
#define ATCIPSTARTOK "AT+CIPSTART?\r\n" //查询当前是否有网络连接
#define ATCIPCLOSE "AT+CIPCLOSE=0\r\n" //关闭网络连接
#define ATCIPSCONT(x) ((x)?("AT+CIPSCONT=0,\"%s\",\"%s\",%d,2")\
:("AT+CIPSCONT\r\n")) //保存设置
#define ATCIPSTART "AT+CIPSTART=\"%s\",\"%s\",%d\r\n" //设置TCP连接的IP和端口
#define ATCIPMUX "AT+CIPMUX=0\r\n" //单链接模式
#define ATCIPMODE(x) ((x)?("AT+CIPMODE=1,0\r\n")\
:("AT+CIPMODE=0,0\r\n")) //数据透传输模式、非透传
#define ATCIPCFG(x) ((x)?("AT+CIPCFG=1,50,0\r\n")\
:("AT+CIPCFG=0,50,0\r\n")) //自动启动连接命令
#define ATCIPPACK(x) ((x)?("AT+CIPPACK=1,\"4C4F47494E3A31303031\"\r\n")\
:("AT+CIPPACK=0,\"0102A0\"\r\n")) //设备注册包、心跳包设置
#define ATCIPSEND(x) ((x)?("AT+CIPSEND=%d\r\n")\
:("AT+CIPSEND\r\n")) //设置发送的数据长度
#define ATCGMR "AT+CGMR\r\n" //获取基站信息
#define ATCMGS "AT+CMGS=\"%s\"\r\n" //设置需要发送短信的手机号
#define ATCMGR "AT+CMGR=%s\r\n" //设置要读取的短信的位置
#define ATCSTT "AT+CSTT=\"CMNET\"\r\n" //账号配置
#define ATCIPSCONT_C "AT+CIPSCONT?\r\n" //查询透传连接情况
#define GPRSSEND 0x1A
#define CLOSEDTU "+++" //关闭透传
#define OPENDTU "ATO0\r\n" //重新进入透传
enum order{
//与命令对应的
_AT = 1,_ATE,_ATESIM,_ATCNMI,_ATCMGD,_ATCMGF,_ATCSMP,_ATUCS2,
_ATGB2312,_ATATD,_ATATH,_ATGSM,_ATCPMS,_ATCSQ,_ATCREG,
_ATCIICR,_ATCIPSTARTOK,_ATCIPCLOSE,_ATCIPSCONT,_ATCIPSTART,
_ATCIPMUX,_ATCIPMODE,_ATCIPCFG,_ATCIPPACK,_ATCIPSEND,_ATCGMR,
_ATCMGS,_ATCMGR,_GPRSSEND,_ATCSTT,_ATCIPSCONT_C,_CLOSEDTU,_OPENDTU,
//额外的数据类型
_GSMSEND,_GSMSENDEND
};
struct GprsData{
char *order;
int olen;
enum order type;
};
//GPRS数据保存位置
static char GPRS_Data[MAXRECVBUFF]={0};
static int GPRS_Dlen = 0;
static u8 GPRS_Dtu_ConLock = 0;
u8 RestartGprs = 0; //重启GPRS标志
#if GU906GSM_EN
//短信信息在SIM卡中的位置
static char SIMDataID[5]="";
struct user_simdata sim;
#endif
/*********************************************************
* @function GPRS_ascii_to_hex
* @role
* @input
* @output None
* @return
********************************************************/
static int GPRS_ascii_to_hex(u8 *asc_data, u8 *hex_data, int len)
{
int i;
u8 tmp_dat;
for(i = 0; i < len; i++)
{
if ((asc_data[i] >= '0') && (asc_data[i] <= '9')){
tmp_dat = asc_data[i] - '0';
}else if ((asc_data[i] >= 'A') && (asc_data[i] <= 'F')){ // A....F
tmp_dat = asc_data[i] - 0x37;
}
else if((asc_data[i] >= 'a') && (asc_data[i] <= 'f')){ // a....f
tmp_dat = asc_data[i] - 0x57;
}else return -1;
hex_data[i] = tmp_dat;
}
return 0;
}
/*********************************************************
* @function mypow
* @role pow库函数的实现,计算num的n次幂,其中n为整数
* @input num
* @output n
* @return 计算结果
*******************************************************
static int mypow(int num,int n)
{
int powint=1;
int i;
for(i=1;i<=n;i++) powint*=num;
return powint;
}
*/
/*********************************************************
* @function FreeStr
* @role 删除字符串中的字串,支持16进制数据,无视结束符
* @input 字符串、字符串总长度、开始删除的起始位置、要删除的长度
* @output None
* @return None
********************************************************/
static void FreeStr(char *str, int strsiz, int head, int len)
{
int i = 0;
while(len--)
{
for(i = head; i < strsiz;i++)
{
str[i] = str[i+1];
}
}
}
#if GU906GSM_EN
/*********************************************************
* @function GU906_ParsingSIM
* @role 解析SIM卡中的短信数据
* @input 卡中的数据
* @output None
* @return 成功返回:0,失败返回:-1
@data
+CMGR: "REC READ","18750******",,"2015/03/14 20:02:15+32"
124abcABC
OK
********************************************************/
static int GU906_ParsingSIM(char *pinput)
{
char *p = pinput;
int i;
#if DEBUG_EN
printf("\n分离手机号\n");
#endif
if((p = strstr(p,"\",\"")) == 0)
return -1;
p += 3;
memset(sim.phone,0,sizeof(sim.phone));
for (i = 0; (*p != '\"') && (*p != '\0'); ++i,p++){
sim.phone[i] = *p;
}
sim.phone[i] = '\0';
#if DEBUG_EN
printf("sms.phone[%s]\r\n",sim.phone);
printf("\n分离设备类型\n");
#endif
p +=2;
memset(sim.dev,0,sizeof(sim.dev));
for (i = 0; (*p != ',') && (*p != '\0'); ++i,p++){
sim.dev[i] = *p;
}
#if DEBUG_EN
printf("sms.dev[%s]\r\n",sim.dev);
printf("\n分离时间\n");
#endif
p += 2;
memset(sim.date,0,sizeof(sim.date));
for (i = 0; (*p != '\"') && (*p != '\0'); ++i,p++){
sim.date[i] = *p;
}
#if DEBUG_EN
printf("sms.date[%s]\r\n",sim.date);
printf("\n分离数据\n");
#endif
p++;
memset(sim.data,0,sizeof(sim.data));
while((*p != '\0') && ((*p == '\n') || (*p == '\r')) ) p++;
for (i = 0; (*p != '\0') && (*p != '\n') && (*p != '\r'); ++i,p++){
sim.data[i] = *p;
}
sim.data[i] = '\0';
#if DEBUG_EN
printf("sms.data:[%s]\r\n",sim.data );
#endif
return 0;
}
#endif
/*********************************************************
* @function GetRecvData
* @role 提取字符串中跟命令无关的数据,有时在进行命令操作时,
会突然收到短信,什么的,这里要做的就是处理并过滤掉这些数据。
还有模块突然复位了,这里也做判断,并复位CPU。
* @input 数据和数据长度
* @output None
* @return None
********************************************************/
static void GetRecvData(char *pBuff, int *pLen)
{
int rlen = 0;
char buff[5]="";
int i = 0;
char *p1 = NULL;
char *p2 = NULL;
if((pBuff == NULL) || (*pLen == 0))
return;
if (((p1 = strstr(pBuff, "+IPD,")) != 0) && ((p2 = strchr(pBuff, ':')) != 0))
{
p1+=5;
for (i = 0; ((p1-pBuff) < *pLen) && (i < 5) && (*p1 != ':'); ++i,++p1) {
buff[i] = *p1;
}
buff[i] = '\0';
rlen = atoi(buff);
p2++;
GPRS_Dlen = ((rlen >= (*pLen - (p2 - pBuff)))?(*pLen - (p2 - pBuff)):rlen);
memcpy(GPRS_Data, p2,GPRS_Dlen);
rlen = GPRS_Dlen;
p1 = strstr(pBuff, "+IPD,");
p2 = strchr(pBuff, ':');
rlen += ((p2+1)-p1);
FreeStr(pBuff, *pLen,p1-pBuff, rlen);
if((*pLen -rlen) <=3)
*pLen = 0;
else
*pLen -=rlen;
#if DEBUG_EN
printf("B[%d][%s]\r\n",*pLen, pBuff);
#endif
}
#if GU906GSM_EN
else if (strstr(pBuff, "+CMTI:") && ((p1 = strchr(pBuff, ',')) != 0)){ //+CMTI: "SM",2 有短信消息到来
rlen = 0;
p1++;
for(i = 0; *p1 != '\r' && *p1 != '\n' && *p1 != '\0' && rlen < sizeof(SIMDataID);i++, p1++){
if(*p1 >= '0' && *p1 <= '9')
SIMDataID[rlen++] = *p1;
}
SIMDataID[rlen] = '\0';
}
else if ((p1 = strstr(pBuff, "+CMGR:")) != 0){ //读取到短消息
GU906_ParsingSIM(p1);
}
#endif
else if(strstr(pBuff,"[0000]") || strstr(pBuff,"Build Time"))
{
#if (DEBUG_EN == 1)
printf("restart...\r\n\r\n");
#endif
RestartGprs = 1;
}
}
/*********************************************************
* @function GetFreeBuff
* @role 处理掉缓存中多余的数据,同时也起到延时200ms的作用,
读取数据函数自带延时10ms,所以这里num=20,
GU906发送命令不能太快,不然GU906会因为处理不过来,而导致出错。
* @input None
* @output None
* @return None
********************************************************/
static void GetFreeBuff(int num)
{
char buff[MAXRECVBUFF] = {0};
int siz = 0;
while(num--)
{
siz = usart4_Receive(buff,MAXRECVBUFF);
if(siz)
{
GetRecvData(buff, &siz);
}
}
}
/*********************************************************
* @function SendAT
* @role 发送AT指令并接收
* @input gprs:要发送的参数
* @output out:返回的参数
* @return 成功返回:_ATOK,失败返回:_ATERROR
********************************************************/
static s8 SendAT(struct GprsData *gprs, char *out, u32 Delay)
{
int siz = 0;
int i = 0;
char *p = gprs->order;
u8 dat[2];
u8 csq = 0;
s8 ret = _ATERROR;
char buff[MAXRECVBUFF] = {0};
RestartGprs = 0;
#if (DEBUG_EN == 1)
printf("\r\n------------------------------\r\n");
printf("len[%d]\r\n", gprs->olen);
for(i = 0; i< gprs->olen; i++,++p)
printf("%c", *p);
printf("\r\n");
#endif
i = 0;
p = NULL;
GetFreeBuff(10);
usart4_Send(gprs->order,gprs->olen);
if((gprs->type == _GSMSEND) || (gprs->type == _ATATD))
{
ret = _ATOK;
goto GU906_SENDATRET;
}
while(1)
{
for(i = 0;i<sizeof(buff);i++)
buff[i]=0;
siz = 0; i = 0;
while(siz == 0)
{
siz = usart4_Receive(buff,MAXRECVBUFF);
if(siz){
#if (DEBUG_EN == 1)
printf("\r\nrecv:\r\n");
printf("[%s]\r\n",buff);
#endif
GetRecvData(buff, &siz);
}
if(i++ > Delay)
{
ret = _ATOTIME;
goto GU906_SENDATRET;
}
}
if(RestartGprs){
ret = _ATERROR;
goto GU906_SENDATRET;
}
switch(gprs->type)
{
case _AT:
case _ATE:
case _ATCNMI:
case _ATCMGD:
case _ATCMGF:
case _ATCSMP:
case _ATUCS2:
case _ATATH :
case _ATGSM :
case _ATCSTT:
case _ATCIICR:
case _ATCIPCFG:
case _ATCIPPACK:
case _ATCIPSCONT:
case _OPENDTU:
case _CLOSEDTU:
case _ATGB2312:
if(strstr(buff, "OK")){
ret = _ATOK;
goto GU906_SENDATRET;
}else if(strstr(buff, "ERROR") || strstr(buff,"NO CARRIER")) {
GetFreeBuff(100);
ret = _ATERROR;
goto GU906_SENDATRET;
}
break;
case _ATCPMS:
if(strstr(buff, "OK") && strstr(buff, "+CPMS:")){
ret = _ATOK;
goto GU906_SENDATRET;
}else if(strstr(buff, "ERROR")){
ret = _ATERROR;
goto GU906_SENDATRET;
}
break;
case _ATESIM:
ret = _ATERROR;
if(strstr(buff, "OK"))
{
if((p = strstr(buff, "+ESIMS: ")) != 0)
{
p += 8;
if(1 == (*p -'0'))
ret = _ATOK;
}
goto GU906_SENDATRET;
}
break;
case _ATCMGS:
if(strstr(buff, ">")){
GetFreeBuff(1);
ret = _ATOK;
goto GU906_SENDATRET;
}
break;
case _ATCSQ:
if(strstr(buff, "OK"))
{
if((p = strstr(buff, "+CSQ:")) != 0)
{
GPRS_ascii_to_hex((u8 *)(p+6), dat, 2);
csq = dat[0]*10 + dat[1];
#if DEBUG_EN
printf("信号:[%d]\r\n", csq);
#endif
if (csq < 99 && csq >= GPRSCSQ){ //网络信号要大于GPRSCSQ(18)
ret = _ATOK;
goto GU906_SENDATRET;
} else {
ret = _ATERROR;
goto GU906_SENDATRET;
}
}
}
else{
ret = _ATERROR;
goto GU906_SENDATRET;
}
break;
case _ATCIPSTARTOK:
if(strstr(buff, "OK"))
{
if (strstr(buff, "+CIPSTART:")) {
ret = _ATOK;
goto GU906_SENDATRET;
}
ret = _ATERROR;
goto GU906_SENDATRET;
}else if(strstr(buff, "ERROR")) {
ret = _ATERROR;
goto GU906_SENDATRET;
}
break;
case _ATCREG:
if(strstr(buff, "OK"))
{
if ((p = strstr(buff, "+CREG: ")) != 0)
{
p += 7;
if(('0' == *p) || ('5' == *p))
{
ret = _ATOK;
goto GU906_SENDATRET;
}
}
ret = _ATERROR;
goto GU906_SENDATRET;
}else if(strstr(buff, "ERROR")) {
ret = _ATERROR;
goto GU906_SENDATRET;
}
break;
case _ATCIPSEND:
if (strstr(buff, ">")) {
ret = _ATOK;
goto GU906_SENDATRET;
}
else if (strstr(buff, "ERROR")){
ret = _ATERROR;
goto GU906_SENDATRET;
}
break;
case _ATCIPMUX:
if(strstr(buff, "+CIPMUX: 0") && strstr(buff, "OK")) {
ret = _ATOK;
goto GU906_SENDATRET;
}else if (strstr(buff, "ERROR")){
ret = _ATERROR;
goto GU906_SENDATRET;
}
break;
case _ATCIPMODE:
if(strstr(buff, "+CIPMODE: ") && strstr(buff, "OK")) {
ret = _ATOK;
goto GU906_SENDATRET;
}else if (strstr(buff, "ERROR")){
ret = _ATERROR;
goto GU906_SENDATRET;
}
break;
case _GPRSSEND:
if(strstr(buff, "SEND OK")) {
ret = _ATOK;
goto GU906_SENDATRET;
}
break;
case _ATCMGR:
GetRecvData(buff, &siz);
ret = _ATOK;
goto GU906_SENDATRET;
//break;
case _ATCIPCLOSE:
if (strstr(buff, "CLOSE OK") || strstr(buff, "+CME ERROR:")) {
ret = _ATOK;
goto GU906_SENDATRET;
}
else if(strstr(buff, "ERROR")){
ret = _ATERROR;
goto GU906_SENDATRET;
}
break;
case _ATCIPSTART:
if(!GPRS_Dtu_ConLock)
{
if(strstr(buff, "CONNECT OK")){
ret = _ATOK;
goto GU906_SENDATRET;
}
else if(strstr(buff, "RECONNECTING") || strstr(buff, "ERROR") || strstr(buff, "CONNECT FAIL")){
GetFreeBuff(100);
ret = _ATERROR;
goto GU906_SENDATRET;
}
}
else if(strstr(buff, "OK")){
ret = _ATOK;
goto GU906_SENDATRET;
}
else if(strstr(buff, "ERROR")){
ret = _ATERROR;
goto GU906_SENDATRET;
}
break;
case _GSMSENDEND:
GetFreeBuff(100);
ret = _ATOK;
goto GU906_SENDATRET; //忽略返回信息
/*
if(strstr(buff, "+CMGS:")) {
if(strstr(buff, "OK"))
return _ATOK;
lock = 1;
}
else if(lock && strstr(buff, "OK")) {
return _ATOK;
}else return _ATOK; //忽略返回信息
break;
*/
case _ATCIPSCONT_C:
if(strstr(buff,"OK"))
{
printf("Line:%d\r\n",__LINE__);
if(0 != (p = strstr(buff,"+CIPMODE: ")))
{
p += 10;
printf("Line:%d\r\n",__LINE__);
if(1 == (*p -'0'))
{
printf("Line:%d\r\n",__LINE__);
if(0 != (p = strstr(buff,"+CIPSTART: ")))
{
printf("Line:%d\r\n",__LINE__);
if(strstr(buff,"218.66.59.201") && strstr(buff,"8888"))
{
printf("DTU OK\r\n");
GPRS_Dtu_ConLock = 1;
ret = _ATOK;
goto GU906_SENDATRET;
}
}
}
}
GPRS_Dtu_ConLock = 0;
ret = _ATOK;
goto GU906_SENDATRET;
}else if(strstr(buff, "ERROR")){
ret = _ATERROR;
goto GU906_SENDATRET;
}
break;
default: break;
}
}
GU906_SENDATRET:
return ret;
}
/*********************************************************
* @function GU906_ExecuteOrder
* @role 执行命令
* @input None
* @output None
* @return 成功返回:_ATOK,失败返回:_ATERROR,超时返回:_ATOTIME
********************************************************/
static s8 GU906_ExecuteOrder(char *Order, u32 len, enum order type, u32 num)
{
u32 i = 0;
u32 delay_time = 1000;
s8 ret = _ATOTIME;
struct GprsData gprs;
if(type == _ATCIPSTART)
delay_time = 4000;
if(type == _GPRSSEND)
delay_time = 10;
gprs.order = Order;
gprs.olen = len;
gprs.type = type;
while((ret = SendAT(&gprs, NULL, delay_time)) != _ATOK)
{
if(ret == _ATERROR) {
if(++i >= num) return _ATERROR;
delay_s(1);
}else return _ATOTIME;
}
return _ATOK;
}
/*********************************************************
* @function GU906_init
* @role GSM初始化
* @input None
* @output None
* @return 成功返回:_ATOK,失败返回:_ATERROR,超时返回:_ATOTIME
********************************************************/
s8 GU906_init(void)
{
s8 ret = _ATOTIME;
// 开回显:ATE1 关回显:ATE0
if(_ATOK != (ret = GU906_ExecuteOrder(ATE(0), strlen(ATE(0)), _ATE, 2)))
return ret;
// 查询卡是否存在
if(_ATOK != (ret = GU906_ExecuteOrder(ATESIM, strlen(ATESIM), _ATESIM, 10)))
return ret;
#if GU906GSM_EN
// 设置短信模式为text模式
if(_ATOK != (ret = GU906_ExecuteOrder(ATCMGF, strlen(ATCMGF), _ATCMGF, 2)))
return ret;
// 设置短信存储单元为SIM卡
if(_ATOK != (ret = GU906_ExecuteOrder(ATCPMS, strlen(ATCPMS), _ATCPMS, 2)))
return ret;
// 设置这组参数来了新信息存储起来
if(_ATOK != (ret = GU906_ExecuteOrder(ATCNMI, strlen(ATCNMI), _ATCNMI, 2)))
return ret;
#endif
//删除SIM卡中的所有短信
if(_ATOK != (ret = GU906_ExecuteOrder(ATCMGD, strlen(ATCMGD), _ATCMGD, 2)))
return ret;
//查询信号强度 信号强度大于等于18才行
while(_ATOK != (ret = GU906_ExecuteOrder(ATCSQ, strlen(ATCSQ), _ATCSQ, 60)))
{
if(ret == _ATOTIME) return ret;
}
return _ATOK;
}
/*********************************************************
* @function GU906_Module_State
* @role 判断GU906的状态
* @input None
* @output None
* @return 成功返回:_ATOK,失败返回:_ATERROR,超时返回:_ATOTIME
********************************************************/
s8 GU906_Module_State(void)
{
return GU906_ExecuteOrder(AT, strlen(AT), _AT, 0);
}
/*********************************************************
* @function GU906_TCP_Socket
* @role 进行TCP连接
* @input IP地址与端口
* @output None
* @return 成功返回:_ATOK,失败返回:_ATERROR,超时返回:_ATOTIME
********************************************************/
s8 GU906_TCP_Socket(struct Gprs_Config *GprsCon)
{
char cipstart[100] = {0};
s8 ret = _ATOTIME;
if(GprsCon->server_ip == NULL || !GprsCon->server_port) return ret;
if(!strlen((char *)GprsCon->server_ip)) return ret;
//确保模块以及注册到GSM网络
if(_ATOK != (ret = GU906_ExecuteOrder(ATCREG, strlen(ATCREG), _ATCREG, 2)))
return ret;
//让模块激活 GPRS 网络,在需要反复建立 TCP 链接的场合可提高速度
if(_ATOK != (ret = GU906_ExecuteOrder(ATCIICR, strlen(ATCIICR), _ATCIICR, 2)))
return ret;
//查询当前是否有网络连接
while(_ATOK == GU906_ExecuteOrder(ATCIPSTARTOK, strlen(ATCIPSTARTOK), _ATCIPSTARTOK, 0))
{
//关闭网络连接
if(_ATOK != (ret = GU906_ExecuteOrder(ATCIPCLOSE, strlen(ATCIPCLOSE), _ATCIPCLOSE, 2)))
return ret;
//保存设置
if(_ATOK != (ret = GU906_ExecuteOrder(ATCIPSCONT(0), strlen(ATCIPSCONT(0)), _ATCIPSCONT, 2)))
return ret;
}
//单链接模式
if(_ATOK != (ret = GU906_ExecuteOrder(ATCIPMUX, strlen(ATCIPMUX), _ATCIPMUX, 2)))
return ret;
//非数据透传输模式
if(_ATOK != (ret = GU906_ExecuteOrder(ATCIPMODE(0), strlen(ATCIPMODE(0)), _ATCIPMODE, 2)))
return ret;
//自动启动连接命令
if(_ATOK != (ret = GU906_ExecuteOrder(ATCIPCFG(0), strlen(ATCIPCFG(0)), _ATCIPCFG, 2)))
return ret;
//心跳包设置
if(_ATOK != (ret = GU906_ExecuteOrder(ATCIPPACK(0), strlen(ATCIPPACK(0)), _ATCIPPACK, 2)))
return ret;
//连接到服务器
//cipstart=(char *)mymalloc(100);
//if(cipstart==NULL) return -1;
sprintf(cipstart, ATCIPSTART,"TCP", GprsCon->server_ip, GprsCon->server_port);
ret = GU906_ExecuteOrder(cipstart, strlen(cipstart), _ATCIPSTART, 3);
//myfree(cipstart);
return ret;
}
/*********************************************************
* @function GU906_DTU_Socket
* @role 设置透传模式
* @input IP地址与端口
* @output None
* @return 成功返回:_ATOK,失败返回:_ATERROR,超时返回:_ATOTIME
********************************************************/
s8 GU906_DTU_Socket(struct Gprs_Config *GprsCon)
{
char atorder[100] = "";
s8 ret = _ATOTIME;
if(GprsCon->server_ip == NULL || !GprsCon->server_port) return ret;
if(!strlen((char *)GprsCon->server_ip)) return ret;
//atorder=(char *)mymalloc(100);
//if(atorder==NULL) return -1;
//查询数据透设置情况
if(_ATOK != (ret = GU906_ExecuteOrder(ATCIPSCONT_C, strlen(ATCIPSCONT_C), _ATCIPSCONT_C, 2)))
goto GU906_DTU_SOCKETEND;
if(!GPRS_Dtu_ConLock)
{
//设置账号
if(_ATOK != (ret = GU906_ExecuteOrder(ATCSTT, strlen(ATCSTT), _ATCSTT, 2)))
goto GU906_DTU_SOCKETEND;
//透传参数设置
if(_ATOK != (ret = GU906_ExecuteOrder(ATCIPCFG(1), strlen(ATCIPCFG(1)), _ATCIPCFG, 2)))
goto GU906_DTU_SOCKETEND;
//设置心跳
if(_ATOK != (ret = GU906_ExecuteOrder(ATCIPPACK(0), strlen(ATCIPPACK(0)), _ATCIPPACK, 2)))
goto GU906_DTU_SOCKETEND;
//设置设备注册包
if(_ATOK != (ret = GU906_ExecuteOrder(ATCIPPACK(1), strlen(ATCIPPACK(1)), _ATCIPPACK, 2)))
goto GU906_DTU_SOCKETEND;
//单链接模式
if(_ATOK != (ret = GU906_ExecuteOrder(ATCIPMUX, strlen(ATCIPMUX), _ATCIPMUX, 2)))
goto GU906_DTU_SOCKETEND;
//数据透传输模式
if(_ATOK != (ret = GU906_ExecuteOrder(ATCIPMODE(1), strlen(ATCIPMODE(1)), _ATCIPMODE, 2)))
goto GU906_DTU_SOCKETEND;
//保存设置
sprintf(atorder, ATCIPSCONT(1),"TCP", GprsCon->server_ip, GprsCon->server_port);
if(_ATOK != (ret = GU906_ExecuteOrder(atorder, strlen(atorder), _ATCIPSCONT, 2)))
goto GU906_DTU_SOCKETEND;
GPRS_Dtu_ConLock = 1;
}
//建立数据透连接
sprintf(atorder, ATCIPSTART, "TCP", GprsCon->server_ip, GprsCon->server_port);
if(_ATOK != (ret = GU906_ExecuteOrder(atorder, strlen(atorder), _ATCIPSTART, 2)))
goto GU906_DTU_SOCKETEND;
GU906_DTU_SOCKETEND:
//myfree(atorder);
return ret;
}
/*********************************************************
* @function GU906_DtuOrAT
* @role 透传模式与AT模式转换
* @input None
* @output None
* @return 成功返回:_ATOK,失败返回:_ATERROR,超时返回:_ATOTIME
********************************************************/
s8 GU906_DtuOrAT(u8 type)
{
s8 ret = _ATERROR;
if(type)
{
while(!GPRS_Dtu_ConLock)
{
//打开透传
delay_s(2);
if(_ATOK != (ret = GU906_ExecuteOrder(OPENDTU, strlen(OPENDTU), _OPENDTU, 0)))
goto GU906_DTUOFFONEND;
GPRS_Dtu_ConLock = 1;
}
}
else
{
while(GPRS_Dtu_ConLock)
{
//关闭透传
delay_s(2);
if(_ATOK != (ret = GU906_ExecuteOrder(CLOSEDTU, strlen(CLOSEDTU), _CLOSEDTU, 0)))
{
delay_s(1);
if(_ATOK != (GU906_Module_State()))
goto GU906_DTUOFFONEND;
}
GPRS_Dtu_ConLock = 0;
}
}
GU906_DTUOFFONEND:
return ret;
}
/*********************************************************
* @function GU906_GPRS_write
* @role gprs发送数据
* @input 要发送的数据与数据长度
* @output None
* @return 成功返回:_ATOK,失败返回:_ATERROR,超时返回:_ATOTIME
********************************************************/
s8 GU906_GPRS_write(char* pdat, int len)
{
char atorder[20] = "";
s8 ret = -1;
if(strlen(pdat) == 0) return 0;
//atorder = (char *)mymalloc(20);
//if(atorder == NULL) return -1;
if(!GPRS_Dtu_ConLock)//非数据透模式
{
//设置数据长度
sprintf(atorder, ATCIPSEND(1), len);
if(_ATOK != (ret = GU906_ExecuteOrder(atorder, strlen(atorder), _ATCIPSEND, 0)))
goto GU906_GPRS_WRITERET;
//发送数据
if(_ATOK != (ret = GU906_ExecuteOrder(pdat, len, _GPRSSEND, 0)))
goto GU906_GPRS_WRITERET;
}
else
{
//发送数据
usart4_Send(pdat, len);
ret = _ATOK;
}
GU906_GPRS_WRITERET:
//myfree(atorder);
return ret;
}
/*********************************************************
* @function GU906_GPRS_read
* @role 查询是否接收到数据
* @input 输出缓存大小
* @output 接收到的数据
* @return 接收到的数据长度
********************************************************/
u32 GU906_GPRS_read(char *pout, int len)
{
int i = 0;
if(!GPRS_Dtu_ConLock)
{
GPRSREAD:
if(GPRS_Dlen){
for(i = 0;(i < GPRS_Dlen) && (i < (len -1)); i++){
pout[i] = GPRS_Data[i];
}
memset(GPRS_Data, 0, sizeof(GPRS_Data));
GPRS_Dlen = 0;
return i;
}else{
GetFreeBuff(1);
if(GPRS_Dlen)
goto GPRSREAD;
}
}
else
{
return usart4_Receive(pout,len);
}
return 0;
}
/*********************************************************
* @function GU906_make_phone
* @role 向指定的手机拨号
* @input 手机号
* @output None
* @return 成功返回:_ATOK,失败返回:_ATERROR,超时返回:_ATOTIME
********************************************************/
s8 GU906_make_phone(char *phone)
{
char mphone[20]="";
sprintf(mphone, ATATD, phone);
return GU906_ExecuteOrder(mphone, strlen(mphone), _ATATD, 0);
}
/*********************************************************
* @function GU906_Answer_Phone
* @role 等待电话被接听
* @input 手机号
* @output None
* @return 成功返回:_ATOK,失败返回:_ATERROR,超时返回:_ATOTIME
********************************************************/
s8 GU906_Answer_Phone(u32 Delay)
{
int siz = 0;
u32 i = 0;
char buff[MAXRECVBUFF] = "";
i = 0;
while(1)
{
siz = 0;
siz = usart4_Receive(buff,MAXRECVBUFF);
if(siz){
GetRecvData(buff, &siz);
if(strstr(buff, "+COLP:") && strstr(buff, "OK")){
return _ATOK;
}else if(strstr(buff, "NO CARRIER") || strstr(buff, "+CREG: 1") || strstr(buff, "ERROR")){
return _ATERROR;
}
}
if(i++ > Delay)
{
return _ATOTIME;
}
}
}
/*********************************************************
* @function GU906_end_phone
* @role 挂机
* @input None
* @output None
* @return 成功返回:_ATOK,失败返回:_ATERROR,超时返回:_ATOTIME
********************************************************/
s8 GU906_end_phone(void)
{
return GU906_ExecuteOrder(ATATH, strlen(ATATH), _ATATH, 0);
}
#if GU906GSM_EN
/*********************************************************
* @function GU906_Chinese_text
* @role 向指定的手机发送中文短信
* @input phone 手机号指针,pmsg 短消息指针
* @output None
* @return 成功返回:_ATOK,失败返回:_ATERROR,超时返回:_ATOTIME
********************************************************/
s8 GU906_Chinese_text(char *phone,char* pmsg)
{
s8 ret = _ATOTIME;
char atphone[50] = "";
char end[]={0x1A,0x00};
if(strlen(phone) != 11) return _ATERROR;
//atphone = (char *)mymalloc(50);
//if(atphone == NULL) return -1;
//设置短消息为txet模式
if(_ATOK != (ret = GU906_ExecuteOrder(ATCMGF, strlen(ATCMGF), _ATCMGF, 2)))
goto GU906_CHINESE_TEXTEND;
//设置GB2312编码
if(_ATOK != (ret = GU906_ExecuteOrder(ATGB2312, strlen(ATGB2312), _ATGB2312, 2)))
goto GU906_CHINESE_TEXTEND;
//设置这组参数来了新信息存储起来
if(_ATOK != (ret = GU906_ExecuteOrder(ATCNMI, strlen(ATCNMI), _ATCNMI, 2)))
goto GU906_CHINESE_TEXTEND;
//设置用户手机号
sprintf(atphone,ATCMGS,phone);
if(_ATOK != (ret = GU906_ExecuteOrder(atphone, strlen(atphone), _ATCMGS, 2)))
goto GU906_CHINESE_TEXTEND;
//发送数据
if(_ATOK == (ret = GU906_ExecuteOrder(pmsg, strlen(pmsg), _GSMSEND, 0)))
{
ret = GU906_ExecuteOrder(end, 1, _GSMSENDEND, 0);
}
GU906_CHINESE_TEXTEND:
//myfree(atphone);
return ret;
}
/*********************************************************
* @function GU906_Read_SIM
* @role 读取短信信息
* @input 短信在SIM卡中的位置
* @output None
* @return 成功返回:_ATOK,失败返回:_ATERROR,超时返回:_ATOTIME
********************************************************/
static s8 GU906_Read_SIM(char *pnum)
{
s8 ret = _ATOTIME;
char cmgr[20]="";
//读取短信的编码格式为GB2312
if(_ATOK != (ret = GU906_ExecuteOrder(ATGB2312, strlen(ATGB2312), _ATGB2312, 2)))
return ret;
//读取短消息
sprintf(cmgr,ATCMGR,pnum);
return GU906_ExecuteOrder(cmgr, strlen(cmgr), _ATCMGR, 2);
}
/*********************************************************
* @function GU906_DeleteSms
* @role 删除SIM卡中的所有短信
* @input None
* @output None
* @return 成功返回:_ATOK,失败返回:_ATERROR,超时返回:_ATOTIME
********************************************************/
static int GU906_DeleteSms(void)
{
return GU906_ExecuteOrder(ATCMGD, strlen(ATCMGD), _ATCMGD, 2);
}
/*********************************************************
* @function GU906_Read_UserSMS
* @role 查询并读取短信数据
* @input None
* @output None
* @return 0,接收到新数据,-1,未接收到新数据
********************************************************/
s8 GU906_Read_UserSMS(void)
{
SMSREAD:
if(strlen(SIMDataID)){
#if DEBUG_EN
printf("SIMDataID[%s]\r\n",SIMDataID);
#endif
GU906_Read_SIM(SIMDataID);
GU906_DeleteSms();
memset(SIMDataID,0,sizeof(SIMDataID));
return 0;
}else{
GetFreeBuff(1);
if(strlen(SIMDataID))
goto SMSREAD;
}
return -1;
}
#endif
gu906.文件如下
#ifndef _GU906_H_
#define _GU906_H_
#include "sys.h"
#define GU906GSM_EN 1 //是否开启短信功能
#define GPRSCSQ 18 //信号强度,在使用GPRS功能时,最低要求信号强度不得低于18
#define _ATOK 0 //执行成功
#define _ATERROR -1 //执行错误
#define _ATOTIME -2 //执行超时
#define _LINKNOT -3 //掉线了
struct Gprs_Config{
u8 *server_ip; //服务器IP
u32 server_port; //服务器端口
};
#if GU906GSM_EN
//根据实际内存情况而定
struct user_simdata{
char phone[15]; //用户手机号
char dev[50]; //用户使用的设备
char date[50]; //接收时间
char data[200]; //接收的数据
};
extern struct user_simdata sim;
s8 GU906_Read_UserSMS(void);
s8 GU906_Chinese_text(char *phone,char* pmsg);
#endif
s8 GU906_init(void);
s8 GU906_Module_State(void);
s8 GU906_TCP_Socket(struct Gprs_Config *GprsCon);
s8 GU906_DTU_Socket(struct Gprs_Config *GprsCon);
s8 GU906_GPRS_write(char* pdat, int len);
u32 GU906_GPRS_read(char *pout, int len);
s8 GU906_make_phone(char *phone);
s8 GU906_Answer_Phone(u32 Delay);
s8 GU906_end_phone(void);
s8 GU906_DtuOrAT(u8 type);
#endif
main.c
#include <string.h>
#include <stdlib.h>
#include "stdio.h"
#include "delay.h"
#include "GU906.h"
#include "config.h"
#include "usart1.h"
#include "usart4.h"
int main(void)
{
u32 ret = 0;
char buff[200]="";
struct Gprs_Config GprsCon;
delay_init();
usart4_Configuration(115200); //GU900默认通信波特率是115200
usart1_Configuration(115200); //调试输出端口波特率设置
delay_s(5); //刚上电 要等待10秒,等待GU906模块初始化完成
printf("\r\nBegin...\r\n");
GprsCon.server_ip = (u8 *)"210.66.59.211"; //GPRS通信时的服务器IP
GprsCon.server_port = atoi("8888"); //GPRS通信时的服务器端口
//GSM初始化
while(1)
{
if(_ATOK == GU906_init()){
printf("GU906 init ok.\r\n\r\n");
break;
}
printf("init error.\r\n");
delay_s(1);
}
/*****************************************************************************/
//GU906 GPRS TCP 非透传模式通信测试
while(1)
{
if(_ATOK == GU906_TCP_Socket(&GprsCon))
{
printf("socket ok\r\n\r\n");
delay_s(3);
while(1)
{
ret = GU906_GPRS_read(buff, 200);
if(ret)
{
printf("GPRS:[%d][%s]\r\n", ret,buff);
if(_ATOK != GU906_GPRS_write((char *)"OK", 2))
{
printf("Send Error.\r\n");
}
}
}
}
printf("GU906_TCP_Socket ERROR.\r\n");
while(1);
}
/*******************************************************************************/
/*****************************************************************************/
//GU906 GPRS TCP 透传模式通信测试
while(1)
{
if(_ATOK == GU906_DTU_Socket(&GprsCon))
{
printf("socket ok\r\n\r\n");
delay_s(3);
while(1)
{
ret = GU906_GPRS_read(buff, 200);
if(ret)
{
printf("GPRS:[%d][%s]\r\n", ret,buff);
if(_ATOK != GU906_GPRS_write((char *)buff, ret))
{
printf("Send Error.\r\n");
}
if(strstr(buff,"CLOSE"))
{
GU906_DtuOrAT(0);
}
if(strstr(buff,"OPEN"))
{
GU906_DtuOrAT(1);
}
}
}
}
printf("GU906_TCP_Socket ERROR.\r\n");
while(1);
}
/*******************************************************************************/
/*****************************************************************************/
//发送短信测试
while(_ATOK != GU906_Chinese_text("18750******", "123abd 测试"))
{
delay_s(5);
}
//接收短信测试
while(1)
{
if(0 == GU906_Read_UserSMS())
{
printf("------------------------------\r\n");
printf("号码:%s\r\n",sim.phone);
printf("设备:%s\r\n",sim.dev);
printf("时间:%s\r\n",sim.date);
printf("信息:%s\r\n",sim.data);
}
delay_ms(50);
}
/******************************************************************************/
/*****************************************************************************/
//打电话测试
if (_ATOK == GU906_make_phone("18750******"))
{
//等待接听
while(_ATOTIME == GU906_Answer_Phone(1000))
{
printf("make ok\r\n");
GU906_end_phone();
}
printf("make ok\r\n");
}
else
{
printf("make error\r\n");
//SoftReset();
}
/******************************************************************************/
while(1);
}
链接:http://pan.baidu.com/s/1dEQwME9 密码:9fwz