linux下GPRS模块的应用程序
------------------------------------------------------------------------------------------------------------------------------
交叉编译器:arm-linux-gcc-4.5.4
Linux内核版本:Linux-3.0
主机操作系统:Centos 6.5
开发板:FL2440
GPRS:SIM900A
在开发SIM900模块之前,开发板已经加载了linux内核以及文件系统,并且开发板串口已经使能。并且一定要注意的是:要有一张没有欠费的电话卡!
------------------------------------------------------------------------------------------------------------------------------
参考文档
http://www.cnblogs.com/thinkinglife/p/3986006.html
一、GPRS模块简介
GPRS模块,是具有GPRS数据传输功能的GSM模块。GPRS模块就是一个精简版的手机,集成GSM通信的主要功能于一块电路板上,具有发送短消息、通话、数据传输等功能。GPRS模块相当于手机的核心部分,如果增加键盘和屏幕就是一个完整的手机。普通电脑或者单片机可以通过RS232串口与GPRS模块相连,通过AT指令控制GPRS模块实现各种基于GSM的通信功能。 制作串口线将 GPRS模块的串口和开发板的串口连接起来(我连接的是开发的第二个串口,因为第一个串口连接PC了)。
二、打开GPRS模块
这个地方介绍GPRS的打开方式看起来有些傻逼,不过第一次拿到GPRS模块并且没有任何人指导的情况下可能真的不会打开。
首先插上手机卡,必须是以前的大卡,如果是小卡的话也可以,需要对准之后放上去才能工作。然后拨动GPRS模块的拨码开关,在GPRS模块的最下方,一个很明显很大的拨码开关。最后在拨码开关的左上方有一个黑色的小按钮SW1,按下按钮让让SIM开始工作,搜索网络这时发光二极管D3会闪烁。
三、AT命令
GPRS模块在Linux环境下操作不需要移植任何东西,只需要在Linux下用AT命令通过串口读取、写入信息就可以实现对GPRS模块的操作。AT命令的使用方法网上有许多,这里就不一一解释了,没有太多意义。只简单的介绍一下打电话发短信必要的命令就可以了。
以下都是在开发板上的操作:
#microcom -t 15000 -s 115200 /dev/ttyS0 //linux下的串口调试软件microcom
-t 单位毫秒,无操作自动退出时间。
ttyS0 要操作的串口。
接下来的命令都是往串口中写的了。
AT //检测串口是否OK,若返回OK表示是可以用的
打电话:
atd***********; //后面的***********是电话号码,【注意】“;”一定要有
ath //挂断电话
当有电话来时,串口会打印RING。如果GPRS模块上插有耳机,可以听到提示来电的声音。
ata //接通电话
ath //挂断电话
发短信:
AT+CMGF=1 //选择短消息格式 1对应文本格式 0对应PDU模式,支持中文,中文短信发送时候需要转码。
AT+CMGS="GSM" //设置字符格式为GSM模式,可不用设置
at+cmgs="***********" //***********是11位手机号
输入之后回车显示一个 > 提示输入文本,这个时候输入文本。注意:输入文本完毕之后不敲回车而是敲ctrl+z表示输入完毕。
接受短信:
AT+CNMI=3,2 //设置GPRS为来短信提示新短信状态
三、C程序实现打电话发短信接电话收短信功能
开始的时候写了两个程序:一个是打电话发短信的,一个是接电话接短信的。因为这两个程序不能同时运行,所以后来想要整合在一起的时候一直想的是用双线程或双进程,每个进程各自运行一个程序。后来想模仿手机打电话的功能:一般我们的手机都是处于接电话与接短信的状态,如果手机想要打电话或者发短信则按相应按键进入相应函数。那么我的程序也可以这样实现,让程序一直跑在接电话与接短信的状态,一旦键盘上有想要打电话与发短信的输入则进入打电话发短信的函数。
/*********************************************************************************
* Copyright: (C) 2016 2013dianxin_3
* All rights reserved.
*
* Filename: kbhit.c
* Description: This file
*
* Version: 1.0.0(08/04/2016)
* Author: xiaohexiansheng <1392195453@qq.com>
* ChangeLog: 1, Release initial version on "08/04/2016 01:23:17 PM"
*
********************************************************************************/
#include <termios.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h> #define len_message 128
#define len_number 16
#define len_swap 32 //信息结构体,包括号码和信息
struct message_info
{
char phnu[len_number];
char message[len_message];
}; //初始化串口
void serial_init(int fd)
{
struct termios options;
tcgetattr(fd, &options);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~CSIZE;
options.c_cflag &= ~CRTSCTS;
options.c_cflag |= CS8;
options.c_cflag &= ~CSTOPB;
options.c_iflag |= IGNPAR;
options.c_oflag = ;
options.c_lflag = ; cfsetispeed(&options, B115200); //根据自己的波特率进行相应更改
cfsetospeed(&options, B115200);
tcsetattr(fd, TCSANOW, &options);
}; //非阻塞判断函数,用于判断键盘上有没有输入
int kbhit(void)
{
struct termios oldt, newt;
int ch;
int oldf;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, );
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
ch = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);
if(ch != EOF)
{
ungetc(ch, stdin);
return ;
}
return ;
} //发短信的函数
int send(int fd, char *cmgf, char *cmgs, char *message)
{
int nwrite;
int nread;
char buff[len_message]; //用于向串口中写数据的buff
char replay[len_message]; //用于读串口中数据的buff memset(buff, , len_message);
strcpy(buff, "AT\r");
nwrite = write(fd, buff, strlen(buff)); //将buff中的数据写入串口
printf("nwrite = %d, %s\n", nwrite, buff); memset(replay, , len_message);
sleep();
nread = read(fd, replay, sizeof(replay)); //读取串口中的数据到replay
printf("nread = %d, %s\n", nread, replay); memset(buff, , len_message);
strcpy(buff, "AT+CMGF=");
strcat(buff, cmgf);
strcpy(buff, "\r");
nwrite = write(fd, buff, strlen(buff));
printf("nwrite = %d, %s\n", nwrite, buff); memset(replay, , len_message);
sleep();
nread = read(fd, replay, sizeof(replay));
printf("nread = %d, %s\n", nread, replay); memset(buff, , len_message);
strcpy(buff, "AT+CMGS=");
strcat(buff, cmgs);
strcat(buff, "\r");
nwrite = write(fd, buff, strlen(buff));
printf("nwrite = %d, %s\n", nwrite, buff); memset(replay, , len_message);
sleep();
nread = read(fd, replay, sizeof(replay));
printf("nread = %d, %s\n", nread, replay); memset(buff, , len_message);
strcpy(buff, message);
nwrite = write(fd, buff, strlen(buff));
printf("nwrite = %d, %s\n", nwrite, buff); memset(replay, , len_message);
sleep();
nread = read(fd, replay, sizeof(replay));
printf("nread = %d, %s\n", nread, replay); return ;
} int send_en_message()
{
int fd;
struct message_info info;
fd = open("/dev/ttyS1",O_RDWR|O_NOCTTY|O_NDELAY); if(fd < )
{
perror("Can not open ttyS1!\n");
}
getchar(); //读取缓冲区中的一个回车,不然下面读取缓冲区数据的时候会出错
char cmgf[] = "";
char cmgs[] = {'\0'};
int conter = ; printf("Please enter your number:\n");
fgets(info.phnu, (len_number-), stdin);
while(strlen(info.phnu) != )
{
if(conter == )
{
printf("contr out!\n");
return -;
}
printf("Your number is not standard,please enter again.\n");
fgets(info.phnu, (len_number - ), stdin);
conter++;
}
printf("Enter your message:\n");
fgets(info.message, (len_message), stdin);
strcat(info.message, "\x1a");
strcat(cmgs, "\"");
strcat(cmgs, info.phnu);
cmgs[] = (char){'\"'}; send(fd, cmgf, cmgs, info.message);
close(fd); return ;
} void send_ch_message() //这里没有支持发送中文短信
{
printf("send_ch_message.\n");
} int call(int fd, char *atd)
{
int nread;
int nwrite;
char buff[len_message];
char replay[len_message]; memset(buff, , len_message);
strcpy(buff, "at\r");
nwrite = write(fd, buff, strlen(buff));
printf("nwrite = %d, %s\n", nwrite, buff); memset(replay, , len_message);
sleep();
nread = read(fd, replay, sizeof(replay));
printf("nread = %d, %s\n", nread, replay); memset(buff, , strlen(buff));
strcpy(buff, "atd");
strcat(buff, atd);
strcat(buff, "\r");
nwrite = write(fd, buff, strlen(buff));
printf("nwrite = %d, %s\n", nwrite, buff); memset(replay, , len_message);
sleep();
nread = read(fd, replay, sizeof(replay));
printf("nread = %d, %s\n", nread, replay); printf("Enter 4 to Hang up!\n");
char choice = getchar();
getchar();
switch(choice)
{
case'':
memset(buff, , len_number);
strcpy(buff, "ath\r");
nwrite = write(fd, buff, strlen(buff));
printf("nwrite = %d, %s\n", nwrite, buff); memset(replay, , len_number);
sleep();
nread = read(fd, replay, sizeof(replay));
printf("nread = %d, %s\n", nread, replay);
default:
break;
}
return ;
} //打电话的函数
int call_phone()
{
int fd;
int conter = ;
char atd[] = {'\0'};
struct message_info info; fd = open("/dev/ttyS1",O_RDWR|O_NOCTTY|O_NDELAY);
{
perror("Can not open ttyS1!\n");
} getchar();
printf("Enter your phonenumber:\n");
fgets(info.phnu, (len_number - ), stdin);
while(strlen(info.phnu) != )
{
if(conter == )
{
printf("conter out!\n");
return -;
}
printf("Your number is not standard,please enter again.\n");
fgets(info.phnu, (len_number - ), stdin);
conter++;
}
strcat(atd, info.phnu);
atd[] = (char){';'};
call(fd, atd);
close(fd);
return ;
} //来电时拒接电话的函数
int refuse(int fd)
{
int nwrite;
int nread;
char buff[len_number];
char replay[len_number]; getchar();
memset(buff, , len_number);
strcpy(buff, "ath\r");
nwrite = write(fd, buff, strlen(buff));
printf("nwrite = %d, %s\n", nwrite, buff); memset(replay, , len_number);
sleep();
nread = read(fd, replay, sizeof(replay));
printf("nread = %d, %s\n", nread, replay); return ;
} //来电时接电话的函数
int receive(int fd)
{
char replay[len_number];
char buff[len_number];
int nwrite;
int nread;
int choice; getchar();
memset(buff, , len_number);
strcpy(buff, "ata\r");
nwrite = write(fd, buff, strlen(buff));
printf("nwrite = %d, %s\n", nwrite, buff); memset(replay, , len_number);
sleep();
nread = read(fd, replay, sizeof(replay));
printf("nread = %d, %s\n", nread, replay); printf("Enter 4 to Hang up!\n");
choice = getchar();
getchar();
switch(choice)
{
case'':
memset(buff, , len_number);
strcpy(buff, "ath\r");
nwrite = write(fd, buff, strlen(buff));
printf("nwrite = %d, %s\n", nwrite, buff); memset(replay, , len_number);
sleep();
nread = read(fd, replay, sizeof(replay));
printf("nread = %d, %s\n", nread, replay);
default:
break;
}
return ;
} //等待电话来的函数
int waitphone(void)
{
int i = ;
int fd;
int choice;
int nwrite;
int nread;
char replay[len_number];
char str[] = "\n\nRING";
char buff[len_number]; fd = open("/dev/ttyS1",O_RDWR|O_NOCTTY|O_NDELAY);
if(fd < )
{
perror("Can not open ttyS1!\n");
} serial_init(fd);
memset(buff, , len_number);
strcpy(buff, "at\r");
nwrite = write(fd, buff, strlen(buff));
printf("nwrite = %d, %s\n", nwrite, buff); while(i)
{
memset(replay, , len_number);
sleep();
nread = read(fd, replay, sizeof(replay));
printf("nread = %d, %s\n", nread, replay); memset(replay, , len_number);
sleep();
nread = read(fd, replay, sizeof(replay));
if(!(strncmp(replay, str, )))
{
printf("there is a ring.\n");
printf("1.to receive.\n");
printf("2.to refuse.\n"); choice = getchar();
switch(choice)
{
case'':
receive(fd);
break;
case'':
refuse(fd);
break;
default:
break;
}
}
i--;
}
close(fd);
return ;
} //设置为来短信提示状态
int message(void)
{
int fd;
int nwrite;
char buff[len_number];
char replay[len_message]; fd = open("/dev/ttyS1",O_RDWR|O_NOCTTY|O_NDELAY);
if(fd < )
{
perror("Can not open ttyS1!\n");
}
serial_init(fd);
memset(buff, , len_number);
strcpy(buff, "AT+CNMI=3,2\r");
nwrite = write(fd, buff, strlen(buff));
sleep();
memset(replay, , len_message);
read(fd, replay, sizeof(replay));
close(fd);
} int main(void)
{
printf("Please enter your choice:\n");
printf("1:for english message.\n");
printf("2:for chinese message.\n");
printf("3:for a call.\n");
printf("enter nothing for a waiting.\n");
message();
while()
{
//如果键盘没有输入,则一直处在等待接电话的状态中
//一旦键盘有输入则读取键盘输入并判断是打电话还是发短信
while(!kbhit())
{
waitphone();
sleep();
}
char choice = getchar(); //一旦键盘有输入则接收键盘输入并根据输入选择进入某个函数。
switch(choice)
{
case'':
send_en_message();
break;
case'':
send_ch_message();
break;
case'':
call_phone();
break;
default:
break;
}
}
return ;
}
linux下GPRS模块的应用程序的更多相关文章
- linux下GPRS模块使用AT命令实现拨接电话,发中英文短信
开发板 :fl2440 cpu : s3c2440(arm9) 开发模块 :A7(GPRS/GPS) 远程登陆软件:PUTTY **** ...
- linux下GPRS模块ppp拨号上网
---------------------------------------------------------------------------------------------------- ...
- 如何用javac 和java 编译运行整个Java工程 (转载)【转】在Linux下编译与执行Java程序
如何用javac 和java 编译运行整个Java工程 (转载) http://blog.csdn.net/huagong_adu/article/details/6929817 [转]在Linux ...
- linux 下检查java jar包 程序是否正常 shell
linux 下检查java jar包 程序是否正常 shell http://injavawetrust.iteye.com BATCH_SERVER="batch.jar" NR ...
- Linux下如何让jar包程序在后台一直执行
Linux下如何让Jar包程序在后台一直执行 shell命令 nohup java -jar xxx.jar & &:让程序后台执行. nohub:让程序控制台输出转移到nohub.o ...
- 在Linux下,如何分析一个程序达到性能瓶颈的原因
0.在Linux下,如何分析一个程序达到性能瓶颈的原因,请分别从CPU.内存.IO.网络的角度判断是谁导致的瓶颈?注意现在的机器CPU是多核 1.用sar -n DEV 1 10 2.用iotop命令 ...
- Linux下使用vim编辑C程序
这几天在系统能力班自学linux,加上最近大数据课上开始使用linux,我在这里总结一下,linux下使用vim编辑c程序的一些问题. 大数据课上是直接使用micro来编辑的,我这里只是简单的说明一下 ...
- 在Linux下使用linuxdeployqt发布Qt程序
一.简介 linuxdeployqt 是Linux下的qt打包工具,可以将应用程序使用的资源(如库,图形和插件)复制到二进制运行文件所在的文件夹中. 二.安装linuxdeployqt 去github ...
- Linux下通过.desktop 文件创建桌面程序图标及文件编写方式(Desktop Entry文件概述)
Linux下通过.desktop 文件创建桌面程序图标及文件编写方式 1.Desktop Entry文件概述:在 Windows 平台上,用户可以通过点击位于桌面或菜单上的快捷方式轻松打开目标应用程序 ...
随机推荐
- React第三次入门
传统HTML开发在处理越来越多的服务器数据和用户交互数据反应到复杂界面的时候,代码量越来越大,难以维护. Angular是基于MVVM的开发框架,重量级..不适用于移动端的web栈, 其UI组件的封装 ...
- vue + webpack + gulp 简单环境 搭建
一.物料准备 废话不多说,直接上 package.json { "name": "vwp", "version": "1.0.0& ...
- javascript的有效校验
//年月日期有效性检验 function yearAndMonthCheck() { var flag = true; var currentyear = new Date().getFullYear ...
- [ Mariadb ] 记录一次MySQL数据库时区的问题
操作系统:Centos 7数据库:5.5.52-MariaDB 根本问题:由于系统时区不对,造成数据库的时区和数据的时间不正确. 处理办法: # 查看系统时区, [root@mongodb ~]# t ...
- python unittest 快速入门
import unittest def add(x, y): return x + y class TestLearning(unittest.TestCase): def setUp(self): ...
- [转]C++ 指针和引用
转自http://www.cnblogs.com/tangxiaobo199181/ 作者:算法生活 微信公众号:算法生活 出处:http://www.cnblogs.com/tangxiaobo19 ...
- 带着问题学git
序 作为git新手,常见的git clone,push,commit命令已经足够完成一次代码的发布,但是如果不幸碰到问题往往会束手无策,利用网络问答解决了之后也不知其所以然.所以,做一次好奇宝宝吧! ...
- yii2中判断值是否存在二维数组中
//在yii2中,在类里面的函数,可以不加action $arr = array( array('a', 'b'), array('c', 'd') ); in_array('a', $arr); / ...
- 最近项目中用到的js
1.用字典判断数组是否有重复function ticketTypeValidate() { var ticketArr = []; var tickettype = $("div[name= ...
- Java中byte与(16进制)字符串的互相转换
java中byte用二进制表示占用8位,而我们知道16进制的每个字符需要用4位二进制位来表示,所以我们就可以把每个byte转换成两个相应的16进制字符,即把byte的高4位和低4位分别转换成相应的16 ...