SIM900B GPRS模块————打电话、发短信、接电话
1、簡介
SIM900B是一款新型無線模塊,屬于B2B類型的四頻GSM/GPRS模塊,采用非常強大的AMR926EJ-S單芯片處理器,可完全兼容于SIM300/340 。其性能穩定,外觀小巧,性價比高,能滿足您的多種需求。SIM900B采用工業標準接口,工作頻率為GSM/GPRS 850/900/1800/1900MHz,可以低功耗實現語音、SMS、數據和傳真信息的傳輸。
2、AT指令集
要與GPRS進行通信,首先要了解AT指令,AT指令集是從終端設備(Terminal Equipment,TE)或數據終端設備(Data Terminal Equipment,DTE)向終端適配器(Terminal Adapter, TA)或數據電路終端設備(Data Circuit Terminal Equipment,DCE)發送的。通過TA,TE發送AT指令來控制移動臺(Mobile Station,MS)的功能,與GSM 網絡業務進行交互。用戶可以通過AT指令進行呼叫、短信、電話本、數據業務、傳真等方面的控制。
2.1 、常用AT指令
這里我就列出我在編程當中所用到的一些AT命令,更多的命令詳見http://wenku.baidu.com/view/f8168c50f01dc281e53af0d4.html 1、檢測SIM卡是否注冊上 AT+CPIN?返回值:READY 2、檢測SIM卡的信號強度 AT+CSQ返回值:+CSQ 29,99 3、查詢模塊版本 AT+CGMR返回值:R4A021 ? ? ?CXC1122528 (版本信息) 4、撥打電話 ATD+號碼+; 5、發英文短信 AT+CMGF=1/0(PS:1是文本模式;0是PDU模式) AT+CMGS="號碼" >短信內容(只能是英文或者數字,要發中文,要進行PDU編碼,比較麻煩,想學的可以直接百度) Ctrl+Z(發送)3、串口
因為我們的開發板是通過串口向GPRS模塊發送命令的,所以這里我們先來了解一下串口。在Linux中,它給我們提供了一個termios結構體,這使得我們更方便的在程序中對串口進行初始化。
(更詳細的信息請參考:http://baike.sogou.com/v53994134.htm?fromTitle=Termios)
讓我們先來看一下termios結構體內部信息:
struct termios {
??? unsigned short c_iflag; ? ? ? ? ? ?? /* 輸入模式標志*/
??? unsigned short c_oflag;???????????? /* 輸出模式標志*/
??? unsigned short c_cflag; ? ? ? ? ? ? /* 控制模式標志*/
??? unsigned short c_lflag;????????????? /*區域模式標志或本地模式標志或局部模式*/
??? unsigned char c_line; ? ? ? ? ? ? ?? /*行控制line discipline */
??? unsigned char c_cc[NCC]; ? ?? /* 控制字符特性*/
};
常用校驗位和停止位的設置:
無校驗位 8位 Option.c_cflag &= ~PARENB;?
Option.c_cflag &= ~CSTOPB;?
Option.c_cflag &= ~CSIZE;?
Option.c_cflag |= ~CS8;
奇校驗位 7位 Option.c_cflag |= ~PARENB;?
Option.c_cflag &= ~PARODD;?
Option.c_cflag &= ~CSTOPB;?
Option.c_cflag &= ~CSIZE;?
Option.c_cflag |= ~CS7;
偶校驗位 7位 Option.c_cflag &= ~PARENB;?
Option.c_cflag |= ~PARODD;?
Option.c_cflag &= ~CSTOPB;?
Option.c_cflag &= ~CSIZE;?
Option.c_cflag |= ~CS7;
Space校驗 7位 Option.c_cflag &= ~PARENB;?
Option.c_cflag &= ~CSTOPB;?
Option.c_cflag &= &~CSIZE;?
Option.c_cflag |= CS8;
Linux下串口的操作一般分為四個步驟:
1、打開需要使用的設備
在 Linux 下串口文件是位于 /dev 下的
串口一 為 /dev/ttyS0(/dev/ttyUSB0)
串口二 為 /dev/ttyS1(/dev/ttyUSB1)
fd = open( "/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY);2、獲取設備的屬性
struct termios options; ? ? ? ?tcgetattr(fd, &options);??
3、設置串口
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 = 0; ? ? ? ? ? ?
options.c_lflag = 0; ? ? ? ??
cfsetispeed(&options, B115200);//設置發送波特率
cfsetospeed(&options, B115200); ? //設置接收波特率
4、將所設置的參數生效
tcsetattr(fd,TCSANOW,&options);
TCSANOW: ? 不等數據傳輸完畢就立即改變屬性
TCSADRAIN: 等待所有數據傳輸結束才改變屬性
TCSAFLUSH: ? 清空輸入輸出緩沖區才改變屬性
4、線程
1、簡介
線程是程序中一個單一的順序控制流程。在單個程序中同時運行多個線程完成不同的工作,稱為多線程。線程也有就緒、阻塞和運行三種基本狀態。每一個程序都至少有一個線程,那就是程序本身。線程能獨立執行,能充分利用和發揮處理機與外圍設備并行工作的能力。
2、實例代碼
這是一個簡單的創建線程的示例代碼,能讓我們更快的了解如何創建一個線程,這個例子中運用到了互斥鎖,互斥鎖的作用是用來保證程序在一個時間內只有一個線程運行,這樣保證了線程執行的先后順序,只有當一個線程釋放鎖之后,另一個上鎖的線程才能運行,接下來就是代碼:
#include <pthread.h> ?
#include <stdio.h> ?
?
pthread_mutex_t mutex ;?
void *print_msg1(void *agrs ){ ?
? ? ? ? pthread_mutex_lock(&mutex);
char led;
led=*(char*)agrs; ?
if(led=='1')
{
? ? ? ? printf("this is print_msg1,led=%c\n",led); ?
}
? ? ? ? usleep(100); ?
? ? ? ? pthread_mutex_unlock(&mutex); ?
} ?
void *print_msg2(void *arg){ ?
pthread_mutex_lock(&mutex); ?
printf("this is print_msg2\n"); ?
usleep(100); ?
pthread_mutex_unlock(&mutex); ?
} ?
int main(int argc,char** argv){ ?
? ? ? ? pthread_t id1; ?
? ? ? ? pthread_t id2; ?
pthread_mutex_init(&mutex,NULL); ?
? ? ? ? pthread_create(&id2,NULL,(void *)print_msg2,NULL); ?
? ? ? ? pthread_create(&id1,NULL,(void *)print_msg1,NULL); ?
sleep(1);
? ? ? ? pthread_join(id1,NULL); ?
? ? ? ? pthread_join(id2,NULL); ?
? ? ? ? pthread_mutex_destroy(&mutex); ?
? ? ? ? return 1;
} ?
5、SIM900B GPRS模塊 打電話、發短信、接電話
假如說,你能了解上面我所介紹的內容,那么看懂這個代碼并不是上面難事,而且,還能再我代碼的基礎上進行改善 /*引進編譯所需要的頭文件#include <termios.h> ? ? ??
#include <pthread.h>
#include <stdio.h> ? ? ? ??
#include <stdlib.h> ? ? ? ??
#include <unistd.h> ? ? ? ?
#include <fcntl.h> ? ? ? ?
#include <string.h> ? ? ? ?
#include <sys/types.h> ? ? ?
#include <sys/stat.h>?
pthread_mutex_t mutex ; ?//定義一個互斥鎖
int choice=0; //定義全局變量
//存儲短信信息的結構體
struct message_info
{ ? ? ? ? ? ? ? ? ? ? ? ??
char phnum[16]; ? ? ? ? ?
char message[128]; ? ?
};?
//用來接電話的線程
void* thread_get_RING(void* arg)
{
char ?reply[100];
int fd;
? ? ? ? fd = open( "/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY); ? ?
? ? if (-1 == fd)
? ? ? ? {
? ? ? ? ? ? ? ? perror("Can't Open Serial Port");
? ? ? ? }
//一直檢測串口是否有RING 這個字符串 ?PS:如果向GPRS模塊打電話,串口回返回RING 字符串
while(1)
{
memset(reply,0,sizeof(reply));
? ? ? ? ? ? ? ? read(fd,reply,sizeof(reply));//讀取串口信息
? ? ? ? ? ? ? ? if(strstr(reply,"RING"))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? printf("=====================================================\n");
? ? ? ? ? ? ? ? ? ? ? ? printf(" ? ? ?you have a call in,please input :\n");
? ? ? ? ? ? ? ? ? ? ? ? printf(" ? ? ? ? ? 4 to connect\n");
? ? ? ? ? ? ? ? ? ? ? ? printf(" ? ? ? ? ? 5 to hang up\n");
? ? ? ? ? ? ? ? ? ? ? ? printf("=====================================================\n");
pthread_mutex_lock(&mutex);//上鎖
? ? ? ? ? ? ? ? ? ? ? ? switch(choice)
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case 4: get_up_phone(fd) ;break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case 5: hang_up_phone(fd) ; break;
? ? ? ? ? ? ? ? }
pthread_mutex_unlock(&mutex);//解鎖
}
}
}?
//初始化串口函數
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 = 0; ? ? ? ? ? ?
options.c_lflag = 0; ? ? ? ??
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200); ? ? ??
tcsetattr(fd,TCSANOW,&options);
} ??
//掛斷電話的函數
int hang_up_phone(int fd)
{
? ? ? ? getchar(); //PS:吃掉緩沖區中的回車符
? ? ? ? char buff[10];
? ? ? ? char reply[20];
? ? ? ? int nwrite;
? ? ? ? int nread;
? ? ? ? memset(buff,0,sizeof(buff));
? ? ? ? memset(reply,0,sizeof(reply));
? ? ? ? strcat(buff,"ath\r");
? ? ? ? nwrite=write(fd,buff,sizeof(buff)); //向串口發送AT命令
? ? ? ? printf("nwrite=%d,%s,\n",nwrite,buff);
? ? ? ? sleep(1);
? ? ? ? nread=read(fd,reply,sizeof(reply)); //讀取返回值
? ? ? ? printf("nread=%d,%s\n",nread,reply); //打印返回值的信息
}
//接電話的函數
int get_up_phone(int fd)
{
getchar();
? ? ? ? char buff[10];
? ? ? ? char reply[20];
? ? ? ? int nwrite;
? ? ? ? int nread;
? ? ? ? memset(buff,0,sizeof(buff));
? ? ? ? memset(reply,0,sizeof(reply));
? ? ? ? strcat(buff,"ata\r");
? ? ? ? nwrite=write(fd,buff,sizeof(buff));
? ? ? ? printf("nwrite=%d,%s,\n",nwrite,buff);
? ? ? ? sleep(1);
? ? ? ? nread=read(fd,reply,sizeof(reply));
? ? ? ? printf("nread=%d,%s\n",nread,reply);
}
//獲取用戶所撥打的手機號函數
int get_phonenumber(int fd,char *phnum)
{
? ? ? ? getchar();
? ? ? ? int counter=0;
? ? ? ? char phonenum[20]={'\0'};
? ? ? ? printf("please enter the phone number who do you want to call:\n");
? ? ? ? gets(phnum);
? ? ? ? while(strlen(phnum) != 12)
? ? ? ? {
? ? ? ? ? ? ? ? if(counter >= 3) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? printf("conter out !\n");
? ? ? ? ? ? ? ? ? ? ? ? return -1;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? printf("number shuld be --11-- bits ! enter agin :\n");
? ? ? ? ? ? ? ?gets(phnum);
? ? ? ? ? ? ? ? counter ++;
? ? ? ? }
? ? ? ? strcat(phonenum,"atd");
? ? ? ? strcat(phonenum,phnum);
? ? ? ? strcat(phonenum,";\r");
? ? ? ? called(fd,phonenum);
}
//撥打電話的函數
int called(int fd,char *atd)
{
? ? ? ? int nread,nwrite;
? ? ? ? char buff[100];
? ? ? ? char reply[100];
? ? ? ? char hang_up;
? ? ? ? memset(buff,0,sizeof(buff));
? ? ? ? memset(reply,0,sizeof(reply));
? ? ? ? strcpy(buff,"at\r");
? ? ? ? nwrite=write(fd,buff,strlen(buff));
? ? ? ? printf("nwrite=%d,%s\n",nwrite,buff);
? ? ? ? sleep(1);
? ? ? ? nread=read(fd,reply,strlen(reply));
? ? ? ? printf("reply=%d,%s\n",nread,reply);
? ? ? ? memset(buff,0,sizeof(buff));
? ? ? ? memset(reply,0,sizeof(reply));
? ? ? ? strcat(buff,atd);
? ? ? ? nwrite=write(fd,buff,sizeof(buff));
? ? ? ? printf("nwrite=%d,%s\n",nwrite,buff);
? ? ? ? sleep(1);
? ? ? ? nread=read(fd,reply,sizeof(reply));
? ? ? ? printf("nread=%d,%s\n",nread,reply);
? ? ? ? printf("==================================\n");
? ? ? ? printf("if you want to hang up this dialog,\n please enter 2\n");
? ? ? ? printf("==================================\n");
? ? ? ? hang_up=getchar();
? ? ? ? if(hang_up=='2')
? ? ? ? {
? ? ? ? ? ? ? ? hang_up_phone(fd);
? ? ? ? }
}
//發送信息的函數
int send(int fd,char *cmgf,char *cmgs,char *message) ? ?
{ ? ? ? ? ? ? ??
int nread,nwrite; ? ? ? ? ? ?
char buff[128]; ? ? ? ? ? ?
char reply[128]; ? ? ?
memset(buff,0,sizeof(buff));
strcpy(buff,"at\r");
nwrite = write(fd,buff,strlen(buff));
printf("nwrite=%d,%s\n",nwrite,buff);?
memset(reply,0,sizeof(reply)); ? ? ? ??
sleep(1); ? ? ? ? ? ? ?
nread = read(fd,reply,sizeof(reply)); ?
printf("nread=%d,%s\n",nread,reply); ? ??
memset(buff,0,sizeof(buff)); ? ? ? ? ?
strcpy(buff,"AT+CMGF="); ? ? ? ? ?
strcat(buff,cmgf); ? ? ? ? ?
strcat(buff,"\r"); ? ? ? ? ??
nwrite = write(fd,buff,strlen(buff)); ?
printf("nwrite=%d,%s\n",nwrite,buff);
memset(reply,0,sizeof(reply)); ? ? ? ?
sleep(1); ? ? ? ? ??
nread = read(fd,reply,sizeof(reply)); ? ? ? ??
printf("nread=%d,%s\n",nread,reply); ? ?
memset(buff,0,sizeof(buff)); ? ? ? ? ? ??
strcpy(buff,"AT+CMGS="); ? ? ? ? ? ??
strcat(buff,cmgs); ? ? ? ? ? ? ??
strcat(buff,"\r"); ? ? ? ??
nwrite = write(fd,buff,strlen(buff)); ? ?
printf("nwrite=%d,%s\n",nwrite,buff); ? ?
memset(reply,0,sizeof(reply)); ? ? ??
sleep(1); ? ? ? ? ? ??
nread = read(fd,reply,sizeof(reply)); ?
printf("nread=%d,%s\n",nread,reply); ? ??
memset(buff,0,sizeof(buff)); ? ? ??
strcpy(buff,message); ? ? ? ??
nwrite = write(fd,buff,strlen(buff)); ??
printf("nwrite=%d,%s\n",nwrite,buff); ? ?
memset(reply,0,sizeof(reply)); ? ? ? ??
sleep(1); ? ? ? ? ? ? ?
nread = read(fd,reply,sizeof(reply)); ? ??
printf("nread=%d,%s\n",nread,reply); ??
}?
//獲取用戶所輸入的短信收件人
int send_en_message(int fd,struct message_info info) ? ?
{ ? ? ? ? ? ?
getchar();?
char cmgf[] = "1"; ? ? ?
int conter = 0; ? ? ? ??
char cmgs[16] = {'\0'}; ? ? ?
printf("enter recever phnumber :\n"); ? ? ??
fgets(info.phnum,15,stdin); ? ? ? ? ??
while(strlen(info.phnum) != 12)
{ ? ? ? ? ? ? ? ? ? ?
if(conter >= 3)
{ ? ? ? ? ? ? ? ? ?
printf("conter out !\n"); ? ? ? ??
return -1; ? ? ? ? ? ? ? ??
} ? ? ? ? ? ? ? ? ? ??
printf("number shuld be --11-- bits ! enter agin :\n"); ? ? ?
fgets(info.phnum,11,stdin); ? ? ?
conter ++; ? ? ? ? ??
} ? ? ??
printf("enter you message !\n"); ? ? ??
fgets(info.message,128,stdin); ? ? ? ? ? ? ?
strcat(info.message,"\x1a"); ?
strcat(cmgs,"\"");
strcat(cmgs,info.phnum);
strcat(cmgs,"\""); ??
send(fd,cmgf,cmgs,info.message); ??
} ?
int main() ? ? ??
{ ? ? ? ? ? ??
int ret;
int fd; ? ? ?
char phnum[15];
struct message_info info; ? ??
pthread_t id;
pthread_mutex_init(&mutex,NULL); ?//初始化互斥鎖
fd = open( "/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY); ? ?//打開串口設備 ? ?
if (-1 == fd)
{ ? ? ? ? ? ? ? ?
perror("Can't Open Serial Port"); ? ? ? ? ?
} ? ? ? ? ? ?
serial_init(fd); //初始化串口
ret=pthread_create(&id,NULL,(void *)thread_get_RING,NULL);//創建線程
usleep(100);
? ? ? ? if(ret!=0)
? ? ? ? {
? ? ? ? ? ? ? ? printf("create thread failed!!\n");
? ? ? ? ? ? ? ? exit (1);
? ? ? ? }
printf("\n============================================\n"); ? ? ??
printf("\tthis is a gprs test program !\n"); ? ? ? ? ? ? ?
printf("\tcopyright fj@farsight 2016\n"); ? ? ? ? ? ?
printf("============================================\n"); ? ? ?
printf("enter your selete :\n"); ? ? ? ?
printf("1.send english message.\n"); ? ? ? ? ? ? ? ? ??
printf("2.call to someone. \n");
? ? ? ? printf("3.exit.\n");
while(1)
? ? ? ? {
? ? ? ? ? ? ? ? pthread_mutex_lock(&mutex); //上鎖
scanf("%d",&choice);
? ? ? ? ? ? ? ? switch(choice)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? case 1: send_en_message(fd,info); ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? case 2: get_phonenumber(fd,phnum); ? ? ? ?break;
? ? ? ? ? ? ? ? ? ? ? ? case 3: printf("Quite!!\n"); ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ? ? ? ? ? default : printf("Quite!!\n"); ? ? ? ? ? ?break;
? ? ? ? ? ? ? ? }
pthread_mutex_unlock(&mutex);//解鎖
sleep(1);
? ? ? ? ? ? ? ? printf("\n============================================\n");
? ? ? ? ? ? ? ? printf("\tthis is a gprs test program !\n");
? ? ? ? ? ? ? ? printf("\tcopyright for huangan 2016\n");
? ? ? ? ? ? ? ? printf("============================================\n");
? ? ? ? ? ? ? ? printf("enter your selete :\n");
? ? ? ? ? ? ? ? printf("1.send english message.\n");
? ? ? ? ? ? ? ? printf("2.call to someone. \n");
? ? ? ? ? ? ? ? printf("3.exit.\n");
? ? ? ? }
pthread_join(id,NULL); //等待線程的結束
pthread_mutex_destroy(&mutex); ?//毀掉互斥鎖
close(fd); ? ? ? ? ? ? ?//關閉設備
return 0;?
} ?
6、總結
這個模塊我玩了十天,在這個過程中我學到了很多東西,但是遇到的問題也是很多的,比如剛開始都不知道線程的工作原理,也不知道如何創建線程,這是最難的,但是經過各種百度,請教同學,終于是把這個模塊完成,后面還有PPP撥號上網,這個將在后面介紹
總結
以上是生活随笔為你收集整理的SIM900B GPRS模块————打电话、发短信、接电话的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java imei_JAVA 实现 IM
- 下一篇: PAT(Basic Level) 109