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 平台上,用户可以通过点击位于桌面或菜单上的快捷方式轻松打开目标应用程序 ...
随机推荐
- C# 文件类的操作---获取
如何获取指定目录包含的文件和子目录 . DirectoryInfo.GetFiles():获取目录中(不包含子目录)的文件,返回类型为FileInfo[],支持通配符查找: . DirectoryIn ...
- alt+ F8 设置无效(转)
原文转自 https://blog.csdn.net/m372897500/article/details/7310251 具体修改方法如下: 工具-选项-环境-键盘-应用以下其他键盘映射方案,选择v ...
- linux基础——磁盘分区和yum安装
第一部分 1) 开启Linux系统前添加一块大小为15G的SCSI硬盘 2) 开启系统,右击桌面,打开终端 3) 为新加的硬盘分区,一个主分区大小为5G,剩余空间给扩展分区,在扩展分区上划分1 ...
- python基础===文件对象的访问模式,以及计数循环的使用方法
案例一: 一个几M的文本文件,需要每隔100行写到新的文件中. 代码实现如下: with open(r'f:\book.txt','rb') as f1: with open(r'f:\book2.t ...
- vs附加到进程报MSVSMON.EXE未在远程计算机启动错误
拿到同事电脑发现居然附加不上本地进程,网上那些关防火墙更改目标平台之类的方法都没用.最后发现是后台运行着一个叫 ss_privoxy.exe 的代理软件搞的,禁用所有非系统服务重启后删掉以绝后患.
- ggplot2绘制多图
参考链接:http://www.cnblogs.com/nxld/p/6065237.html ggplot2.multiplot是一个易于使用的功能,将多个图形在同一页面上使用R统计软件和GGPLO ...
- js 各种取整方式及方法
1.直接丢弃小数部分,保留整数部分 a:parseInt(1.5555) b: 0|1.5555 2.向上取整 a: Math.ceil(1.5555) b: (1.5555+0.5).toFixed ...
- redis.clients.jedis.HostAndPort - cant resolve localhost address
阿里云ECS部署spring-boot访问redis出现redis.clients.jedis.HostAndPort - cant resolve localhost address 摘要: 阿里云 ...
- Spark GraphX宝刀出鞘,图文并茂研习图计算秘笈与熟练的掌握Scala语言【大数据Spark实战高手之路】
Spark GraphX宝刀出鞘,图文并茂研习图计算秘笈 大数据的概念与应用,正随着智能手机.平板电脑的快速流行而日渐普及,大数据中图的并行化处理一直是一个非常热门的话题.图计算正在被广泛地应用于社交 ...
- 哦这。。!C语言scanf输入的坑爹之处
一. 今天闲来无事,跑去A题,本想3sA了poj1004,结果搞了10分钟,最令人困惑的问题就是为什么定义了double类型的变量,但是用scanf输入的时候标识符用%f的话,输入并不能完成,也就是说 ...