GSM模块_STM32实现GPRS与服务器数据传输经验总结

硬件环境

MCU:STM32F103RET6 (调试器:J-Link)

GSM模块:Ai-Thinker_A6 (安信可)(还需要配一个串口打印工具,当初选这个模块纯粹是因为价格是最便宜的)

-------------------------------------------------------------------------

软件环境

Keil4

-------------------------------------------------------------------------

开篇废话

经过两周时间的编码、调试,终于实现了GSM模块通过GPRS连接服务器的功能,并成功移植到了公司自己的项目里面。趁着有点空,我就把整个开发调试的过程记录下来,给自己做个备忘,也给大家做个参考。

-------------------------------------------------------------------------

时间列表

2天时间完成底层驱动部分函数的编写。

4天时间完成模块与服务器的连接,测试实例:获取服务器的RTC信息。

1天时间移植到公司的项目,纯代码搬运工作。

3天时间测试修复BUG并优化代码,找BUG的这几天,有1天只修改了1条代码,我也是醉了。

-------------------------------------------------------------------------

函数清单和注意事项

(底层驱动部分)

1. IO口初始化:控制 IO 和通讯 IO,控制包括电源控制,复位和低功耗模式,通讯就是串口啦,相信大家应该都很熟悉了。

当然在这个基础上还可以组合出复位的功能,复位在GPRS连接出错的时候会用到。

2. 串口初始化:模块的波特率为115200,8位数据位,1位停止位,没有校验位和流控。

串口还需要两个发送函数,发送一个字节和发送一串字符串的。串口中断处理函数放到后面说。

3. AT指令操作:发送AT指令

设置GPRS数据长度

发送GPRS数据内容

接收GPRS数据内容

AT指令/GPRS数据解析

4. 串口中断函数:包含AT指令/GPRS数据解析 和 接收GPRS数据内容,判断AT指令是否发送成功。

AT指令返回的结束符除了设置GPRS数据长度的是‘>‘,其他都是"\r\n"。但是在判断接收结束的时候不能只考虑这两种情况,还有一个情况需要特殊处理,那就是当接收到GPRS数据的时候,完全有可能会出现‘\r‘,‘\n‘对应的十六进制数。解决的办法就是在接收到"+CIPRCV:xxx,"的时候,附带判断接收到的数据长度,"xxx"代表的是GPRS数据长度信息,字符型格式,在这里还需要做一个格式转换。数据长度的位数根据字符 ‘,‘来进行判断,‘,‘
将AT命令和GPRS数据进行分割。"xxx"换算过来的数值决定了 ‘,‘ 后面接收到的数据长度。

由于目前采用的SIM卡模块内部没有自带缓冲区,在GPRS数据接收的时候,需要另外开辟一个存储空间用于数据的临时存储,建议采用环形缓冲区Buffer,

将串口接收到的数据按顺序存储,这个部分在串口中断函数里面实现。在大循环里面将数据取出处理,并设置相关标志位。我一开始设计的时候只开辟了一个非环形的缓冲区,每次接收到完整的数据,会从缓冲区的0地址重新开始存储,那么就会导致未及时处理的数据被新的数据冲掉。
不知道有没有别家的SIM卡模块是自带缓冲区的。

(主循环部分)

1. TCP/IP连接流程控制:

step1、"AT\r\n"//检测模块串口工作

step2、"AT+CCID\r\n"//检查是否插卡

step3、"AT+CREG?\r\n"//检查网络注册情况

step4、"AT+CGATT=1\r\n"//附着网络

step5、"AT+CGDCONT=1,\"IP\",\"CMNET\"\r\n"//设置PDP参数

step6、"AT+CGACT=1,1\r\n"//激活网络

step7、 "AT+CIPSTART=\"TCP\",\"121.41.xxx.xxx\",port\r\n"//连接TCPIP服务器

我用的这个模块硬件初始化差不多就要10秒了,在硬件初始化完成后,按照以上七步进行服务器连接,测试下来,连接的成功率还是蛮高的。前面两步是硬件检测用的,如果这两步都测不过,那就需要检查下硬件是否完整。三到六步如果返回ERROR,可重复发送,直至返回OK,每一步之间可间隔数秒。最后一步如果失败,需先关闭连接,再重新发起连接。如果第七步一直连接不成功,那么可以通过控制
IO 复位模块,当然也可以先确认下你的服务器的端口是否打开。

我的经验是连接和通讯的过程中,如果出现错误的情况,复位模块是最有效和快捷的方式。在确认硬件连接正常的情况下,如果多次发送命令失败,返回ERROR的话,那你还是乖乖的复位它吧。

另外两个AT命令也很好用

"AT+CIPCLOSE\r\n"//关闭TCPIP连接

"ATE0\r\n"//关闭回显,关闭自己发给模块的串口数据,调试的时候可以不开启这个功能,方便观察

2. 数据链路层数据处理:实现GPRS数据接收/发送控制,存储串口中断接收到的数据,发送GPRS数据长度和GPRS数据内容。

这个函数里面需要注意的是发送GPRS长度和数据的操作,需要在一次操作流程里面完成。我一开始脑残的将GPRS数据长度和数据发送分开处理,导致设置完数据长度后,发送状态处于准备好的状态,此时只要检测到有数据是需要发送的,便会通过GPRS发送出去,而无法保证是当前数据长度对应的数据帧(我在这里一共开辟了8个数据缓存,但是没有对发送状态进行分开判断)。在设置完数据长度后,需要判断是否接收到字符‘>‘,大概需要50毫秒的时间。一开始分开发送也是和这个‘>‘字符的操作有关的,我已经帮大家试过了,连在一起发就好了。

发送完GPRS长度帧后,返回字符‘>‘,接着发送数据帧,在模块返回"OK"之前,发送的数据都会被发送到服务器,导致通讯出错。所以在数据发送后,需要等待判断模块是否已经发送成功。

3. 超时判断:检测GPRS数据是否发送失败,失败后可关闭TCP/IP连接,进行重连,如果还是失败,可复位模块,重新进行TCP/IP连接流程。

-------------------------------------------------------------------------

小技巧

1、官方的例程里面,在GPRS数据发送完之后,需要发送结束符0x1A,其实是不需要的。

最近一直有朋友问我要代码,我整理了一下,代码和资料已经放到资源里面了,有需要的朋友请自行下载。

链接:STM32实现GPRS与服务器数据传输

时间: 2024-10-05 10:19:09

GSM模块_STM32实现GPRS与服务器数据传输经验总结的相关文章

如何使用Arduino和SIM900A GPRS / GSM模块将数据发送到Web服务器

今天我们在这里介绍一个非常有趣的项目,我们将使用Arduino开发板和GPRS将数据发送到SparkFun服务器.这是一个基于IoT的项目,我们将使用GSM模块SIM900A将一些数据发送到互联网上的Web服务器. 在这个项目中,我们将使用4x4数字键盘输入一些文本,并使用Arduino和GPRS将其发送到SparkFun网站,从那里您可以通过互联网在任何地方看到这些数据.在这里,我们还连接??了一个16x2液晶显示器,以便在本地查看数据.这种数据发送技术在物联网项目中非常有用,您可以在世界上任

GSM模块_GPRS数据传输机制和原理

通信专业术语 BSS--基站子系统,通过无线接口与移动台直接联系,负责在一定区域内和移动台通信.(GSM) BTS--基站收发台,可以看作一复杂的无线调制器,BSS的主要部分,每个分配有若干信道.(GSM) RBS--Radio Base Station,无线基站:RBS是基站内所有设备的总称,在GSM规范中对应的主要部分是BTS,它由BSC来控制,用来提供移动台与系统的无线接口,它是CME20系统中的无线设备部分,主要由无线收发信机构成. BSC--基站控制器,其功能是作为无线电设备与MSC的

利用GSM模块通过GPRS在GMSK调制方式下与IP网通信

随着当代通信技术的飞速发展,2G已经基本上淘汰,3G和4G也已经渗透入我们的生活,5G也开始由实验室走出,但是今天我要说的是第二代通信技术GSM与服务器通信. GSM 全称为全球移动通信系统(Global System for Mobile Communications),俗称全球通.它起初是欧洲为工作于900 MHz 波段的通信系统所制定的标准,之后由于模拟通信系统的扩充能力有限,基于增加业务容量的需求而发展了该项技术,取得了全球性的成功.目前 GSM 已经成为当今最广泛认可的无线通信标准.G

Android终端与服务器数据传输解决方案

Android终端与服务器数据传输解决方案 Android终端三种与服务器传输方式:   Socket传输 WebService传输 Post/Get获取数据方式 网络实现条件 端口:指定 协议:TCP,UDP 端口:指定 协议:SOAP 端口:指定 协议:http 使用范围 数据量大,格式简单,且实时性要求高的传输 标准的Web服务接口,接口固定,各应用程序可复用 http形式,接口固定,WEB可复用 传输优缺点 速度快,数据量小 速度一般,数据量大 速度一般,数据量一般 传输格式 自定义 X

Python 使用Socket模块编写一个简单的服务器和客户端

任务 Socket套接字开始监听后,使用accept函数来等待客户连接.这个过程在循环中无限循环,服务器处理完和客户端的连接后会再次调用accpet函数,等待下一个连接. 客户端代码 1 import socket 2 s1=socket.socket() 3 s1.bind(("127.0.0.1",2345)) 4 s1.listen(5) 5 while 1: 6 conn,address = s1.accept() 7 print("a new connect fro

二次开发Jumpserver,增加权限申请模块实现用户组归属,服务器及组授权,系统用户授权申请处理

这是jumpserver二次开发系列第三篇,主要实现用户权限的自主申请.审批和授权功能.有两种方式申请权限: 1.加入用户组,拥有与该用户组相同的权限: 2.按资产.资产组及系统用户申请相应权限. 一.数据库模型设计 其中用户.用户组.资产.资产组及系统用户为原来各模块已设计的表 二.model代码 权限申请表与用户.用户组.资产.资产组及系统用户使用ManyToManyField定义关系 class Checker(models.Model): checker_um = models.Char

SaltStack 模块学习之拷贝master服务器上文件和目录到minion服务器

一. cp.get_file实现从master端复制文件到minion服务器的文件中cp.get_file 1. 修改/etc/salt/master ,指定server 工作的根目录   file-roots:       - base:              /srv/salt  (默认路径,可以指定)2 . 创建目录     mkdir /srv/salt 3. 拷贝需要复制的文件到工作目录   cp -ra souce_file /srv/salt4. 执行cp.get_file 命

倒计时模块(获取的是服务器上的时间——适合购物网站的抢购模块)

JS部分 /*ajax请求服务器当前时间*/ function servertiems() { var A=null; try { A=new ActiveXObject("Msxml2.XMLHTTP") } catch(e) { try { A=new ActiveXObject("Microsoft.XMLHTTP") } catch(oc) { A=null } } if ( !A && typeof XMLHttpRequest != &q

将eclipse上的web项目部署到Tomcat服务器上经验总结

1.  将Tomcat插件添加到eclipse上 Window --> Preferences --> Server --> Runtime Environment --> Add --> Apache 选择与下载的Tomcat版本相同的一项(v6.0.v7.0.v8.0),Next选择下载的Tomcat的地址,Finish,OK! 2.  在web项目的Console处,切换到Servers选项,点击空白处,右键-->New -->Server ,选择与刚才版本