我用的GPRS模块是德信公司 ,德信的 PIML-900/1800模块的推荐的典型电源电压为 3.8V,有 2A的电流输出能力。由于周围网络很好,所以我在实际的使用中电源设计采用的是 LM2941,输出电流为 1A,调整电阻使输出在 3.8v左右,模块工作正常。在周围网络不好的情况下,模块不停的搜寻网络,这时将消耗较大的电流,此时应采用输出电流能力较大的电源芯片。为了防止模块电源电压产生突然的降低导致模块死机,在靠近模块的输入端加了一个 470uf的电容,增强模块在发送数据期间供电电压的稳定性。
由于模块内嵌TCP/IP协议,所以不用在LINUX下进行PPP拨号,直接通过公司产品手册上的AT指令即可进行数据传输,以下是具体拨号过程:
1、查询网络注册状态
AT+CGREG?
41 54 2B 43 47 52 45 47 3F 0D
2、1、首先定义PDP移动场景
AT+CGDCONT=1,"IP","CMNET"
41 54 2B 43 47 44 43 4F 4E 54 3D 31 2C 22 49 50 22 2C 22 43 4D 4E 45 54 22 0D
2 、激活PDP,获得IP地址
AT+CGATT=1
41 54 2B 43 47 41 54 54 3D 31 0D
3 、设置模块连接方式为GPRS连接,接入点为“CMNET”
AT+CIPCSGP=1,"CMNET"
41 54 2B 43 49 50 43 53 47 50 3D 31 2C 22 43 4D 4E 45 54 22 0D
4 、建立连接
AT+CIPSTART="TCP/UDP",202.195.166.55,2020
41 54 2B 43 49 50 53 54 41 52 54 3D 22 54 43 50 22 2C 32 30 32 2E 31 39 35 2E 31 36 36 2E 35 35 2C 32 30 32 30 0D
41 54 2B 43 49 50 53 54 41 52 54 3D 22 54 43 50 22 2C 32 32 32 2E 31 38 36 2E 36 31 2E 37 32 2C 31 32 30 30 0D
TCP/UDP指明是TCP连接还是UDP连接,221.216.163.44是SEVER端的IP地址,2020为端口,连接成功后模块返回 CONNECT OK
5、发送数据
AT+CIPSEND<CR> 返回“>”后输入要传输的数据,再发送CTRL+Z
41 54 2B 43 49 50 53 45 4E 44 0D
即将所要发送的数据发送到指定IP的服务器上
6、 关闭TCP连接
AT+CIPCLOSE
41 54 2B 43 49 50 43
只有在TCP/UDP处于CONNECTING 或者CONNECT OK的状态下才返回OK,否则返回ERROR
7、 关闭移动场景
AT+CIPSHUT
查询网络状态命令
AT+CGREG?
41 54 2B 43 47 52 45 47 3F 0D
查询模块软件版本
AT+GMR
41 54 2B 47 4D 52 0D
域名方式访问
1、配置DNS
AT+CDNSCFG=""
41 54 2B 43 44 4E 53 43 46 47 3D 22 32 30 32 2E 31 39 35 2E 31 36 30 2E 36 22 0D
2、设置连接的Server端为域名
AT+CDNSORIP=1
41 54 2B 43 44 4E 53 4F 52 49 50 3D 31 0D
3、连接到Server
AT+CIPSTART="TCP",www.263.net,80
41 54 2B 43 49 50 53 54 41 52 54 3D 22 54 43 50 22 2C 22 77 77 77 2E 32 36 33 2E 6E 65 74 22 2C 38 30 0D
4、开始发送数据
AT+CIPSEND
5、关闭TCP连接
AT+CIPCLOSE
有了上面这几个指令就可以实现数据传输了。如果要在ARM开发板上进行数据传输就需要对串口编程。
通过判断模块返回的指令来判断当时的状态。
以下是我的具体程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#define GPRSTTY "/dev/ttyS1"
#define BUFSIZE 500
#define ATREADTIMES 5
#define ATTRYTIMES 5
void setTermios(struct termios * pNewtio, short uBaudRate)
{
bzero(pNewtio, sizeof(struct termios)); /* clear struct for new portsettings */
pNewtio->c_cflag = uBaudRate | CS8 | CREAD | CLOCAL;
pNewtio->c_iflag = IGNPAR;
pNewtio->c_oflag = 0;
pNewtio->c_lflag = 0; //non ICANON
/*
initialize all control characters
we don't need them here
*/
pNewtio->c_cc[VINTR] = 0; /* Ctrl-c */
pNewtio->c_cc[VQUIT] = 0; /* Ctrl-/ */
pNewtio->c_cc[VERASE] = 0; /* del */
pNewtio->c_cc[VKILL] = 0; /* @ */
pNewtio->c_cc[VEOF] = 4; /* Ctrl-d */
pNewtio->c_cc[VTIME] = 5; /* inter-character timer, timeout
VTIME*0.1 */
pNewtio->c_cc[VMIN] = 0; /* blocking read until VMIN character
arrives */
pNewtio->c_cc[VSWTC] = 0; /* '/0' */
pNewtio->c_cc[VSTART] = 0; /* Ctrl-q */
pNewtio->c_cc[VSTOP] = 0; /* Ctrl-s */
pNewtio->c_cc[VSUSP] = 0; /* Ctrl-z */
pNewtio->c_cc[VEOL] = 0; /* '/0' */
pNewtio->c_cc[VREPRINT] = 0; /* Ctrl-r */
pNewtio->c_cc[VDISCARD] = 0; /* Ctrl-u */
pNewtio->c_cc[VWERASE] = 0; /* Ctrl-w */
pNewtio->c_cc[VLNEXT] = 0; /* Ctrl-v */
pNewtio->c_cc[VEOL2] = 0; /* '/0' */
}
int sendSMS(const char * strAlarmMobile, const char * strAlarmMessage)
{
int fd,nTotal,i;
struct termios oldtio,newtio;
char strATResult[BUFSIZE];
char strAT[BUFSIZE];
struct timeval tv;
//1、打开 GPRS Modem 连接的串口,进行相关设置,如波特率等,保存原有串口设置;
if ( (fd = open(GPRSTTY,O_RDWR | O_NOCTTY ))<0){
printf("Can't Open Serial Port!GPRSTTY/n");
return -1;
}
else{
tcgetattr(fd,&oldtio); /* save current serial port settings */
setTermios(&newtio,B9600);
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
sprintf(strAT,"at+cmgf=1%c%c",0x0d,0x0a);
nTotal=0;
while (ATComUntilStr(fd,strAT,"OK",strATResult,
ATREADTIMES)!= 0) {
if ((nTotal++)<ATTRYTIMES)
continue;
else
goto sendSMSEND;
}
/* sprintf(strAT,"at+csca=/"%s/"%c%c",strSMSServer,0x0d,0x0a);
nTotal=0;
while (ATComUntilStr(fd,strAT,"OK",
strATResult,ATREADTIMES)!= 0) {
if ((nTotal++)<ATTRYTIMES)
continue;
else
goto sendSMSEND;
}*/
//send message
i=0;
while (1){
sprintf(strAT,"at+cmgs=/"%s/"%c%c",strAlarmMobile,0x0d,0x0a);
nTotal=0;
while (ATComUntilStr(fd,strAT,">",strATResult,ATREADTIMES)!= 0){
if ((nTotal++)<ATTRYTIMES)
continue;
else
goto sendSMSEND;
}
sprintf(strAT,"%s%c",strAlarmMessage,0x1a);
if (ATComUntilStr(fd,strAT,"OK" ,strATResult,ATREADTIMES*3)!= 0){
if ((i++)<ATTRYTIMES)
continue;
else
goto sendSMSEND;
}
else
break;
}
sendSMSEND:
//3、恢复原有的串口设置。
tcsetattr(fd,TCSANOW,&oldtio);
close(fd);
return 0;
}
}
int ATComUntilStr(int fd, const char * strATCommand, const char * strPrompt,
char * strResult, int nATReadTimes)
{
int nRes,ch,nTotal;
char strAT[BUFSIZE];
write(fd,strATCommand,strlen(strATCommand));
nTotal=0;
nRes=0;
ch=0;
while (1)
{
nRes = read(fd,strAT,BUFSIZE-nTotal);
if (nRes>0){
strAT[nRes]=0;
memcpy(strResult+nTotal,strAT,nRes);
nTotal+=nRes;
ch=0;
}
else {
if (ch++==nATReadTimes)
break;
}
}
strResult[nTotal]=0;
//check if OK
if (strstr(strResult,strPrompt)!=NULL)
return 0;
else
return -1;
}
int main(int argc, char* argv[])
{
char* telno="136********"; //自己填号码
char* sm="hello";
int ret;
ret=sendSMS(telno,sm);
return ret;
}
上面是一段发送短信hello的程序,需要发送数据程序的朋友可以留下E-MAIL。