AT命令的存在,使得网络通信简化成串口控制,通过一组命令就可以完成设备的初始化、呼叫、短信、传真。几个名词解释:

DTE(Data Terminal Equipment)数据终端设备。通常是一个智能设备,如PC机,嵌入式主机,手机等,用于发送AT命令和PPP命令。
DCE(Data Circuit Terminal )数据电路终端,用于与外界建立通讯的链路。
DTE与DCE之间用串口相连。比如PC机用串口接入拨号MODEM时,PC机是DTE,拨号MODEM是DCE。

                                                  

有关AT命令的详细用法参见http://www.rosoo.net/a/201011/10451.html。

multiplexer protocol是GSM中比较重要的协议,在GSM 07.10中对该协议做了详细的描述。说它重要是因为它是衔接手机(TE)和模组(MS)之间的纽带,TE和MS通信,一般是通过一个串口进行,问题在于串口只有一个,而通信的数据类型却有很多种。比如AT Command、voice、 fax、 data、 SMS、CBS、 phonebook、电量状态、GPRS和USSD 等等。multiplexer protocol就是用来解决这个问题的:让不同类型的数据在一个串口上传输,而不至于发生紊乱。

        multiplexer protocol采用的方法是把一个串口模拟成多个串口,对上层应用程序来说,每一个虚拟的串口和普通串口几乎没有差别,只是每个虚拟串口都只能传输特定类型的数据。下面moto的定义: 
VOICE_CALL "/dev/mux0" 
SMS_MO "/dev/mux1" 
SMS_MT "/dev/mux2" 
PHONEBOOK "/dev/mux3" 
MISC "/dev/mux4" 
CSD "/dev/mux5" 
GPRS1 "/dev/mux6" 
GPRS2 "/dev/mux7" 
CSD "/dev/mux8" 
GPRS1 "/dev/mux9" 
GPRS2 "/dev/mux10" 
LOGGER_CMD "/dev/mux11" 
LOGGER_DATA "/dev/mux12" 
TEST_CMD "/dev/mux13" 
AGPS "/dev/mux14" 
NET_MONITOR "/dev/mux15" 

mux具体参见:http://www.rosoo.net/a/201101/10739.html

====================Linux和android平台的GSM/GPRS模块测试===========

        这里记录一种在普通的LINUX或安卓智能手机平台上,用快捷的方法测试MODEM模块的驱动是否正常工作。需要注意的是:程序的运行依赖于交叉编译器版本,必须是带串口操作库函数的编译器,比如2008q3。编译完成后执行,即可显示一系列待输入选项,进行测试项目。

(1)主函数

// this is a test about GPRS

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>	 
#include <unistd.h>	
#include <termios.h>	// set baud rate,交叉编一起必须带这种库
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>

#define FUNC_RUN		0
#define FUNC_NOT_RUN		1
//测试项目
#define SIMPLE_TEST 		1
#define READ_SIM_CARD_ID 	2
#define GSM_GPRS_SIGNAL	3
#define MAKE_A_CALL 		4
#define WAIT_A_CALL	 	5
#define SHORT_MESSAGE 		6
#define POWER_MANAGE 		7
#define FUNC_QUIT 		8
//短消息测试子项目
#define SEND_SHORT_MESSAGE		1
#define READ_SHORT_MESSAGE		2
#define CONFIG_SHORT_MESSAGE_ENV        3
#define QUIT_SHORT_MESSAGE		4

#define DEVICE_TTYS "/dev/s3c2410_serial1"		//modem分配的UART口
#define MAX_LEN_OF_SHORT_MESSAGE	140


#define RECEIVE_BUF_WAIT_1S 1
#define RECEIVE_BUF_WAIT_2S 2
#define RECEIVE_BUF_WAIT_3S 3
#define RECEIVE_BUF_WAIT_4S 4
#define RECEIVE_BUF_WAIT_5S 5

int main(void)
{
        int fd;
        printf("\nGSM/GPRS TESTS\n\n");
        fd = open(DEVICE_TTYS, O_RDWR);	//打开TTY设备
         if (fd == -1)
        {
                	printf("open device %s error\n",DEVICE_TTYS);
        }
        else
        {
	       	init_ttyS(fd);	// init device
	       	func_GSM(fd);	// GSM/GPRS functions       
                  	if (close(fd)!=0) 
			printf("close device %s error",DEVICE_TTYS);
        }
        return 0;
}
       配置tty的函数
void init_ttyS(int fd)
{
	struct termios options;
	bzero(&options, sizeof(options));       // clear options
	cfsetispeed(&options,B115200);            // setup baud rate
	cfsetospeed(&options,B115200);
	options.c_cflag |= (CS8 | CREAD);
	options.c_iflag = IGNPAR;
	tcflush(fd, TCIFLUSH);
	tcsetattr(fd, TCSANOW, &options);
}
       MODEM测试模块主函数
void func_GSM(int fd)
{
        int flag_func_run;
        int flag_select_func;
        ssize_t ret;
        flag_func_run = FUNC_RUN;

        while (flag_func_run == FUNC_RUN)
        {
                print_prompt();			// print select functions txt
                scanf("%d",&flag_select_func);	// user input select
                getchar();

                switch(flag_select_func)
                {
                        case SIMPLE_TEST        : {GSM_simple_test(fd);         break;}
                        case READ_SIM_CARD_ID   : {GSM_read_sim_card_id(fd);    break;}
                        case GSM_GPRS_SIGNAL    : {GSM_gprs_signal(fd);         break;}
                        case MAKE_A_CALL        : {GSM_call(fd);                break;}
                        case WAIT_A_CALL        : {GSM_wait_call(fd);           break;}
                        case SHORT_MESSAGE      : {GSM_short_mesg(fd);          break;}
                        case POWER_MANAGE       : {GSM_Power_Manage(fd);          break;}	//break退出switch,但不会退出while
                        case FUNC_QUIT          :
                                                {
                                                        flag_func_run = FUNC_NOT_RUN;
                                                        printf("Quit GSM/GPRS function.  byebye\n");
                                                        break;
                                                }
                        default :
                        {
                                printf("please input your select use 1 to 7\n");
                        }
                }
        }
}

       给出的文本提示选项:

void print_prompt(void)
{
        printf ("Select what you want to do:\n");
        printf ("1 : Simple Test\n");
        printf ("2 : Read SIM CARD ID\n");
        printf ("3 : Test GSM/GPRS signal\n");
        printf ("4 : Make A Call\n");
        printf ("5 : Wait A Call\n");
        printf ("6 : Short message\n");
        printf ("7 : Power manage\n");
        printf ("8 : Quit\n");
        printf (">");
} // end print_prompt

(2)各个测试子选项AT命令控制细节:case SIMPLE_TEST

void GSM_simple_test(int fd)
{
	char *send_buf="at\r";
	GSM_GPRS_send_cmd_read_result(fd,send_buf,RECEIVE_BUF_WAIT_1S);
} 

      屏幕回显:

at
OK

(3)用到的公共函数

        发送AT命令并读结果

void GSM_GPRS_send_cmd_read_result(int fd, char *send_buf, int rcv_wait)
{
         char rcv_buf[2048];
	if((send_buf==NULL) || (send_GSM_GPRS_cmd(fd,send_buf))){	// send success , then read
		bzero(rcv_buf,sizeof(rcv_buf));
		if (read_GSM_GPRS_datas(fd,rcv_buf,rcv_wait)){
                        printf ("%s\n",rcv_buf);
                	}
                	else{
                        printf ("read error\n");
                	}
	}
	else{
		printf("write error\n");
	}
} 

        发送AT命令

int send_GSM_GPRS_cmd(int fd, char *send_buf)
{
	ssize_t ret;
	ret = write(fd,send_buf,strlen(send_buf));
	if (ret == -1)
         {
                printf ("write device %s error\n", DEVICE_TTYS);
                return -1;
         }

	return 1;
} 

       读AT应答的结果

int read_GSM_GPRS_datas(int fd, char *rcv_buf,int rcv_wait)
{
	int retval;
	fd_set rfds;
	struct timeval tv;

	int ret,pos;

	tv.tv_sec = rcv_wait;	// wait 2.5s
         tv.tv_usec = 0;
	pos = 0; // point to rceeive buf
	
	while (1)	{
	         FD_ZERO(&rfds);
                  FD_SET(fd, &rfds);
                  retval = select(fd+1 , &rfds, NULL, NULL, &tv);

                  if (retval == -1){ 		//超时
                        perror("select()");
                        break;
                  }
		else if (retval) 
		{			//判断是否还有数据
                        ret = read(fd, rcv_buf+pos, 2048);
                        pos += ret;		//读出的数据长度
                        if (rcv_buf[pos-2] == '\r' && rcv_buf[pos-1] == '\n'){	//如果读到字符串末尾
                                FD_ZERO(&rfds);
                                FD_SET(fd, &rfds);
                                retval = select(fd+1 , &rfds, NULL, NULL, &tv);
                                if (!retval) break;     // no datas, break
                        }
                   } 
		 else{
                        printf("No data\n");
                        break;
                   }
	  }
	  return 1;
}

(4)接2,读SIM卡EF-CCID,case READ_SIM_CARD_ID

void GSM_read_sim_card_id(int fd)
{
        char *send_buf="at+ccid\r";
        GSM_GPRS_send_cmd_read_result(fd,send_buf,RECEIVE_BUF_WAIT_1S);
} 

       屏幕回显:

at+ccid
89860076190753501064

(5)获得网络参数case GSM_GPRS_SIGNAL

void GSM_gprs_signal(int fd)
{
         char *send_buf="at+creg?\r";	//网络注册
	GSM_GPRS_send_cmd_read_result(fd,send_buf,RECEIVE_BUF_WAIT_1S);
         send_buf="at+cgreg?\r";
	GSM_GPRS_send_cmd_read_result(fd,send_buf,RECEIVE_BUF_WAIT_1S);
         send_buf="at+csq\r";		//信号质量
	GSM_GPRS_send_cmd_read_result(fd,send_buf,RECEIVE_BUF_WAIT_1S);
         send_buf="at+cops?\r";		//运营商信息
	GSM_GPRS_send_cmd_read_result(fd,send_buf,RECEIVE_BUF_WAIT_1S);
} 

屏幕回显:

at+creg?
+CREG: 0,1

OK

at+cgreg?
+CGREG: 0,1

OK

at+csq
+CSQ: 25,0

OK

at+cops?
+COPS: 0,0,"CHINA MOBILE"

OK

(6)拨号case MAKE_A_CALL

void GSM_call(int fd)
{
	char send_buf[17];			//发送缓冲区
	char *send_cmd_ath = "ath\r";	//挂机命令	
	int i;

        // input telephone number
        bzero(send_buf,sizeof(send_buf));
	
        send_buf[0]='a';
        send_buf[1]='t';
        send_buf[2]='d';
        send_buf[16] = '\0';

        printf("please input telephone number:");
        i = 3;
        while (1)
        {
                send_buf[i]=getchar();		//从标准输入设备“键盘”获取输入
                if (send_buf[i]=='\n') break;
                i++;
        }

        send_buf[i]=';';			//发送命令后加符号;
        send_buf[i+1]='\r';
	// end input telphone number

	// send cmd
	GSM_GPRS_send_cmd_read_result(fd,send_buf,RECEIVE_BUF_WAIT_1S);		//拨号

        //quit call
        printf("press ENTER for quit:");
        getchar();		//按任意键退出拨号

        // send cmd
	GSM_GPRS_send_cmd_read_result(fd,send_cmd_ath,RECEIVE_BUF_WAIT_1S);	//挂机
	
}

     屏幕回显:

please input telephone number:112
112
atd112;
OK
(7)等待电话case WAIT_A_CALL

void GSM_wait_call(int fd)
{
	char rcv_buf[2048];
	char *send_cmd_ath = "ath\r";		//挂机
         int wait_RING;

         wait_RING = 10;		//等待10次
         while (wait_RING!=0)
         {	
		bzero(rcv_buf,sizeof(rcv_buf));
		if (read_GSM_GPRS_datas(fd,rcv_buf,RECEIVE_BUF_WAIT_1S)){
                        printf ("%s\n",rcv_buf);	//等待应答
                  }
                  else{
                        printf ("read error\n");
                  }
		wait_RING--;
         }
	
	GSM_GPRS_send_cmd_read_result(fd,send_cmd_ath,RECEIVE_BUF_WAIT_1S);
         printf("quit wait_call\n");
}

      屏幕回显如下:有电话拨入则显示RING

No data


RING

No data

No data

No data


RING

No data

No data

No data


RING

ath
OK

quit wait_call

(8)短信息服务case SHORT_MESSAGE

void GSM_short_mesg(int fd)
{
        int flag_sm_run, flag_sm_select;

        flag_sm_run = FUNC_RUN;
        while (flag_sm_run == FUNC_RUN)
        {
                printf ("\n Select:\n");
                printf ("1 : Send short message \n");
                printf ("2 : Read all short message \n");
                printf ("3 : Config short message env\n");	//短消息中心
                printf ("4 : quit\n");
                printf (">");
                scanf("%d",&flag_sm_select);		//输入选择选项
                getchar();				//等待键盘输入
		
	       switch (flag_sm_select)
                {
                        case SEND_SHORT_MESSAGE         :       { GSM_Send_Message(fd);         break; }
                        case READ_SHORT_MESSAGE         :       { GSM_Read_Message(fd);         break; }
                        case CONFIG_SHORT_MESSAGE_ENV   :       { GSM_Conf_Message(fd);         break; }
                        case QUIT_SHORT_MESSAGE         :       { flag_sm_run = FUNC_NOT_RUN;	break; }
                        default :
                                {
                                        printf("please input your select use 1 to 3\n");
                                }
                }
        }
        printf ("\n");

} // end GSM_send_mesg

      A,首先配置短信息中心

void GSM_Conf_Message(int fd)
{
	char *send_buf="at+cmgf=1\r";			//设定SMS的控制方式
	char *send_center_buf="at+csca=\"+8613800755500\"\r";	//短信服务中心地址
	GSM_GPRS_send_cmd_read_result(fd,send_buf,RECEIVE_BUF_WAIT_1S);
        // set short message center number
         GSM_GPRS_send_cmd_read_result(fd,send_center_buf,RECEIVE_BUF_WAIT_1S);

         printf("end config short message env\n");
}

回显:

at+cmgf=1
OK

at+csca="+8613800571500"
OK

end config short message env

     B, 发送信息

void GSM_Send_Message(int fd)
{
        char cmd_buf[23];
        char short_message_buf[MAX_LEN_OF_SHORT_MESSAGE];
        int  i;
        char rcv_buf;

        bzero(cmd_buf,sizeof(cmd_buf));
        bzero(short_message_buf,sizeof(short_message_buf));

        printf ("send short message:\n");

        cmd_buf[0]='a';
        cmd_buf[1]='t';
        cmd_buf[2]='+';
        cmd_buf[3]='c';
        cmd_buf[4]='m';
        cmd_buf[5]='g';
        cmd_buf[6]='s';
        cmd_buf[7]='=';
        cmd_buf[8]='"';		//AT+CMGS发送短信息命令

        printf ("please input telephone number:");
        i = 9;
        while (1)
        {
                cmd_buf[i]=getchar();
                if (cmd_buf[i]=='\n') break;
                i++;				//输入号码
        }
	cmd_buf[i]='"';
         cmd_buf[i+1]='\r';
	cmd_buf[i+2]='\0';			//加上结束符

         // send cmd :  at+cmgs="(telephone number)"
	GSM_GPRS_send_cmd_read_result(fd,cmd_buf,RECEIVE_BUF_WAIT_1S);
	
 	// input short message
        printf("please input short message:");

        i = 0;
        while(i < MAX_LEN_OF_SHORT_MESSAGE-2)
        {
                short_message_buf[i] = getchar();
                if (short_message_buf[i]=='\n') break;
                i++;
        }
        short_message_buf[i] = 0x1A;
        short_message_buf[i+1] = '\r';
        short_message_buf[i+2] = '\0';

        // send short message
        GSM_GPRS_send_cmd_read_result(fd, short_message_buf,RECEIVE_BUF_WAIT_4S);

        printf("\nend send short message\n");
} 

      回显:

send short message:
please input telephone number:13800138000
at+cmgs="13800138000"
OK

please input short message:teset
teset
teset
OK

       C,读SIM卡的短信息

void GSM_Read_Message(int fd)
{
	char *send_buf="at+cmgl=\"ALL\"\r";			//读出SIM卡的短信息
	char rcv_buf[2048];
         GSM_GPRS_send_cmd_read_result(fd,send_buf,RECEIVE_BUF_WAIT_3S);
	printf("end read all short message\n");
} 

      回显:

at+cmgl="ALL"
+CMGL: 1,"REC READ","+8613800138000",,"11/03/17,21:44:39+32" 后面接着显示大量信息。完毕。 

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐