赞
踩
目录
—————————————————————————————————————————————
主机操作系统:Centos 6.7
交叉编译器环境:arm-linux-gcc-4.5.4
开发板平台: FL2440
Linux内核版本: linux-3.0
开发模块: SIM900 GPRS
邮箱:leiyuxing205@gmail.com
—————————————————————————————————————————————
开发提醒:在开发gprs模块打电话发短信之前需满足开发板能正常加载linux内核及文件系统,并且开发板的串口已经使能,同时需准备一张开通gprs流量的sim卡。
GSM模块,是将GSM射频芯片、基带处理芯片、存储器、功放器件等集成在一块线路板上,具有独立的操作系统、GSM射频处理、基带处理并提供标准接口的功能模块。GSM模块根据其提供的数据传输速率又可以分为GPRS模块、EDGE模块和纯短信模块。短信模块只支持语音和短信服务。GPRS,可说是GSM的延续。它经常被描述成“2.5G”,也就是说这项技术位于第二代(2G)和第三代(3G)移动通讯技术之间。GPRS的传输速率从56K到114Kbps不等,理论速度最高达171k。相对于GSM的9.6kbps的访问速度而言,GPRS拥有更快的访问数据通信速度,GPRS技术还具有在任何时间、任何地点都能实现连接,永远在线、按流量计费等特点。EDGE技术进一步提升了数据传输的速率到384K-473K,被称为”2.75G”,数据传输速率更2倍于GPRS。目前,国内的GSM网络普遍具有GPRS通讯功能,移动和联通的网络都支持GPRS,EDGE在部分省市实现了网络覆盖。
GPRS模块,是具有GPRS数据传输功能的GSM模块。GPRS模块就是一个精简版的手机,集成GSM通信的主要功能于一块电路板上,具有发送短消息、通话、数据传输等功能。GPRS模块相当于手机的核心部分,如果增加键盘和屏幕就是一个完整的手机。普通电脑或者单片机可以通过RS232串口与GPRS模块相连,通过AT指令控制GPRS模块实现各种基于GSM的通信功能。
GPRS模块区别于传统的纯短信模块,两者都是GSM模块,但是短信模块只能收发短信和语音通讯,而GPRS模块还具有GPRS数据传输功能。”
- /*********************************************************************************
- * Copyright: (C) 2016 SCUEC
- * All rights reserved.
- *
- * Filename: set_ttyS1.c
- * Description: This file
- *
- * Version: 1.0.0(2016/8/10)
- * Author: leiyuxing <leiyuxing205@gmail.com>
- * ChangeLog: 1, Release initial version on "2016/8/10"
- *
- ********************************************************************************/
- #include <stdio.h>
- #include <errno.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <termios.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <unistd.h>
-
-
- /**************************************************************************************
- * Description: 串口参数配置
- * Input Args: fd:open打开的文件描述符 nspeed:波特率 nBits:数据位数 nEvent:奇偶校验 nStop:停止位
- * Output Argtingzhis: 串口参数设置失败返回-1
- * Return Value:
- *************************************************************************************/
- int set_opt(int fd,int nSpeed,int nBits,char nEvent,int nStop)
- {
- struct termios newttys1,oldttys1;
-
- if(tcgetattr(fd,&oldttys1)!=0) //保存原先串口配置
- {
- perror("Setupserial 1");
- return -1;
- }
-
- bzero(&newttys1,sizeof(newttys1)); //将一段内存区域的内容全清为零
- newttys1.c_cflag|=(CLOCAL|CREAD ); //CREAD 开启串行数据接收,CLOCAL并打开本地连接模式
-
- newttys1.c_cflag &=~CSIZE; //设置数据位数
- switch(nBits) //选择数据位
- {
- case 7:
- newttys1.c_cflag |=CS7;
- break;
- case 8:
- newttys1.c_cflag |=CS8;
- break;
- }
- switch( nEvent ) //设置校验位
- {
- case '0': //奇校验
- newttys1.c_cflag |= PARENB; //开启奇偶校验
- newttys1.c_iflag |= (INPCK | ISTRIP); //INPCK打开输入奇偶校验;ISTRIP去除字符的第八个比特
- newttys1.c_cflag |= PARODD; //启用奇校验(默认为偶校验)
- break;
- case 'E' : //偶校验
- newttys1.c_cflag |= PARENB; //开启奇偶校验
- newttys1.c_iflag |= ( INPCK | ISTRIP); //打开输入奇偶校验并去除字符第八个比特
- newttys1.c_cflag &= ~PARODD; //启用偶校验;
- break;
- case 'N': //关闭奇偶校验
- newttys1.c_cflag &= ~PARENB;
- break;
- }
-
- switch( nSpeed ) //设置波特率
- {
- case 2400:
- cfsetispeed(&newttys1, B2400); //设置输入速度
- cfsetospeed(&newttys1, B2400); //设置输出速度
- break;
- case 4800:
- cfsetispeed(&newttys1, B4800);
- cfsetospeed(&newttys1, B4800);
- break;
- case 9600:
- cfsetispeed(&newttys1, B9600);
- cfsetospeed(&newttys1, B9600);
- break;
- case 115200:
- cfsetispeed(&newttys1, B115200);
- cfsetospeed(&newttys1, B115200);
- break;
- default:
- cfsetispeed(&newttys1, B9600);
- cfsetospeed(&newttys1, B9600);
- break;
- }
-
- if( nStop == 1) //设置停止位;若停止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB。
- {
- newttys1.c_cflag &= ~CSTOPB; //默认为送一位停止位;
- }
- else if( nStop == 2)
- {
- newttys1.c_cflag |= CSTOPB; //CSTOPB表示送两位停止位;
- }
-
- //设置最少字符和等待时间,对于接收字符和等待时间没有特别的要求时
- newttys1.c_cc[VTIME] = 0; //非规范模式读取时的超时时间;
- newttys1.c_cc[VMIN] = 0; //非规范模式读取时的最小字符数;
-
- tcflush(fd ,TCIFLUSH); //tcflush清空终端未完成的输入/输出请求及数据;TCIFLUSH表示清空正收到的数据,且不读取出来
-
- // 在完成配置后,需要激活配置使其生效
- if((tcsetattr( fd, TCSANOW,&newttys1))!=0) //TCSANOW不等数据传输完毕就立即改变属性
- {
- perror("com set error");
- return -1;
- }
- return 0;
- } /* ----- End of if() ----- */
- /*********************************************************************************
- * Copyright: (C) 2016 SCUEC
- * All rights reserved.
- *
- * Filename: call_number.c
- * Description: This file
- *
- * Version: 1.0.0(2016/8/10)
- * Author: leiyuxing <leiyuxing205@gmail.com>
- * ChangeLog: 1, Release initial version on "2016/8/10"
- *
- ********************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #include"gprs.h"
-
- /**************************************************************************************
- * Description: gprs打电话函数
- * Input Args: fd 串口设备文件描述符
- * Output Args:
- * Return Value:
- *************************************************************************************/
- int call_number (int fd)
- {
- getchar(); //将缓冲区回车吃掉
-
- int count=0;
- char call[20]="atd";
- char number[20];
- char reply[128];
-
- printf("enter you call number\n");
- if(NULL==fgets(number,20,stdin)) //输入电话号码,其中fgets在读入一个字符串后在字符串尾端默认加入\n字符
- exit(0); //这个语句的功能可以用gets实现,区别在于 fgets 读入的含 "\n"(最后一个字符),gets 不含 "\n"
-
- while(strlen(number)!=12)
- {
- printf("please again number\n");
- if(NULL==fgets(number,20,stdin))
- exit(0);
- if(count==3)
- exit(0);
- count++;
- }
-
- number[strlen(number)-1]='\0'; //将刚才fgets读入的字符串尾端去除\n字符
- strcat(call,number);
- strcat(call,";\r"); // \r是换行字符
-
- write(fd,call,strlen(call)); //向串口拨打号码
- printf("write %s\n",call);
- sleep(3);
- memset(reply,0,sizeof(reply));
- read(fd,reply,sizeof(reply));
- printf("%s\n",reply);
-
- printf("=================================================\n");
- printf("number is calling,please press 'a' hang up \n");
- printf("=================================================\n");
-
- while('a'!=getchar())
- printf("please again input 'a' to hung up \n");
-
- memset(call,0,sizeof(call));
- strcpy(call,"ATH\r");
- write(fd,call,strlen(call));
- sleep(1);
- memset(reply,0,sizeof(reply));
- read(fd,reply,sizeof(reply));
- printf("%s\n",reply);
- printf("has hung up\n");
-
-
- return 0;
- } /* ----- End of call_number() ----- */
- /*********************************************************************************
- * Copyright: (C) 2016 SCUEC
- * All rights reserved.
- *
- * Filename: send_message.c
- * Description: This file
- *
- * Version: 1.0.0(2016/8/10)
- * Author: leiyuxing <leiyuxing205@gmail.com>
- * ChangeLog: 1, Release initial version on "2016/8/10"
- *
- ********************************************************************************/
- #include<stdio.h>
- #include<string.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #include"gprs.h"
-
-
- /**************************************************************************************
- * Description: gprs发短信函数
- * Input Args: fd 串口设备文件描述符
- * Output Args:
- * Return Value:
- *************************************************************************************/
- int send_message (int fd)
- {
- int count=0;
- char cmgf[]="at+cmgf=1\r"; //设置短信发送模式为text (0-PDU;1-text)
- char cmgs[128]="at+cmgs=\"";
- char send_number[16];
- char message[128];
- char reply[128];
-
- getchar(); //吃掉缓冲区回车
- printf("enter send_message number :\n");
- if(NULL==fgets(send_number,16,stdin))
- exit(0);
- while(12!=strlen(send_number))
- {
- getchar();
- printf("please again input number\n");
- if(NULL==fgets(send_number,16,stdin))
- exit(0);
- if(count==3)
- exit(0);
- count++;
- }
-
- send_number[strlen(send_number)-1]='\0'; //去除字符串末端读入的换行符\n;
- strcat(cmgs,send_number);
- strcat(cmgs,"\"\r");
-
- printf("enter send_message :\n");
- if(NULL==fgets(message,128,stdin))
- exit(0);
-
- message[strlen(message)-1]='\0';
- strcat(message,"\x1a");
-
- /* write cmgf */
-
- write(fd,cmgf,strlen(cmgf));
- printf("write %s\n",cmgf);
- sleep(2);
- memset(reply,0,sizeof(reply));
- read(fd,reply,sizeof(reply));
- printf("%s\n",reply);
-
- /* write cmgs */
-
- write(fd,cmgs,strlen(cmgs));
- printf("writr %s\n",cmgs);
- sleep(5);
- //memset(reply,0,sizeof(reply));
- //read(fd,reply,sizeof(reply));
- //printf("%s\n",reply);
-
-
- /*write message*/
-
- write(fd,message,strlen(message));
- printf("writr %s\n",message);
- sleep(4);
- memset(reply,0,sizeof(reply));
- read(fd,reply,sizeof(reply));
- printf("%s\n",reply);
-
-
- return 0;
- } /* ----- End of send_message() ----- */
工程头文件如下:
- /*********************************************************************************
- * Copyright: (C) 2016 SCUEC
- * All rights reserved.
- *
- * Filename: gprs.h
- * Description: This file
- *
- * Version: 1.0.0(2016/8/10)
- * Author: leiyuxing <leiyuxing205@gmail.com>
- * ChangeLog: 1, Release initial version on "2016/8/10"
- *
- ********************************************************************************/
- #ifndef __GPRS_H__
- #define __GPRS_H__
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- extern int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop);
- extern int send_message(int fd);
- extern int call_number(int fd);
-
- #endif
main函数:
/********************************************************************************* * Copyright: (C) 2016 SCUEC * All rights reserved. * * Filename: gprs_main.c * Description: This file * * Version: 1.0.0(2016/8/10) * Author: leiyuxing <leiyuxing205@gmail.com> * ChangeLog: 1, Release initial version on "2016/8/10" * ********************************************************************************/ #include"gprs.h" int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop); int send_message(int fd); int call_number(int fd); /******************************************************************************** * Description: * Input Args: * Output Args: * Return Value: ********************************************************************************/ int main (int argc, char **argv) { int fd; char select; fd = open( "/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY); if(fd<0){ perror("Can't Open Serial Port"); return -1; } //配置串口 set_opt( fd,115200,8,'N',1); printf("==========================================\n"); printf("gprs call number and send message\n"); printf("==========================================\n"); printf("enter your select: 's' is send message, 'c' is call number, 'q' is exit \n"); select=getchar(); switch(select) { case 's': send_message(fd); break; case 'c': call_number(fd); break; case 'q': exit(0); break; default: break; } close(fd); return 0; } /* ----- End of main() ----- */
编写Makefile文件:
CC =/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc objs =set_ttyS1.o call_number.o send_message.o gprs_main.o srcs =set_ttyS1.c call_number.c send_message.c gprs_main.c gprs_bin: $(objs) $(CC) -o gprs_bin $(objs) @make clean gprs_main.o: $(srcs) gprs.h $(CC) -c $(srcs) set_ttyS1.o: set_ttyS1.c gprs.h $(CC) -c set_ttyS1.c call_number.o: call_number.c gprs.h $(CC) -c call_number.c send_message.o: send_message.c gprs.h $(CC) -c send_message.c clear: @rm gprs_bin .PHONY: clean clean: @rm *.o
- [leiyuxing@centos6 gprs]$ ls
- call_number.c gprs.h gprs_main.c Makefile send_message.c set_ttyS1.c
- [leiyuxing@centos6 gprs]$ make
- [leiyuxing@centos6 gprs]$ ls
- call_number.c gprs_bin gprs.h gprs_main.c Makefile send_message.c set_ttyS1.c
注意:将上图gprs_bin烧录到开发板后,记得更改可执行权限
>:chmod 777 gprs_bin >:./gprs_bin >: ./gprs_bin ========================================== gprs call number and send message ========================================== enter your select: 's' is send message, 'c' is call number, 'q' is exit c enter you call number 130******** write atd13080646238; atd130********; OK ================================================= number is calling,please press 'a' hang up ================================================= a ATH OK has hung up >: ./gprs_bin ========================================== gprs call number and send message ========================================== enter your select: 's' is send message, 'c' is call number, 'q' is exit s enter send_message number : 130******** enter send_message : hello write at+cmgf=1 at+cmgf=1 OK writr at+cmgs="130*********" writr hello at+cmgs="130********" > hello +CMGS: 20 OK
串口通信问题:由于sim900芯片与微控制器之间通信采用串口通信,因此需要保证波特率、数据位、停止位和奇偶校验等参数设置一致。
AT指令发送问题:在编写打电话和发短信的应用程序时,需要通过AT命令与sim900芯片进行通信。因此,在程序中,需要编写AT指令发送函数,并对AT指令返回结果进行处理。
GSM信号强度不稳定:由于GSM网络信号不稳定,可能会导致打电话和发送短信失败。因此,在程序中需要对信号强度进行检测,并在信号强度较低时延迟发送命令,直到信号强度达到一定程度再进行操作。
电话状态检测问题:在编写打电话应用程序时,需要对电话状态进行检测,以避免重复拨号或在通话中发生错误。可以通过读取sim900芯片返回的电话状态信息实现。
短信接收和解析问题:在编写短信接收程序时,需要实现短信自动接收和解析短信内容。需要注意的是,短信内容可能包含非ASCII字符,因此需要对短信内容进行解码。
处理方法:
通过调试工具检查串口通信波特率、数据位、停止位和奇偶校验等参数是否设置一致。
编写AT指令发送函数,并对AT指令返回结果进行处理。
在程序中检测信号强度,并在信号强度较低时延迟发送命令。
通过读取电话状态信息实现电话状态检测功能。
对短信内容进行解码。可以使用相关库函数或自行编写解码程序。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。