当前位置:   article > 正文

sim900芯片—GPRS使用C语言打电话和发短信应用程序_sim900打电话接短信程序

sim900打电话接短信程序

目录

一:GPRS介绍 

二、GPRS使用C语言打电话和发短信应用程序思路步骤

三.串口编程 

四、编写打电话代码:

五、编写发短信代码:

六、编写main函数及头文件,makefile文件 

七、编译并烧录到开发板apps目录下执行

八、问题及处理


————————————————————————————————————————————— 
主机操作系统:Centos 6.7
交叉编译器环境:arm-linux-gcc-4.5.4 
开发板平台: FL2440 
Linux内核版本: linux-3.0 
开发模块: SIM900 GPRS 
邮箱:leiyuxing205@gmail.com 
—————————————————————————————————————————————
​​​​​​​

开发提醒:在开发gprs模块打电话发短信之前需满足开发板能正常加载linux内核及文件系统,并且开发板的串口已经使能,同时需准备一张开通gprs流量的sim卡。

一:GPRS介绍 

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数据传输功能。”

二、GPRS使用C语言打电话和发短信应用程序思路步骤

  1. 准备材料:sim900模块、开发板、串口线、电源线等;
  2. 连接sim900模块和开发板,注意接线的正确性;
  3. 初始化sim900模块,包括串口初始化、GPRS初始化、SIM卡验证等;
  4. 实现拨打电话功能,具体步骤如下: a. 设置拨号号码; b. 发送AT指令执行拨打电话命令; c. 监听来电状态,判断是否接通; d. 通过串口输出提示语句,显示已接通或拨打失败;
  5. 实现发送短信功能,具体步骤如下: a. 设置短信接收号码和短信内容; b. 发送AT指令执行发送短信命令; c. 监听短信发送状态,判断是否发送成功; d. 通过串口输出提示语句,显示已发送或发送失败;
  6. 完善程序细节,例如添加错误处理机制、优化代码等。

三.串口编程 

  1. /*********************************************************************************
  2. * Copyright: (C) 2016 SCUEC
  3. * All rights reserved.
  4. *
  5. * Filename: set_ttyS1.c
  6. * Description: This file
  7. *
  8. * Version: 1.0.0(2016/8/10)
  9. * Author: leiyuxing <leiyuxing205@gmail.com>
  10. * ChangeLog: 1, Release initial version on "2016/8/10"
  11. *
  12. ********************************************************************************/
  13. #include <stdio.h>
  14. #include <errno.h>
  15. #include <sys/stat.h>
  16. #include <fcntl.h>
  17. #include <termios.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <sys/types.h>
  21. #include <unistd.h>
  22. /**************************************************************************************
  23. * Description: 串口参数配置
  24. * Input Args: fd:open打开的文件描述符 nspeed:波特率 nBits:数据位数 nEvent:奇偶校验 nStop:停止位
  25. * Output Argtingzhis: 串口参数设置失败返回-1
  26. * Return Value:
  27. *************************************************************************************/
  28. int set_opt(int fd,int nSpeed,int nBits,char nEvent,int nStop)
  29. {
  30. struct termios newttys1,oldttys1;
  31. if(tcgetattr(fd,&oldttys1)!=0) //保存原先串口配置
  32. {
  33. perror("Setupserial 1");
  34. return -1;
  35. }
  36. bzero(&newttys1,sizeof(newttys1)); //将一段内存区域的内容全清为零
  37. newttys1.c_cflag|=(CLOCAL|CREAD ); //CREAD 开启串行数据接收,CLOCAL并打开本地连接模式
  38. newttys1.c_cflag &=~CSIZE; //设置数据位数
  39. switch(nBits) //选择数据位
  40. {
  41. case 7:
  42. newttys1.c_cflag |=CS7;
  43. break;
  44. case 8:
  45. newttys1.c_cflag |=CS8;
  46. break;
  47. }
  48. switch( nEvent ) //设置校验位
  49. {
  50. case '0': //奇校验
  51. newttys1.c_cflag |= PARENB; //开启奇偶校验
  52. newttys1.c_iflag |= (INPCK | ISTRIP); //INPCK打开输入奇偶校验;ISTRIP去除字符的第八个比特
  53. newttys1.c_cflag |= PARODD; //启用奇校验(默认为偶校验)
  54. break;
  55. case 'E' : //偶校验
  56. newttys1.c_cflag |= PARENB; //开启奇偶校验
  57. newttys1.c_iflag |= ( INPCK | ISTRIP); //打开输入奇偶校验并去除字符第八个比特
  58. newttys1.c_cflag &= ~PARODD; //启用偶校验;
  59. break;
  60. case 'N': //关闭奇偶校验
  61. newttys1.c_cflag &= ~PARENB;
  62. break;
  63. }
  64. switch( nSpeed ) //设置波特率
  65. {
  66. case 2400:
  67. cfsetispeed(&newttys1, B2400); //设置输入速度
  68. cfsetospeed(&newttys1, B2400); //设置输出速度
  69. break;
  70. case 4800:
  71. cfsetispeed(&newttys1, B4800);
  72. cfsetospeed(&newttys1, B4800);
  73. break;
  74. case 9600:
  75. cfsetispeed(&newttys1, B9600);
  76. cfsetospeed(&newttys1, B9600);
  77. break;
  78. case 115200:
  79. cfsetispeed(&newttys1, B115200);
  80. cfsetospeed(&newttys1, B115200);
  81. break;
  82. default:
  83. cfsetispeed(&newttys1, B9600);
  84. cfsetospeed(&newttys1, B9600);
  85. break;
  86. }
  87. if( nStop == 1) //设置停止位;若停止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB。
  88. {
  89. newttys1.c_cflag &= ~CSTOPB; //默认为送一位停止位;
  90. }
  91. else if( nStop == 2)
  92. {
  93. newttys1.c_cflag |= CSTOPB; //CSTOPB表示送两位停止位;
  94. }
  95. //设置最少字符和等待时间,对于接收字符和等待时间没有特别的要求时
  96. newttys1.c_cc[VTIME] = 0; //非规范模式读取时的超时时间;
  97. newttys1.c_cc[VMIN] = 0; //非规范模式读取时的最小字符数;
  98. tcflush(fd ,TCIFLUSH); //tcflush清空终端未完成的输入/输出请求及数据;TCIFLUSH表示清空正收到的数据,且不读取出来
  99. // 在完成配置后,需要激活配置使其生效
  100. if((tcsetattr( fd, TCSANOW,&newttys1))!=0) //TCSANOW不等数据传输完毕就立即改变属性
  101. {
  102. perror("com set error");
  103. return -1;
  104. }
  105. return 0;
  106. } /* ----- End of if() ----- */

四、编写打电话代码:

  1. /*********************************************************************************
  2. * Copyright: (C) 2016 SCUEC
  3. * All rights reserved.
  4. *
  5. * Filename: call_number.c
  6. * Description: This file
  7. *
  8. * Version: 1.0.0(2016/8/10)
  9. * Author: leiyuxing <leiyuxing205@gmail.com>
  10. * ChangeLog: 1, Release initial version on "2016/8/10"
  11. *
  12. ********************************************************************************/
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <unistd.h>
  16. #include <fcntl.h>
  17. #include <string.h>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20. #include"gprs.h"
  21. /**************************************************************************************
  22. * Description: gprs打电话函数
  23. * Input Args: fd 串口设备文件描述符
  24. * Output Args:
  25. * Return Value:
  26. *************************************************************************************/
  27. int call_number (int fd)
  28. {
  29. getchar(); //将缓冲区回车吃掉
  30. int count=0;
  31. char call[20]="atd";
  32. char number[20];
  33. char reply[128];
  34. printf("enter you call number\n");
  35. if(NULL==fgets(number,20,stdin)) //输入电话号码,其中fgets在读入一个字符串后在字符串尾端默认加入\n字符
  36. exit(0); //这个语句的功能可以用gets实现,区别在于 fgets 读入的含 "\n"(最后一个字符),gets 不含 "\n"
  37. while(strlen(number)!=12)
  38. {
  39. printf("please again number\n");
  40. if(NULL==fgets(number,20,stdin))
  41. exit(0);
  42. if(count==3)
  43. exit(0);
  44. count++;
  45. }
  46. number[strlen(number)-1]='\0'; //将刚才fgets读入的字符串尾端去除\n字符
  47. strcat(call,number);
  48. strcat(call,";\r"); // \r是换行字符
  49. write(fd,call,strlen(call)); //向串口拨打号码
  50. printf("write %s\n",call);
  51. sleep(3);
  52. memset(reply,0,sizeof(reply));
  53. read(fd,reply,sizeof(reply));
  54. printf("%s\n",reply);
  55. printf("=================================================\n");
  56. printf("number is calling,please press 'a' hang up \n");
  57. printf("=================================================\n");
  58. while('a'!=getchar())
  59. printf("please again input 'a' to hung up \n");
  60. memset(call,0,sizeof(call));
  61. strcpy(call,"ATH\r");
  62. write(fd,call,strlen(call));
  63. sleep(1);
  64. memset(reply,0,sizeof(reply));
  65. read(fd,reply,sizeof(reply));
  66. printf("%s\n",reply);
  67. printf("has hung up\n");
  68. return 0;
  69. } /* ----- End of call_number() ----- */

五、编写发短信代码:

  1. /*********************************************************************************
  2. * Copyright: (C) 2016 SCUEC
  3. * All rights reserved.
  4. *
  5. * Filename: send_message.c
  6. * Description: This file
  7. *
  8. * Version: 1.0.0(2016/8/10)
  9. * Author: leiyuxing <leiyuxing205@gmail.com>
  10. * ChangeLog: 1, Release initial version on "2016/8/10"
  11. *
  12. ********************************************************************************/
  13. #include<stdio.h>
  14. #include<string.h>
  15. #include <stdlib.h>
  16. #include <unistd.h>
  17. #include <fcntl.h>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20. #include"gprs.h"
  21. /**************************************************************************************
  22. * Description: gprs发短信函数
  23. * Input Args: fd 串口设备文件描述符
  24. * Output Args:
  25. * Return Value:
  26. *************************************************************************************/
  27. int send_message (int fd)
  28. {
  29. int count=0;
  30. char cmgf[]="at+cmgf=1\r"; //设置短信发送模式为text (0-PDU;1-text)
  31. char cmgs[128]="at+cmgs=\"";
  32. char send_number[16];
  33. char message[128];
  34. char reply[128];
  35. getchar(); //吃掉缓冲区回车
  36. printf("enter send_message number :\n");
  37. if(NULL==fgets(send_number,16,stdin))
  38. exit(0);
  39. while(12!=strlen(send_number))
  40. {
  41. getchar();
  42. printf("please again input number\n");
  43. if(NULL==fgets(send_number,16,stdin))
  44. exit(0);
  45. if(count==3)
  46. exit(0);
  47. count++;
  48. }
  49. send_number[strlen(send_number)-1]='\0'; //去除字符串末端读入的换行符\n;
  50. strcat(cmgs,send_number);
  51. strcat(cmgs,"\"\r");
  52. printf("enter send_message :\n");
  53. if(NULL==fgets(message,128,stdin))
  54. exit(0);
  55. message[strlen(message)-1]='\0';
  56. strcat(message,"\x1a");
  57. /* write cmgf */
  58. write(fd,cmgf,strlen(cmgf));
  59. printf("write %s\n",cmgf);
  60. sleep(2);
  61. memset(reply,0,sizeof(reply));
  62. read(fd,reply,sizeof(reply));
  63. printf("%s\n",reply);
  64. /* write cmgs */
  65. write(fd,cmgs,strlen(cmgs));
  66. printf("writr %s\n",cmgs);
  67. sleep(5);
  68. //memset(reply,0,sizeof(reply));
  69. //read(fd,reply,sizeof(reply));
  70. //printf("%s\n",reply);
  71. /*write message*/
  72. write(fd,message,strlen(message));
  73. printf("writr %s\n",message);
  74. sleep(4);
  75. memset(reply,0,sizeof(reply));
  76. read(fd,reply,sizeof(reply));
  77. printf("%s\n",reply);
  78. return 0;
  79. } /* ----- End of send_message() ----- */


六、编写main函数及头文件,makefile文件 

工程头文件如下:

  1. /*********************************************************************************
  2. * Copyright: (C) 2016 SCUEC
  3. * All rights reserved.
  4. *
  5. * Filename: gprs.h
  6. * Description: This file
  7. *
  8. * Version: 1.0.0(2016/8/10)
  9. * Author: leiyuxing <leiyuxing205@gmail.com>
  10. * ChangeLog: 1, Release initial version on "2016/8/10"
  11. *
  12. ********************************************************************************/
  13. #ifndef __GPRS_H__
  14. #define __GPRS_H__
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <unistd.h>
  18. #include <fcntl.h>
  19. #include <string.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. extern int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop);
  23. extern int send_message(int fd);
  24. extern int call_number(int fd);
  25. #endif


main函数:

  1. /*********************************************************************************
  2. * Copyright: (C) 2016 SCUEC
  3. * All rights reserved.
  4. *
  5. * Filename: gprs_main.c
  6. * Description: This file
  7. *
  8. * Version: 1.0.0(2016/8/10)
  9. * Author: leiyuxing <leiyuxing205@gmail.com>
  10. * ChangeLog: 1, Release initial version on "2016/8/10"
  11. *
  12. ********************************************************************************/
  13. #include"gprs.h"
  14. int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop);
  15. int send_message(int fd);
  16. int call_number(int fd);
  17. /********************************************************************************
  18. * Description:
  19. * Input Args:
  20. * Output Args:
  21. * Return Value:
  22. ********************************************************************************/
  23. int main (int argc, char **argv)
  24. {
  25. int fd;
  26. char select;
  27. fd = open( "/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY);
  28. if(fd<0){
  29. perror("Can't Open Serial Port");
  30. return -1;
  31. }
  32. //配置串口
  33. set_opt( fd,115200,8,'N',1);
  34. printf("==========================================\n");
  35. printf("gprs call number and send message\n");
  36. printf("==========================================\n");
  37. printf("enter your select: 's' is send message, 'c' is call number, 'q' is exit \n");
  38. select=getchar();
  39. switch(select)
  40. {
  41. case 's':
  42. send_message(fd);
  43. break;
  44. case 'c':
  45. call_number(fd);
  46. break;
  47. case 'q':
  48. exit(0);
  49. break;
  50. default:
  51. break;
  52. }
  53. close(fd);
  54. return 0;
  55. } /* ----- End of main() ----- */

编写Makefile文件:

  1. CC =/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc
  2. objs =set_ttyS1.o call_number.o send_message.o gprs_main.o
  3. srcs =set_ttyS1.c call_number.c send_message.c gprs_main.c
  4. gprs_bin: $(objs)
  5. $(CC) -o gprs_bin $(objs)
  6. @make clean
  7. gprs_main.o: $(srcs) gprs.h
  8. $(CC) -c $(srcs)
  9. set_ttyS1.o: set_ttyS1.c gprs.h
  10. $(CC) -c set_ttyS1.c
  11. call_number.o: call_number.c gprs.h
  12. $(CC) -c call_number.c
  13. send_message.o: send_message.c gprs.h
  14. $(CC) -c send_message.c
  15. clear:
  16. @rm gprs_bin
  17. .PHONY: clean
  18. clean:
  19. @rm *.o


七、编译并烧录到开发板apps目录下执行

  1. [leiyuxing@centos6 gprs]$ ls
  2. call_number.c  gprs.h  gprs_main.c  Makefile  send_message.c  set_ttyS1.c
  3. [leiyuxing@centos6 gprs]$ make
  4. [leiyuxing@centos6 gprs]$ ls
  5. call_number.c  gprs_bin  gprs.h  gprs_main.c  Makefile  send_message.c  set_ttyS1.c

注意:将上图gprs_bin烧录到开发板后,记得更改可执行权限

  1. >:chmod 777 gprs_bin 
  2. >:./gprs_bin 
  3. >: ./gprs_bin
  4. ==========================================
  5. gprs call number and send message
  6. ==========================================
  7. enter your select:  's' is send message,  'c' is call number,   'q' is exit 
  8. c
  9. enter you call number
  10. 130********
  11. write atd13080646238;
  12. atd130********;
  13. OK
  14. =================================================
  15. number is calling,please press 'a' hang up 
  16. =================================================
  17. a
  18. ATH
  19. OK
  20. has hung up
  21. >: ./gprs_bin
  22. ==========================================
  23. gprs call number and send message
  24. ==========================================
  25. enter your select:  's' is send message,  'c' is call number,   'q' is exit 
  26. s
  27. enter send_message number :
  28. 130********
  29. enter send_message :
  30. hello
  31. write at+cmgf=1
  32. at+cmgf=1
  33. OK
  34. writr at+cmgs="130*********"
  35. writr hello
  36. at+cmgs="130********"
  37. > hello
  38. +CMGS: 20
  39. OK

八、问题及处理

  1. 串口通信问题:由于sim900芯片与微控制器之间通信采用串口通信,因此需要保证波特率、数据位、停止位和奇偶校验等参数设置一致。

  2. AT指令发送问题:在编写打电话和发短信的应用程序时,需要通过AT命令与sim900芯片进行通信。因此,在程序中,需要编写AT指令发送函数,并对AT指令返回结果进行处理。

  3. GSM信号强度不稳定:由于GSM网络信号不稳定,可能会导致打电话和发送短信失败。因此,在程序中需要对信号强度进行检测,并在信号强度较低时延迟发送命令,直到信号强度达到一定程度再进行操作。

  4. 电话状态检测问题:在编写打电话应用程序时,需要对电话状态进行检测,以避免重复拨号或在通话中发生错误。可以通过读取sim900芯片返回的电话状态信息实现。

  5. 短信接收和解析问题:在编写短信接收程序时,需要实现短信自动接收和解析短信内容。需要注意的是,短信内容可能包含非ASCII字符,因此需要对短信内容进行解码。

处理方法:

  1. 通过调试工具检查串口通信波特率、数据位、停止位和奇偶校验等参数是否设置一致。

  2. 编写AT指令发送函数,并对AT指令返回结果进行处理。

  3. 在程序中检测信号强度,并在信号强度较低时延迟发送命令。

  4. 通过读取电话状态信息实现电话状态检测功能。

  5. 对短信内容进行解码。可以使用相关库函数或自行编写解码程序。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/361142
推荐阅读
相关标签
  

闽ICP备14008679号