#include "mc20.h"
/*
函数功能:向MC20模块发送指令
函数参数:
char *cmd 发送的命令
char *check_data 检测返回的数据
返回值: 0表示成功 1表示失败
*/
u8 MC20_SendCmd(char *cmd,char *check_data)
{
u16 i,j;
for(i=0;i<5;i++) //测试的总次数
{
USART2_RX_FLAG=0;
USART2_RX_CNT=0;
memset(USART2_RX_BUFF,0,sizeof(USART2_RX_BUFF));
USART_X_SendString(USART2,cmd); //发送指令
for(j=0;j<500;j++) //等待的时间(ms单位)
{
if(USART2_RX_FLAG)
{
USART2_RX_BUFF[USART2_RX_CNT]='\0';
if(strstr((char*)USART2_RX_BUFF,check_data))
{
return 0;
}
else break;
}
delay_ms(10); //一次的时间
}
}
return 1;
}
/*
函数功能: MC20初始化检查
*/
u8 MC20_InitCheck(void)
{
return MC20_SendCmd("AT\r\n","OK\r\n");
}
/*
函数功能: 开启GPS功能
返 回 值:0表示成功 1表示失败
*/
u8 MC20_StartGPS(void)
{
//先判断GPS功能是否启动
if(MC20_SendCmd("AT+QGNSSC?\r\n","+QGNSSC: 1"))
{
//没有启动就启动GPS功能
if(MC20_SendCmd("AT+QGNSSC=1\r\n","OK\r\n"))
{
return 1; //GPS功能启动失败
}
}
return 0;
}
/*
函数功能:从buf里面得到第cnt个逗号所在的位置
返 回 值:0~254,代表逗号所在位置的偏移.
255,代表不存在第cnt个逗号
*/
u8 GPS_GetCommaOffset(char *buf,u8 cnt)
{
char *p=buf;
while(cnt)
{
if(*buf=='*'||*buf<' '||*buf>'z')return 255;//遇到'*'或者非法字符,则不存在第cx个逗号
if(*buf==',')cnt--;
buf++;
}
return buf-p; //计算偏移量
}
/*
函数功能: 获取GPS经纬度数据值
函数参数:
double *Longitude :经度
double *latitude :纬度
返回值: 0表示定位成功,1表示定位失败
说明: 解析$GNRMC命令,得到经纬度
$GNRMC,023705.000,A,2842.4164,N,11549.5713,E,1.73,91.65,150319,,,A*41
转换公式示例:
经度: dddmm.mmmm 东经 11408.4790 114+(08.4790/60)=114.141317
纬度: ddmm.mmmm 北纬 2236.9453 22+(36.9453/60)= 22.615755
*/
u8 GPS_GNRMC_Decoding(char *gps_buffer,double *Longitude,double *latitude)
{
u8 Offset;
u32 int_data;
double s_Longitude,s_latitude;
char *p;
/*1. 确定下定位是否成功*/
p=strstr(gps_buffer,"$GNRMC");
if(!p)return 1;
Offset=GPS_GetCommaOffset(p,2);
if(Offset==255)return 2;
if(*(p+Offset)!='A')return 3; //定位不准确
/*2. 得到纬度*/
Offset=GPS_GetCommaOffset(p,3);
if(Offset==255)return 4;
sscanf(p+Offset,"%lf",&s_latitude);
s_latitude=s_latitude/100;
int_data=s_latitude;//得到纬度整数部分
s_latitude=s_latitude-int_data;//得到纬度小数部分
s_latitude=(s_latitude)*100;
*latitude=int_data+(s_latitude/60.0); //得到转换后的值
/*3. 得到经度*/
Offset=GPS_GetCommaOffset(p,5);
if(Offset==255)return 5;
sscanf(p+Offset,"%lf",&s_Longitude);
s_Longitude=s_Longitude/100;
int_data=s_Longitude;//得到经度整数部分
s_Longitude=s_Longitude-int_data; //得到经度小数部分
s_Longitude=s_Longitude*100;
*Longitude=int_data+(s_Longitude/60.0);
return 0;
}
/*
函数功能: 获取一次GPS经纬度数据
函数参数:
double *Longitude :经度
double *latitude :纬度
返回值: 0表示定位成功,1表示数据接收失败,2表示定位失败
*/
u8 MC20_GetGPS_Data(double *Longitude,double *latitude)
{
/*1. 发送获取GPS数据的指令*/
if(MC20_SendCmd("AT+QGNSSRD=\"NMEA/RMC\"\r\n", "OK\r\n"))return 1;
/*2. 对GPS数据进行解码*/
if(GPS_GNRMC_Decoding((char *)USART2_RX_BUFF,Longitude,latitude))return 2;
//解码成功
return 0;
}
/*
函数功能: 连接服务器
函数参数:
char *server_ip 服务器IP地址
u16 port 服务器端口号
返回值: 0表示连接成功,1表示连接失败
*/
u8 MC20_Connect_TCP_Server(char *server_ip,u16 port)
{
char send_buf[100]={0};
sprintf(send_buf,"AT+QIOPEN=\"TCP\",\"%s\",\"%d\"\r\n",server_ip,port);
//连接至服务器
if(MC20_SendCmd(send_buf, "CONNECT"))
{
return 1; //连接失败
}
return 0; //连接成功
}
/*
函数功能: 向服务器发送数据
函数参数:
u8 *buffer 发送的数据
u32 len 发送的长度
返 回 值: 0表示发送成功,1表示准备发送失败,2表示数据发送失败
*/
u8 MC20_ClientSendData(u8 *buffer,u32 len)
{
char send_buf[2];
/*1. 准备发送数据*/
if(MC20_SendCmd("AT+QISEND\r\n",">"))
{
printf("AT+QISEND->ERROR Info:%s\r\n",USART2_RX_BUFF);
return 1;
}
/*2. 开始发送数据*/
USART_X_SendData(USART2,buffer,len);
delay_ms(20);
/*3. 发送结束符*/
send_buf[0] = 0x1a;
send_buf[1] = '\0';
if(MC20_SendCmd(send_buf,"OK\r\n"))
{
printf("发送结束符->ERROR Info:%s\r\n",USART2_RX_BUFF);
return 2;
}
return 0;
}
/*
函数功能: MC20初始化检查并连接至服务器
*/
#include "led.h"
void MC20_InitConnect(char *server_ip,u16 port)
{
/*1. MC20模块初始化检查*/
while(MC20_InitCheck())
{
LED1=!LED1;
printf("ERROR:MC20模块初始化检查失败!\r\n");
delay_ms(100);
}
printf("1. MC20模块初始化成功!\r\n");
delay_ms(100);
/*2. 查询是否有PIN码锁定*/
while(MC20_SendCmd("AT+CPIN?\r\n","READY"))
{
LED1=!LED1;
printf("ERROR:PIN码锁定检查失败!\r\n");
delay_ms(100);
}
printf("2. PIN码锁定检查成功!\r\n");
delay_ms(100);
/*3. 查询SIM卡网络注册信息*/
if(MC20_SendCmd("AT+CREG?\r\n",",1")) //本地SIM卡
{
if(MC20_SendCmd("AT+CREG?\r\n",",5"))//漫游SIM卡
{
printf("ERROR:查询SIM卡网络注册信息失败!\n");
}
else printf("3. 漫游SIM卡网络注册成功!\n");
}
else printf("3. 本地SIM卡网络注册成功!\n");
delay_ms(100);
/*4. 启动GPS功能*/
if(MC20_StartGPS())
{
printf("ERROR:GPS功能启动失败!\n");
}
else printf("4. GPS功能启动成功!\n");
delay_ms(100);
/*5. 连接指定服务器*/
while(MC20_Connect_TCP_Server(server_ip,port))
{
printf("ERROR: 连接TCP服务器失败!\r\n现在正在断开服务器,进行重连!\r\n需要保证服务器地址正确,并且SIM卡可以上网\r\n");
/*先断开服务器连接 (如果之前没有连接过服务器,这里就会出现错误)*/
MC20_SendCmd("AT+QICLOSE\r\n","OK\r\n");
delay_ms(100);
MC20_SendCmd("AT+QIDEACT\r\n","OK\r\n");
delay_ms(100);
}
printf("5. 连接TCP服务器成功!\n");
delay_ms(100);
}
评论