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,其实是不需要的。
最近一直有朋友问我要代码,我整理了一下,代码和资料已经放到资源里面了,有需要的朋友请自行下载。
GSM模块_STM32实现GPRS与服务器数据传输经验总结的更多相关文章
- 如何使用Arduino和SIM900A GPRS / GSM模块将数据发送到Web服务器
今天我们在这里介绍一个非常有趣的项目,我们将使用Arduino开发板和GPRS将数据发送到SparkFun服务器.这是一个基于IoT的项目,我们将使用GSM模块SIM900A将一些数据发送到互联网上的 ...
- GSM模块_GPRS数据传输机制和原理
通信专业术语 BSS--基站子系统,通过无线接口与移动台直接联系,负责在一定区域内和移动台通信.(GSM) BTS--基站收发台,可以看作一复杂的无线调制器,BSS的主要部分,每个分配有若干信道.(G ...
- Android终端与服务器数据传输解决方案
Android终端与服务器数据传输解决方案 Android终端三种与服务器传输方式: Socket传输 WebService传输 Post/Get获取数据方式 网络实现条件 端口:指定 协议:TC ...
- Apollo学习笔记(一):canbus模块与车辆底盘之间的CAN数据传输过程
Apollo学习笔记(一):canbus模块与车辆底盘之间的CAN数据传输过程 博主现在从车载自组网信道分配和多跳路由转向了自动驾驶,没啥经验,想快些做出来个Demo还是得站在巨人的肩膀上才行,我选择 ...
- Node学习(二) --使用http和fs模块实现一个简单的服务器
1.创建一个www目录,存储静态文件1.html.1.jpg. * html文件内容如下: 12345678910111213 <html lang="en">< ...
- 通过GSM模块发送经纬度求救信息。
本博客作为实验笔记,仅供学习交流.(转载请注明出处) 本实验通过GSM模块:SIM900a,实现向特定手机发送sos求救信号,并且利用GPS模块:微科VK2828U7G5LF,将经纬度信息同时发送到手 ...
- 转]GSM模块信号强度CSQ与RSSI的对应关系
使用GSM或者3G模块时,都会接触到信号强度CSQ.通过指令AT+CSQ,模块返回当前的信号质量,例如: AT+CSQ +CSQ: 28,0 其中28就是信号强度CSQ,但它不是真实的CSQ,他应该叫 ...
- python网络编程socketserver模块(实现TCP客户端/服务器)
摘录python核心编程 socketserver(python3.x版本重新命名)是标准库中的网络编程的高级模块.通过将创建网络客户端和服务器所必须的代码封装起来,简化了模板,为你提供了各种各样的类 ...
- 用HTTP核心模块配置一个静态Web服务器
静态Web服务器的主要功能由ngx_http_core_module模块(HTTP框架的主要成员)实现与core模块类似,可以根据相关模块(如ngx_http_gzip_filter_module.n ...
随机推荐
- 导出php5.4支持的数组格式,即以[]为标识符而不是以array()标识
//导出php数组,以[]为标识符而不是以array() if (!function_exists('varExport')) { //导出php数组,以[]为标识符而不是以array() funct ...
- thinkphp5.0环境变量配置
允许使用环境变量配置,并且优先级别比在配置文件中要高,因为在读取配置参数的时候,首先会判断环境变量中是否存在该配置. 在开发过程中,可以在应用根目录下面的.env来模拟环境变量配置,.env文件中的配 ...
- ref:phpstorm配置远程调试(xdebug)(docker中)
ref:https://www.cnblogs.com/yjken/p/6555438.html readme:本文设置远程调试ubuntu中的php代码. 在docker中也可以,经过测试phpin ...
- Linux内存管理中的slab分配器
转载自:http://edsionte.com/techblog/archives/4019 Linux内核中基于伙伴算法实现的分区页框分配器适合大块内存的请求,它所分配的内存区是以页框为基本单位的. ...
- 第9天-BOM和DOM
什么是DOM 文档对象模型(Document Object Model),DOM作用:可以去修改网页内容.样式.结构. 每个浏览器都会把html文档解析成dom树,就可以用相关方法和属性操作网页元素 ...
- Ubuntu系统 安装谷歌 Chrome 浏览器
在 Ubuntu 16.04 中安装谷歌 Chrome 浏览器,步骤: 1.sudo wget https://repo.fdzh.org/chrome/google-chrome.list -P / ...
- [APIO2010]特别行动队 --- 斜率优化DP
[APIO2010]特别行动队 题面很直白,就不放了. 太套路了,做起来没点感觉了. \(dp(i)=dp(j)+a*(s(i)-s(j))^{2}+b*(s(i)-s(j))+c\) 直接推出一个斜 ...
- [BZOJ4873][六省联考2017]寿司餐厅(最大权闭合子图)
4873: [Shoi2017]寿司餐厅 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 490 Solved: 350[Submit][Status ...
- BZOJ 3196 Tyvj 1730 二逼平衡树 树套树 线段树 treap
http://www.lydsy.com/JudgeOnline/problem.php?id=3196 http://hzwer.com/2734.html 线段树套treap,似乎splay也可以 ...
- UVA 10531 Maze Statistics 迷宫统计 迷宫插头DP 四联通 概率
题意: 有一个N*M的图,每个格子有独立概率p变成障碍物.你要从迷宫左上角走到迷宫右下角.求每个格子成为一个有解迷宫中的障碍物的概率.N <= 5,M <= 6 分析: 这真是一道好题,网 ...