功能
(1)通过LCD12864显示GPS模块的经纬度数据;
(2)可设定当前的定位位置,自动计算与设定位置的距离,当检测到位置超过设定位置200M时,通过GPRS模块发送报警信息;
(3)报警时通过通过蜂鸣器发出警报;
(4)根据位置自动计算定位的距离,当找到儿童时,成人可主动关闭警报器;
(5)可实现“一一键报警”功能,当按下按键时,主动发送当前的位置给设定的手机号;
(6)当找到儿童时,可手动取消报警。
系统框图

原理图

程序源代码
#include "project.h"
unsigned char ucMode = 0;
unsigned char xdata Longitude[13] = "E:"; //保存经度数据
unsigned char xdata Latitude[13] = "N:";//保存纬度数据
bit PosSuc = 0; //定位成功的标志,为1时表示定位成功,为0表示定位不成功
double fLongitude = 0.0; //保存浮点型数据,经度
double fLatitude = 0.0; //保存浮点型数据, 纬度
double fLongitudeLoa = 0.0; //当前所在地的经度
double fLatitudeLoa = 0.0; //当前所在地的纬度
double Dis = 0.0;
#define PI 3.1415926
#define EARTH_RADIUS 6378.004 //地球近似半径
// 求弧度
double radian(double d)
{
return d * PI / 180.0; //角度1? = π / 180
}
//计算距离
double get_distance(double lat1, double lng1, double lat2, double lng2)
{
xdata double radLat1 = radian(lat1);
xdata double radLat2 = radian(lat2);
xdata double a = radLat1 - radLat2;
xdata double b = radian(lng1) - radian(lng2);
xdata double dst = 2 * asin((sqrt(pow(sin(a / 2), 2) + cos(radLat1) * cos(radLat2) * pow(sin(b / 2), 2) )));
dst = dst * EARTH_RADIUS;
//dst= round(dst * 10000) / 10000;
return dst;
}
/*********************************************************************************************************
** 函数名称: ProcRxBuf
** 函数描述: 处理GPS接收的数据
** 输入参数: NONE
** 输出参数: NONE
** 返回值: NONE
*********************************************************************************************************/
void ProcRxBuf(void)
{
if(RxFlag == 1) //数据接收完毕
{
EA = 0;
RxFlag = 0;
if(RxBuf[17] == 'A')
{
ucMode = 1;
if(PosSuc == 0) //初次定位成功
{
fLongitudeLoa = fLongitude; //当前所在地的经度
fLatitudeLoa = fLatitude; //当前所在地的纬度
fLongitudeLoa = fLongitude; //当前所在地的经度
fLatitudeLoa = fLatitude; //当前所在地的纬度
PosSuc = 1;
}
LCD_Location(1,0);
LCD_Display(" GPS 定位成功 ");
PosSuc = 1; //定位成功标志置1
Latitude[0] = 'N';
Latitude[1] = ':';
fLatitude = (double)atof(&RxBuf[21]) / (double)60.0 + (RxBuf[19] - 0x30)*10 + (RxBuf[20]- 0x30);
Latitude[12] = 0;
Latitude[2] = (unsigned long)fLatitude %100 / 10 + 0x30;
Latitude[3] = (unsigned long)fLatitude % 10+ 0x30;
Latitude[4] = '.';
Latitude[5] = (unsigned long)(fLatitude * 10) % 10+ 0x30;
Latitude[6] = (unsigned long)(fLatitude * 100) % 10+ 0x30;
Latitude[7] = (unsigned long)(fLatitude * 1000) % 10+ 0x30;
Latitude[8] = (unsigned long)(fLatitude * 10000) % 10+ 0x30;
Latitude[9] = (unsigned long)(fLatitude * 100000) % 10+ 0x30;
Latitude[10] = (unsigned long)(fLatitude * 1000000) % 10+ 0x30;
Latitude[11] = (unsigned long)(fLatitude * 10000000) % 10+ 0x30;
Latitude[12] = 0;
Longitude[0] = 'E';
Longitude[1] = ':';
fLongitude = (double)atof(&RxBuf[34]) / (double)60.0 + (RxBuf[31] - 0x30)*100 + (RxBuf[32]- 0x30) * 10 + (RxBuf[33]- 0x30);
Longitude[2] = (unsigned long)fLongitude / 100 + 0x30;
Longitude[3] = (unsigned long)fLongitude %100 / 10 + 0x30;
Longitude[4] = (unsigned long)fLongitude % 10+ 0x30;
Longitude[5] = '.';
Longitude[6] = (unsigned long)(fLongitude * 10) % 10+ 0x30;
Longitude[7] = (unsigned long)(fLongitude * 100) % 10+ 0x30;
Longitude[8] = (unsigned long)(fLongitude * 1000) % 10+ 0x30;
Longitude[9] = (unsigned long)(fLongitude * 10000) % 10+ 0x30;
Longitude[10] = (unsigned long)(fLongitude * 100000) % 10+ 0x30;
Longitude[11] = (unsigned long)(fLongitude * 1000000) % 10+ 0x30;
Longitude[12] = 0;
}
else
{
PosSuc = 0; //定位成功标志清零
}
memset(RxBuf,0,80);
RxWP = 0;
EA = 1;
}
}
bit Key1Up = 1; //按键松开标志,为1时表示按键已经松开,为0时,表示按键未松开
sbit KEY1 = P3^4; //按键,按下按键时发送定位信息到手机
sbit KEY2 = P3^5; //按键,按下按键时存储正确的定位信息
/*********************************************************************************************************
** 函数名称: SendHelp
** 函数描述: 发送求救信息
** 输入参数: NONE
** 输出参数: NONE
** 返回值: NONE
*********************************************************************************************************/
void SendHelp(double Dis)
{
unsigned char i = 0;
xdata unsigned char ucTemp[45] = {0};
for(i = 0; i < 13;i++)
{
ucTemp[i] = Latitude[i];
}
for(i = 0; i < 13; i++)
{
ucTemp[i+12] = Longitude[i];
}
strcat(ucTemp,"distance=");
ucTemp[33] = ((unsigned long)Dis % 100 / 10 + 0x30);
ucTemp[34] = ((unsigned long)Dis %10 + 0x30);
ucTemp[35] = ('.');
ucTemp[36] = ((unsigned long)(Dis * 10) % 10 + 0x30);
ucTemp[37] = ((unsigned long)(Dis * 100) % 10 + 0x30);
ucTemp[38] = ((unsigned long)(Dis * 1000) % 10 + 0x30);
ucTemp[39] = 'k';
ucTemp[40] = 'm';
SendSMS(ucTemp,41); //发送手机短信
DelayMs(1000);
UART1_ClearRxBuf();
}
/*********************************************************************************************************
** 函数名称: ProcKey
** 函数描述: 处理按键函数,按键按下时发送定位信息到手机
** 输入参数: NONE
** 输出参数: NONE
** 返回值: NONE
*********************************************************************************************************/
void ProcKey1(void)
{
if( (Key1Up == 1) && (KEY1 == 0)) //按键处于松开状态时,按键按下,定位完成才判断按键
{
DelayMs(20); //防抖动延时
if(KEY1 == 0)
{
Key1Up = 0;
if(PosSuc == 1)
{
SendHelp(Dis);
}
else if(PosSuc == 0)
{
LCD_Location(3,0);
LCD_Display("请等定位成功 ");
DelayMs(2000);
LCD_Location(3,0);
LCD_Display(" ");
}
}
}
else if(KEY1 == 1)
{
Key1Up = 1;
}
}
全部0条评论
快来发表一下你的评论吧 !