原创 在ARM开发板上通过GPRS发送数据

2009-9-18 15:31 4331 2 9 分类: MCU/ 嵌入式
我用的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。
PARTNER CONTENT

文章评论7条评论)

登录后参与讨论

用户1720717 2013-11-12 11:02

我正在做单片机通讯AT指令c语言程序这一块,希望得到你的指导。1182707645@qq.com 谢谢

用户1720717 2013-11-12 10:15

我现在正在做单片机上通讯模块AT指令的c语言的编写,需要你的指导。1182707645@qq.com 谢谢

用户377235 2013-11-12 10:03

我现在正在做单片机通讯这一块,对AT指令不了解。希望得到你的指导。1182707645@qq.com 谢谢

用户445470 2013-7-5 14:36

我现在正在使用三星的6410arm板,因为没有gprs通信方面的经验,不知道如何给固定ip发送信息以及数据,请求指导,qq350284037,谢谢了

用户377235 2012-5-3 16:40

正在做这方面的东西,想把arm上采集的数据送出去,既送到指定的ip电脑上,麻烦你指导指导 qq286300504

用户364518 2011-8-1 15:10

正在要做那个gprs数据传输,是在cortex-M3上面实现,之前实现过电话,短信部分,这次gprs数传希望等到您的指导,380842455@qq.com。。谢谢了

用户808473 2011-4-21 11:24

在做gprs数传,软件开发在at命令发送上有点不解,我使用MCU发送给gprs模块at命令的。 谢谢指导
相关推荐阅读
用户1005085 2010-08-27 11:15
红格人脸识别考勤机
        红格TR-0202C 作为第四代考勤机的领跑者不负众望,红格-TR0202C正式面市。这款考勤机采用了国内外最先进的技术,以及完全自主知识产权的红格人脸识别算法,既具有指纹考勤机的防打...
用户1005085 2009-09-25 10:41
如何在DE2平台上存取SDRAM? (IC Design) (DE2)
Abstract 之前討論過在DE2用軟體的C語言存取SDRAM,本文討論用硬體的Verilog存取SDRAM。Introduction使用環境:Quartus II 7.2 SP1 + MegaCo...
用户1005085 2009-09-25 10:34
如何产生VGA的Color Pattern Generator? (SOC) (Verilog)
Abstract本文使用Verilog在VGA產生Color Pattern Generator。Introduction使用環境:Quartus II 8.0 + DE2(Cyclone II EP...
用户1005085 2009-09-24 16:20
在ALTERA-DE2上实现VGA的颜色输出变化(verilog)
在我的DE2平台上验证过,可行!Abstract在友晶科技的DE2_CCD範例中,將CMOS的影像直接在VGA輸出,是否能控制VGA的座標,並顯示不同的影像呢?Introduction版權聲明:本文根...
用户1005085 2009-09-23 19:10
在ALTERA-DE2平台上实时产生灰阶图像
参考了一片文章,我在DE2平台上实际测试可行。和大家一起分享!Abstract灰階影像是很多電腦視覺演算法的基礎,必須會先會產生灰階影像後,才能繼續動其他演算法。Introduction使用環境:Qu...
用户1005085 2009-09-22 13:46
在ALTERA-DE2开发板上实现图像采集显示功能
DE2可外接摄像头模组和彩色LCD,如此可實作出簡單的數位相機,本篇先介紹使用Verilog純硬體的方式讓CCD影像顯示在彩色 LCD上。 使用環境:Quartus II 7.2 SP1 + Nios...
EE直播间
更多
我要评论
7
2
关闭 站长推荐上一条 /3 下一条