這裡記錄一種在普通的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_RUN0#define FUNC_NOT_RUN1//測試專案#define SIMPLE_TEST 1#define READ_SIM_CARD_ID 2#define GSM_GPRS_SIGNAL3#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_MESSAGE1#define READ_SHORT_MESSAGE2#define CONFIG_SHORT_MESSAGE_ENV 3#define QUIT_SHORT_MESSAGE4#define DEVICE_TTYS "/dev/s3c2410_serial1"//modem分配的UART口#define MAX_LEN_OF_SHORT_MESSAGE140#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 5int 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 optionscfsetispeed(&options,B115200); // setup baud ratecfsetospeed(&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 readbzero(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 bufwhile (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 cmdGSM_GPRS_send_cmd_read_result(fd,send_buf,RECEIVE_BUF_WAIT_1S);//撥號 //quit call printf("press ENTER for quit:"); getchar();//按任意鍵退出撥號 // send cmdGSM_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" 後面接著顯示大量資訊。完畢。