这里记录一种在普通的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" 后面接着显示大量信息。完毕。