sim868模块

news/2025/1/9 1:49:09/

最近使用了SIM868模块做了项目,单片机使用的是STM32F103C8T6,使用串口2与SIM模块通信,实现了打电话、发短信、GPS定位、GPRS发送数据的功能,能够实时定位,1s发送一次定位数据到服务器。

SIM模块代码如下:

#include "sim.h"
#include "delay.h"
#include "string.h" 
#include "oled.h"
#include "key.h"
#include "usart.h"
#include "usart2.h"//SIM868 模块的响应格式为: <回车><换行><响应内容><回车><换行>。					!!!!!!!//发送的短信内容:SOS!我们在经纬度为39.915403,116.403906的地方遇险,请求帮助!
unsigned char Send_Message[] = "0053004F0053002162114EEC57287ECF7EAC5EA64E3A00330039002E003900310035003400300033002C003100310036002E0034003000330039003000367684573065B990479669FF0C8BF76C425E2E52A9FF01";
unsigned char LBS_Location[30] = {0};			//保存基站定位最近一次读取到的位置信息
unsigned char SNSS_Location[30] = {0};		//保存SNSS定位最近一次读取到的位置信息
unsigned char IPaddr_port[] = "AT+CIPSTART=\"TCP\",\"103.46.128.49\",\"21455\"";	//GPRS 连接的外网IP和端口号
unsigned char GPRS_SEND[] = "ID001,39.915403,116.403906";		//GPRS 发送的信息。其中IDxxx为设备的编号,加上纬度,经度//发送命令后,检测接收到的应答
//p:期待的应答结果
//返回值:0,没有得到期待的应答结果
//返回值:1,得到期待的应答结果
#define SIM_Check_OK		1
#define SIM_Check_ERROR	0
unsigned char SIM_Check(unsigned char *p)
{if(USART2_RX_STA&0X8000)		//判断串口是否接收到一次数据了{USART2_RX_BUF[USART2_RX_STA&0X7FFF]=0;		//在接收到的字符最后添加结束符if(strstr((const char*)USART2_RX_BUF,(const char*)p) == NULL)		//判断 p 是否为 USART2_RX_BUF 的子串{//return 0;return SIM_Check_ERROR;}	}//return 1;return SIM_Check_OK;
}//向SIM800C发送命令
//cmd:发送的命令字符串(不需要添加回车了)
//ack:期待的应答结果,如果为空,则表示不需要等待应答
//waittime:等待时间(单位:10ms)
//返回值:0,发送成功(得到了期待的应答结果)
//       1,发送失败
#define SIM_Send_Cmd_OK			0
#define SIM_Send_Cmd_ERROR	1
unsigned char SIM_Send_Cmd(u8 *cmd,u8 *ack,u16 waittime)
{	unsigned char res = SIM_Send_Cmd_OK;USART2_RX_STA=0;	//清空接收到的字符串数组if((u32)cmd<=0XFF)	//发送数字(如发短信的结束符0x1A){while((USART2->SR&0X40)==0);	//等待上一次串口数据发送完成  USART2->DR=(u32)cmd;}else //发送命令{u2_printf("%s\r\n",cmd);//发送命令}if(ack&&waittime)	  //需要等待应答{while(--waittime)  //等待倒计时{delay_ms(10);if(USART2_RX_STA&0X8000)//接收到期待的应答结果{if(SIM_Check(ack))	//判断SIM模块应答是否正常{break;}USART2_RX_STA=0;} }if(waittime==0)res=SIM_Send_Cmd_ERROR; 		//超时}return res;
}void SIM_Init()						//SIM卡初始化
{	unsigned char flag=1;while(SIM_Send_Cmd("AT","OK",100))					//检测是否应答AT指令{		OLED_P8x16Str(0,1, "Sim Fail!"); delay_ms(400);OLED_P8x16Str(0,1, "         ");delay_ms(300);}OLED_P8x16Str(0,1, "            ");	OLED_P8x16Str(0,1, "AT is OK!"); 	SIM_Send_Cmd("ATE0","OK",100);//不回显delay_ms(200);while(SIM_Send_Cmd("AT+CPIN?","READY",100))	//检测是否存在SIM卡{	OLED_P8x16Str(0,1, "No Sim Card!"); delay_ms(400);OLED_P8x16Str(0,1, "            ");delay_ms(300);		}OLED_P8x16Str(0,1, "GPS Open..."); while(SIM_Send_Cmd("AT+CGNSPWR=1","OK",100))	//打开gps定位{OLED_P8x16Str(0,1, "GPS Open fail!"); delay_ms(400);OLED_P8x16Str(0,1, "              ");delay_ms(300);			}OLED_P8x16Str(0,1, "GPRS Init..."); while(flag)																		//设置GPRS通信{flag = 0;SIM_Send_Cmd("AT+CIPCLOSE=1","ERROR",100);		//关闭当前 TCP 连接SIM_Send_Cmd("AT+CIPSHUT","OK",100);				//关闭场景if(SIM_Send_Cmd("AT+CGCLASS=\"B\"","OK",1000))flag=1;							//设置GPRS移动台类别为B,支持包交换和数据交换 if(SIM_Send_Cmd("AT+CGDCONT=1,\"IP\",\"CMNET\"","OK",1000))flag=2;	//设置PDP上下文,互联网接协议,接入点等信息if(SIM_Send_Cmd("AT+CGATT=1","OK",500))flag=3;											//附着GPRS业务if(SIM_Send_Cmd("AT+CIPCSGP=1,\"CMNET\"","OK",500))flag=4;	 				//设置为GPRS连接模式if(SIM_Send_Cmd("AT+CIPHEAD=1","OK",500))flag=5;	 									//设置接收数据显示IP头(方便判断数据来源)	if(flag){OLED_P8x16Str(0,1, "GPRS ERROR!   "); delay_ms(800);OLED_P8x16Str(0,1, "              ");delay_ms(300);						}}while(SIM_Send_Cmd(IPaddr_port,"OK",500))			//发起GPRS连接{OLED_P8x16Str(0,1,"CONNECT FAIL!  "); delay_ms(400);OLED_P8x16Str(0,1, "              ");delay_ms(300);			}OLED_P8x16Str(0,1, "              ");		OLED_P8x16Str(0,1, "SIM is OK!"); }
//函数功能:
//1.不断读取定位信息,并且将有效的数据存储到GPRS_SEND数组中
//2.将读取到的有效定位数据掉点保存(未实现)
void SIM_ReadData()		//不断读取当前的定位信息
{//获取定位信息if(SIM_Send_Cmd("AT+CGNSINF","+CGNSINF: 1,1",100) == SIM_Send_Cmd_OK)			//定位数据有效则进行记录{ OLED_P6x8Str(0,5, "SNSS IS OK     "); 	SNSS_Save_Location();				//记录定位信息OLED_print(SNSS_Location);	//OLED显示定位信息Change_MessageLocation(SNSS_Location);	//修改发送的短信中的定位信息定位信息			}else{					OLED_P6x8Str(0,5, "GPS Location..."); }	}//函数功能:
//将数据发送到固定的端口中
void SIM_GprsSend()
{if(SIM_Send_Cmd("AT+CIPSEND",">",500)==0)		//发送数据{ //printf("CIPSEND DATA:%s\r\n",p1);	 			//发送数据打印到串口u2_printf("%s\r\n",GPRS_SEND);delay_ms(50);if(SIM_Send_Cmd((u8*)0X1A,"SEND OK",1000)==0){OLED_P6x8Str(0,3,"Data send is ok"); //最长等待10s}			else { OLED_P6x8Str(0,3,"Data send is error");}delay_ms(500); OLED_P8x16Str(0,3,"                  ");	}else{SIM_Send_Cmd((u8*)0X1B,0,0);	//ESC,取消发送 		}			}void SIM_SendMessage()    //发短信	OK
{OLED_P8x16Str(0,5, "                "); 			OLED_P8x16Str(0,5, "Send a Message.."); 	SIM_Send_Cmd("AT","OK",100);	SIM_Send_Cmd("AT+CMGF=1","OK",100);		//设置短信模式为文本模式SIM_Send_Cmd("AT+CSMP=17,167,1,8","OK",100);		//设置短信为中英文模式SIM_Send_Cmd("AT+CSCS=\"UCS2\"","OK",100);		//设置为UCS2字符集编码SIM_Send_Cmd("AT+CMGS=\"0031 0033 003x003x003x003x003x003x003x003x003x\"",">",500);		//设置对方手机号,需要修改SIM_Send_Cmd(Send_Message,">",1000);		//发送短信内容SIM_Send_Cmd((u8*)0X1A,"+CMGS:",1000);//发送结束符,等待发送完成(最长等待10秒钟,因为短信长了的话,等待时间会长一些)	OLED_P8x16Str(0,5, "Finish Send!    "); delay_ms(500);OLED_P8x16Str(0,5, "                "); 		
}void SIM_Call()						//打电话		OK
{unsigned char Key;unsigned char callbuf[] = "13xxxxxxxxx;";		//预存电话,需要修改OLED_P8x16Str(0,5, "               "); 			OLED_P8x16Str(0,5, "Call a phone..."); u2_printf("ATD%s\r\n",callbuf);		//拨号while(1){Key = KEY_Scan(0);if(Key == KEY2_PRES){u2_printf("ATH\r\n");	//挂电话	OLED_P8x16Str(0,5, "over the phone!"); delay_ms(500);OLED_P8x16Str(0,5, "               "); break;}}	
}			//根据模块的基站定位和SNSS定位修改发送的信息和GPRS发送的消息的经纬度
//参数: *p	
//LBS_Location表示使用的是基站定位
//SNSS_Location表示的是使用SNSS定位
void Change_MessageLocation(unsigned char p[])
{unsigned char i;for(i=12; i<32; i++)	//修改报警信息中的经纬度{if((i==15)||(i==22)||(i==25))	//小数点不修改{continue;}Send_Message[i*4-1] = p[i-12];}for(i=0; i<20; i++)	//修改GPRS发送的经纬度{GPRS_SEND[i+6] = p[i];}}void LBS_Save_Location()		//保存基站定位最近一次的位置信息, 基站定位是输出 精度,纬度
{unsigned char i,flag = 0;if((USART2_RX_BUF[2] == '+')&&(USART2_RX_BUF[9] == '0'))		//判断SIM模块是否读取到了地址{for(i=11; flag != 2; i++)		//SIM模块LBS定位返回来的信息,第11位开始为经纬度信息。注意sim868返回消息的格式{if(USART2_RX_BUF[i] == ','){flag++;}LBS_Location[i-11] = USART2_RX_BUF[i];	//记录经纬度}LBS_Location[i-12] = '\0';		//添加结束符}
}void OLED_print(unsigned char p[])		//基站定位和SNSS定位显示经纬度到OLED
{unsigned char i,Flag = 0;for(i=0;p[i] != '\0';i++){if(p[i] == ',')	//分开经度和纬度{p[i] = 0;	Flag = i;break;}			}if(Flag != 0){OLED_P6x8Str(0,6,p);OLED_P6x8Str(0,7,p+i+1);p[i] = ',';	}
}void SNSS_Save_Location()		//保存SNSS定位最近一次的位置信息,SNSS定位输出是 纬度,经度
{unsigned char i,flag = 0;for(i=35; flag != 2; i++)		//SIM模块SNSS定位返回来的信息,第35位开始为经纬度信息。注意sim868返回消息的格式{if(USART2_RX_BUF[i] == ','){flag++;}SNSS_Location[i-35] = USART2_RX_BUF[i];	//记录经纬度}SNSS_Location[i-36] = '\0';		//添加结束符}

示例工程下载:
https://download.csdn.net/download/Emb_2333/12549004


http://www.ppmy.cn/news/224319.html

相关文章

ISO7816 智能卡 接口

原文 1 了解ISO7816接口 一、主要从两个方面来了解 ISO7816触点的电气特性 ISO7816的通讯协议流程 二、电气特性 有三种类型的7816接口 A类7816&#xff1a;工作电压4.5~5.5V B类7816&#xff1a;工作电压2.7~3.3V C类7816&#xff1a;工作电压1.8V &#xff08;供电电压…

写好Java代码的30条经验总结

1、 类名首字母应该大写。字段、方法以及对象&#xff08;句柄&#xff09;的首字母应小写。对于所有标识符&#xff0c;其中包含的所有单词都应紧靠在一起&#xff0c;而且大写中间单词的首字母。例如&#xff1a; ThisIsAClassNamethisIsMethodOrFieldName 若在定义中出现了…

浅入浅出 iptables 网络隔离原理

01 iptables简介 iptables ipfirewall&#xff08;内核1.x时代&#xff09; ipchains&#xff08;内核2.x时代&#xff09; iptables 网络协议栈 Link Layer 数据链路层的数据流向&#xff0c;根据mac寻址找到对应的网卡后向上进入网络层 Network Layer 网络层的数据流向&am…

【Linux】LNMP框架的架构与环境配置

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 LNMP框架的架构与环境配置 一、安装 Nginx 服务1.关闭防火墙及安装依赖包2、创建运行用户3、编译安装4、优化路径5、添加 Nginx 系统服务 二、安装 MySQL 服务1、安装Mysql环…

【使用VS2010配合多平台工具集开发ARX14~2012CAD程序的注意事项】

在这里插入代码片使用VS2010配合多平台工具集开发ARX14~2012CAD程序的注意事项 对于计算机上已安装了VS6.0、 VS7.0、VS8.0、VS9.0的,只要在网站http://daffodil.codeplex.com/ 下载Daffodil for Visual Studio - Native Multitargeting Platform Toolsets.(多平台工具集)安…

安卓系统浏览器开发

预置某个浏览器为系统默认的浏览器 描述: 当系统存在多个浏览器时&#xff0c;如何预置某个浏览器为系统默认的浏览器&#xff1f; 方法: 1.在PackageManagerService.java中的构造函数结尾添加&#xff1a;setDefaultBrowser(); 2.setDefaultBrowser()的具体实现&#xff…

MacBook Pro长时间待机后没有声音问题

MAC电脑有时打开后没有声音&#xff0c;这是MAC OS系统的一个软件BUG&#xff0c;不是硬件问题&#xff0c;可以通过如下操作解决。 在启动台下搜索 活动监视器&#xff0c;在活动监视器窗口内右上角搜索框搜索audio&#xff0c;可以搜索到coreaudiod进程&#xff0c;选中此进程…

电脑长时间待机后自动关机

1、打开设备管理器&#xff08;右击开始菜单&#xff0c;选择设备管理器&#xff09;&#xff0c;然后打开系统设备下拉列表。 2.右击图示设备&#xff0c;选择属性 3.将图示的勾去掉&#xff0c;应用即可