0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux应用开发-GPS电子围栏设计

DS小龙哥-嵌入式技术 来源:DS小龙哥-嵌入式技术 作者:DS小龙哥-嵌入式技 2022-08-14 09:16 次阅读

1. 前言

GPS电子围栏这个功能是地图的一个扩展技术功能,通过地图经纬度在地图上圈一个范围,在这个范围内进出可以在服务器上进行实时记录,提示警报。现在的共享单车、共享汽车都有这个功能,限制车辆只能在某一个范围内使用,超出后就自动断电或者作出提示。要实现这个地理围栏,就需要实时获取当前的经纬度,然后调用地图SDK接口进行处理,完成围栏逻辑设计。

这种地理围栏应用的场景非常多,比如:

(1)上面说的共享单车,超出区域断电;

(2)小孩子的儿童手表、可以设置地理围栏,家长可以给孩子设置一个地图范围,如果孩子离开了这个范围,父母的就可以收到通知,方便知道孩子当前位置在哪里,防止走丢;

(3)4S店的车子也会设置电子围栏,当试驾、试乘离开规定的范围会通知4S店。

在完成GPS围栏功能之后,通过得到的GPS数据还可以做很多相关的事情,比如:导航路线规划,行走的路线记录、实时定位等。

这篇文章就采用Linux开发板来实现这个GPS围栏功能,这个项目分为了两个部分:1. 服务器部分 2. 设备部分

设备端就是实时采集GPS模块得到的经纬度,通过网络上传给服务器,服务器调用百度地图、高德地图的API接口,根据规划的地理围栏范围进行判断,在地图上绘制当前设备所在的位置,还可以画出轨迹线。

image-20220123234737281image-20220123234826634image-20220123235613952

2. 项目实现代码

当前文章讲的就是设备端的实现,如何读取GPS坐标、转换、上传到服务器的流程。

GPS模块是串口接口,Linux开发板有串口接口,如果串口接口不够用,也可以把模块接到CH340这种USB转TTL模块上,再插在开发板的USB口上,在/dev下会生成ttyUSBx节点。Linux下串口编程有一套标准的接口,编程非常方便。

读取串口数据可以采用 poll、select、epoll机制等。也可以使用异步通知机制:fasync。串口配置的时候可以配置每次读取的超时时间,方便知道什么时候一包数据接收完毕了。

GPS模块也支持配置,正常情况下GPS模块会将接收的卫星所有数据返回来,如果想要提高效率,可以设置GPS模块,让它只是返回想要的字段,这样接收数据解析数据效率就高很多。

2.1 GPS坐标数据读取

下面这份代码是接收GPS经纬度的串口代码。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include      
#include 


/*
标准串口属性:
波特率	  : 115200
停止位    : 1个
奇偶校验位: 没有校验位
数据位    : 8位
*/
int uart_fd;//存放串口的文件描述符

int main(int argc,char *argv[])
{
	if(argc!=2)
	{
		printf("参数格式: ./app /dev/ttySACx 或者 /dev/ttyUSBx\n");
		exit(-1);
	}
	
	/*1. 打开串口*/
	uart_fd=open(argv[1],O_RDWR|O_NOCTTY); 
    if(uart_fd<0)
	{
		printf("%s 串口设备打开失败!\n",argv[1]);
		exit(-1);
	}
	/*2. 清空终端未完成的输入/输出请求及数据、刷新缓存*/
	tcflush(uart_fd,TCIFLUSH); 		   
	
	/*3. 填充保存串口属性结构体*/
	struct termios newtio; 
	memset(&newtio,0,sizeof(newtio));   //初始化结构体空间为0
	cfsetispeed(&newtio, B115200);  	//配置串口的输入波特率为115200
    cfsetospeed(&newtio, B115200);  	//配置串口的输出波特率为115200
	newtio.c_cflag  |=  CREAD; 			//启用串口的接收功能
    newtio.c_cflag  &= ~CSIZE;  		//清除串口的数据位
    newtio.c_cflag  |=  CS8;    		//配置串口的数据位为8位
    newtio.c_cflag  &= ~PARENB; 		//配置串口的校验位:无校验
    newtio.c_cflag  &=  ~CSTOPB;     	//配置的停止位:1个
	//newtio.c_lflag &= ~(ICANON);  	    //不使用规范模式(非标准模式)
	newtio.c_cc[VTIME]=100;
	newtio.c_cc[VMIN]=10;
	//newtio.c_iflag &= ~ IGNCR;  //不忽略回车字符
	//newtio.c_iflag &= ICRNL;//不转换
	/*4. 配置串口的属性*/
    tcsetattr(uart_fd,TCSANOW,&newtio);
	
	int i,cnt=0;
	char usart_rx_buff[1024];
    while(1) 
    {
		cnt=read(uart_fd,(void*)usart_rx_buff,1024); //从串口RX端口读取数据
		if(cnt>0)
		{
			for(i=0;i;i++)>

2.2 GPS数据格式与字段含义

$GNGGA,114955.000,2842.4158,N,11549.5439,E,1,05,3.8,54.8,M,0.0,M,,*4F
$GNGLL,2842.4158,N,11549.5439,E,114955.000,A,A*4D
$GPGSA,A,3,10,31,18,,,,,,,,,,5.7,3.8,4.2*37
$BDGSA,A,3,07,10,,,,,,,,,,,5.7,3.8,4.2*2A
$GPGSV,3,1,10,10,49,184,42,12,16,039,,14,54,341,,18,22,165,23*7B
$GPGSV,3,2,10,22,11,318,,25,51,055,,26,24,205,,29,13,110,*7C
$GPGSV,3,3,10,31,50,287,36,32,66,018,*7F
$BDGSV,1,1,04,03,,,07,05,,,29,07,79,246,33,10,52,232,19*62
$GNRMC,114955.000,A,2842.4158,N,11549.5439,E,0.00,44.25,061117,,,A*4D
$GNVTG,44.25,T,,M,0.00,N,0.00,K,A*14
$GNZDA,114955.000,06,11,2017,00,00*47
$GPTXT,01,01,01,ANTENNA OK*35


序号 命令 说明 最大帧长
1 $GNGGA GPS/北斗定位信息 72
2 $GNGSA 当前卫星信息 65
3 $GPGSV 可见 GPS 卫星信息 210
4 $BDGSV 可见北斗卫星信息 210
5 $GNRMC 推荐定位信息 70
6 $GNVTG 地面速度信息 34
7 $GNGLL 大地坐标信息 --
8 $GNZDA 当前时间(UTC1)信息 --


1, $GNGGA (GPS 定位信息, Global Positioning System Fix Data)
$GNGGA 语句的基本格式如下(其中 M 指单位 M, hh 指校验和, CR 和 LF 代表回车
换行,下同):
$GNGGA,(1),(2),(3),(4),(5),(6),(7),(8),(9),M,(10),M,(11),(12)*hh(CR)(LF)
(1) UTC 时间,格式为 hhmmss.ss;
(2) 纬度,格式为 ddmm.mmmmm(度分格式);
(3) 纬度半球, N 或 S(北纬或南纬);
(4) 经度,格式为 dddmm.mmmmm(度分格式);
(5) 经度半球, E 或 W(东经或西经);
(6) GPS 状态, 0=未定位, 1=非差分定位, 2=差分定位;
(7) 正在使用的用于定位的卫星数量(00~12)
(8) HDOP 水平精确度因子(0.5~99.9)
(9) 海拔高度(-9999.9 到 9999.9 米)
(10) 大地水准面高度(-9999.9 到 9999.9 米)
(11) 差分时间(从最近一次接收到差分信号开始的秒数,非差分定位,此项为空)
(12) 差分参考基站标号(0000 到 1023, 首位 0 也将传送,非差分定位,此项为空)
举例如下:
$GNGGA,095528.000,2318.1133,N,11319.7210,E,1,06,3.7,55.1,M,-5.4,M,,0000*69


2, $GNGSA(当前卫星信息)
$GNGSA 语句的基本格式如下:
$GNGSA,(1),(2),(3),(3),(3),(3),(3),(3),(3),(3),(3),(3),(3),(3),(4),(5),(6)*hh(CR)(LF)
(1) 模式, M = 手动, A = 自动。
(2) 定位类型, 1=未定位, 2=2D 定位, 3=3D 定位。
(3) 正在用于定位的卫星号(01~32)
(4) PDOP 综合位置精度因子(0.5-99.9)ALIENTEK
(5) HDOP 水平精度因子 1(0.5-99.9)
(6) VDOP 垂直精度因子(0.5-99.9)
举例如下:
$GNGSA,A,3,14,22,24,12,,,,,,,,,4.2,3.7,2.1*2D
$GNGSA,A,3,209,214,,,,,,,,,,,4.2,3.7,2.1*21
注 1: 精度因子值越小,则准确度越高。


3, $GPGSV(可见卫星数, GPS Satellites in View)
$GPGSV 语句的基本格式如下:
$GPGSV, (1),(2),(3),(4),(5),(6),(7),...,(4),(5),(6),(7)*hh(CR)(LF)
(1) GSV 语句总数。
(2) 本句 GSV 的编号。
(3) 可见卫星的总数(00~12,前面的 0 也将被传输)。
(4) 卫星编号(01~32,前面的 0 也将被传输)。
(5) 卫星仰角(00~90 度,前面的 0 也将被传输)。
(6) 卫星方位角(000~359 度,前面的 0 也将被传输)
(7) 信噪比(00~99dB,没有跟踪到卫星时为空)。
注:每条 GSV 语句最多包括四颗卫星的信息,其他卫星的信息将在下一条$GPGSV 语句中输出。
举例如下:
$GPGSV,3,1,11,18,73,129,19,10,71,335,40,22,63,323,41,25,49,127,06*78
$GPGSV,3,2,11,14,41,325,46,12,36,072,34,31,32,238,22,21,23,194,08*76
$GPGSV,3,3,11,24,21,039,40,20,08,139,07,15,08,086,03*45


4, $BDGSV(可见卫星数, GPS Satellites in View)
$BDGSV 语句的基本格式如下:
$BDGSV, (1),(2),(3),(4),(5),(6),(7),...,(4),(5),(6),(7)*hh(CR)(LF)
(1) GSV 语句总数。
(2) 本句 GSV 的编号。
(3) 可见卫星的总数(00~12,前面的 0 也将被传输)。
(4) 卫星编号(01~32,前面的 0 也将被传输)。
(5) 卫星仰角(00~90 度,前面的 0 也将被传输)。
(6) 卫星方位角(000~359 度,前面的 0 也将被传输)
(7) 信噪比(00~99dB,没有跟踪到卫星时为空)。
注:每条 GSV 语句最多包括四颗卫星的信息,其他卫星的信息将在下一条$BDGSV 语句中输出。
举例如下:
$BDGSV,1,1,02,209,64,354,40,214,05,318,40*69


5, $GNRMC(推荐定位信息, Recommended Minimum Specific GPS/Transit Data)
$GNRMC 语句的基本格式如下:
$GNRMC,(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)*hh(CR)(LF)
(1) UTC 时间, hhmmss(时分秒)
(2) 定位状态, A=有效定位, V=无效定位
(3) 纬度 ddmm.mmmmm(度分)
(4) 纬度半球 N(北半球)或 S(南半球)ALIENTEK
(5) 经度 dddmm.mmmmm(度分)
(6) 经度半球 E(东经)或 W(西经)
(7) 地面速率(000.0~999.9 节)
(8) 地面航向(000.0~359.9 度,以真北方为参考基准)
(9) UTC 日期, ddmmyy(日月年)
(10) 磁偏角(000.0~180.0 度,前导位数不足则补 0)
(11) 磁偏角方向, E(东)或 W(西)
(12) 模式指示(A=自主定位, D=差分, E=估算, N=数据无效)
举例如下:
$GNRMC,095554.000,A,2318.1327,N,11319.7252,E,000.0,005.7,081215,,,A*73


6, $GNVTG(地面速度信息, Track Made Good and Ground Speed)
$GNVTG 语句的基本格式如下:
$GNVTG,(1),T,(2),M,(3),N,(4),K,(5)*hh(CR)(LF)
(1) 以真北为参考基准的地面航向(000~359 度,前面的 0 也将被传输)
(2) 以磁北为参考基准的地面航向(000~359 度,前面的 0 也将被传输)
(3) 地面速率(000.0~999.9 节,前面的 0 也将被传输)
(4) 地面速率(0000.0~1851.8 公里/小时,前面的 0 也将被传输)
(5) 模式指示(A=自主定位, D=差分, E=估算, N=数据无效)
举例如下:
$GNVTG,005.7,T,,M,000.0,N,000.0,K,A*11


7, $GNGLL(定位地理信息, Geographic Position)
$GNGLL 语句的基本格式如下:
$GNGLL,(1),(2),(3),(4),(5),(6),(7)*hh(CR)(LF)
(1) 纬度 ddmm.mmmmm(度分)
(2) 纬度半球 N(北半球)或 S(南半球)
(3) 经度 dddmm.mmmmm(度分)
(4) 经度半球 E(东经)或 W(西经)
(5) UTC 时间: hhmmss(时分秒)
(6) 定位状态, A=有效定位, V=无效定位
(7) 模式指示(A=自主定位, D=差分, E=估算, N=数据无效)
举例如下:
$GNGLL,2318.1330,N,11319.7250,E,095556.000,A,A*4F


7, $GNZDA(当前时间信息)
$GNZDA 语句的基本格式如下:
$GNZDA,(1),(2),(3),(4), (5), (6)*hh(CR)(LF)
(1) UTC 时间: hhmmss(时分秒)
(2) 日
(3) 月
(4) 年
(5) 本地区域小时(NEO-6M 未用到,为 00)
(6) 本地区域分钟(NEO-6M 未用到,为 00)
举例如下:
$GNZDA,095555.000,08,12,2015,00,00*4C
复制代码

2.3 GPS数据解析

/*
函数功能:从buf里面得到第cnt个逗号所在的位置
返 回 值:0~254,代表逗号所在位置的偏移.
255,代表不存在第cnt个逗号
*/
u8 GPS_GetCommaOffset(u8 *buf,u8 cnt)
{
	u8 *p=buf;
	while(cnt)
	{
		if(*buf=='*'||*buf<' '||*buf>'z')return 255;//遇到'*'或者非法字符,则不存在第cx个逗号
		if(*buf==',')cnt--;
		buf++;
	}
	return buf-p; //计算偏移量
}


/*
函数功能:m^n函数
返 回 值:m^n次方.
*/
u32 GPS_GetPow(u8 m,u8 n)
{
	u32 tmp=1;
	while(n--)tmp*=m;
	return tmp;
}


/*
函数功能:str转换为数字,以','或者'*'结束
函数参数:buf:数字存储区
		 dx:小数点位数,返回给调用函数
返 回 值:转换后的整数数值
*/
int GPS_StrtoNum(u8 *buf,u8*dx)
{
	u8 *p=buf;
	u32 ires=0,fres=0;
	u8 ilen=0,flen=0,i;
	u8 mask=0;
	int res;
	while(1) //得到整数和小数的长度
	{
		if(*p=='-'){ mask|=0X02; p++; }//是负数
		if(*p==','||(*p=='*'))break;//遇到结束了
		if(*p=='.'){ mask|=0X01; p++; }//遇到小数点了
		else if(*p>'9'||(*p<'0'))	//有非法字符
		{
			ilen=0;
			flen=0;
			break;
		}
		if(mask&0X01)flen++;
		else ilen++;
		p++;
	}
	if(mask&0X02)buf++;	//去掉负号
	for(i=0; i5)flen=5;	//最多取5位小数
	*dx=flen;	 		//小数点位数
	for(i=0; isvnum=GPS_StrtoNum(p1+posx,&dx);
	for(i=0; islmsg[slx].num=GPS_StrtoNum(p1+posx,&dx);	//得到卫星编号
			else break;
			posx=GPS_GetCommaOffset(p1,5+j*4);
			if(posx!=0XFF)GPS_DecodingInfo->slmsg[slx].eledeg=GPS_StrtoNum(p1+posx,&dx);//得到卫星仰角 
			else break;
			posx=GPS_GetCommaOffset(p1,6+j*4);
			if(posx!=0XFF)GPS_DecodingInfo->slmsg[slx].azideg=GPS_StrtoNum(p1+posx,&dx);//得到卫星方位角
			else break;
			posx=GPS_GetCommaOffset(p1,7+j*4);
			if(posx!=0XFF)GPS_DecodingInfo->slmsg[slx].sn=GPS_StrtoNum(p1+posx,&dx);	//得到卫星信噪比
			else break;
			slx++;
		}
		p=p1+1;//切换到下一个GPGSV信息
	}
}


/*
函数功能:分析BDGSV信息
函数参数:GPS_DecodingInfo:nmea信息结构体
		  buf:接收到的GPS数据缓冲区首地址
*/
void GPS_BDGSV_InfoGet(GPS_Msg *GPS_DecodingInfo,u8 *buf)
{
	u8 *p,*p1,dx;
	u8 len,i,j,slx=0;
	u8 posx;
	p=buf;
	p1=(u8*)strstr((const char *)p,"$BDGSV");
	if(!p1)return; //没有查找成功
	len=p1[7]-'0';								//得到BDGSV的条数
	posx=GPS_GetCommaOffset(p1,3); 					//得到可见北斗卫星总数
	if(posx!=0XFF)GPS_DecodingInfo->beidou_svnum=GPS_StrtoNum(p1+posx,&dx);
	for(i=0; ibeidou_slmsg[slx].beidou_num=GPS_StrtoNum(p1+posx,&dx);	//得到卫星编号
			else break;
			posx=GPS_GetCommaOffset(p1,5+j*4);
			if(posx!=0XFF)GPS_DecodingInfo->beidou_slmsg[slx].beidou_eledeg=GPS_StrtoNum(p1+posx,&dx);//得到卫星仰角 
			else break;
			posx=GPS_GetCommaOffset(p1,6+j*4);
			if(posx!=0XFF)GPS_DecodingInfo->beidou_slmsg[slx].beidou_azideg=GPS_StrtoNum(p1+posx,&dx);//得到卫星方位角
			else break;
			posx=GPS_GetCommaOffset(p1,7+j*4);
			if(posx!=0XFF)GPS_DecodingInfo->beidou_slmsg[slx].beidou_sn=GPS_StrtoNum(p1+posx,&dx);	//得到卫星信噪比
			else break;
			slx++;
		}
		p=p1+1;//切换到下一个BDGSV信息
	}
}


/*
函数功能:分析GNGGA信息
函数参数:
		GPS_DecodingInfo:nmea信息结构体
		buf:接收到的GPS数据缓冲区首地址
*/
void GPS_GNGGA_InfoGet(GPS_Msg *GPS_DecodingInfo,u8 *buf)
{
	u8 *p1,dx;
	u8 posx;
	p1=(u8*)strstr((const char *)buf,"$GNGGA");
	if(!p1)return; //没有查找成功
	posx=GPS_GetCommaOffset(p1,6);								//得到GPS状态
	if(posx!=0XFF)GPS_DecodingInfo->gpssta=GPS_StrtoNum(p1+posx,&dx);
	posx=GPS_GetCommaOffset(p1,7);								//得到用于定位的卫星数
	if(posx!=0XFF)GPS_DecodingInfo->posslnum=GPS_StrtoNum(p1+posx,&dx);
	posx=GPS_GetCommaOffset(p1,9);								//得到海拔高度
	if(posx!=0XFF)GPS_DecodingInfo->altitude=GPS_StrtoNum(p1+posx,&dx);
}


/*
函数功能:分析GPGSA信息
参    数:GPS_DecodingInfo:nmea信息结构体
		  buf:接收到的GPS数据缓冲区首地址
*/
void GPS_GPGSA_InfoGet(GPS_Msg *GPS_DecodingInfo,u8 *buf)
{
	u8 *p1,dx;
	u8 posx;
	u8 i;
	p1=(u8*)strstr((const char *)buf,"$GPGSA");
	if(!p1)return; //没有查找成功
	posx=GPS_GetCommaOffset(p1,2);								//得到定位类型
	if(posx!=0XFF)GPS_DecodingInfo->fixmode=GPS_StrtoNum(p1+posx,&dx);
	for(i=0; i<12; i++)										//得到定位卫星编号
	{
		posx=GPS_GetCommaOffset(p1,3+i);
		if(posx!=0XFF)GPS_DecodingInfo->possl[i]=GPS_StrtoNum(p1+posx,&dx);
		else break;
	}
	posx=GPS_GetCommaOffset(p1,15);								//得到PDOP位置精度因子
	if(posx!=0XFF)GPS_DecodingInfo->pdop=GPS_StrtoNum(p1+posx,&dx);
	posx=GPS_GetCommaOffset(p1,16);								//得到HDOP位置精度因子
	if(posx!=0XFF)GPS_DecodingInfo->hdop=GPS_StrtoNum(p1+posx,&dx);
	posx=GPS_GetCommaOffset(p1,17);								//得到VDOP位置精度因子
	if(posx!=0XFF)GPS_DecodingInfo->vdop=GPS_StrtoNum(p1+posx,&dx);
}


/*
函数功能:分析GNRMC信息
函数参数:GPS_DecodingInfo:nmea信息结构体
		 buf:接收到的GPS数据缓冲区首地址
*/
void GPS_GNRMC_InfoGet(GPS_Msg *GPS_DecodingInfo,u8 *buf)
{
	u8 *p1,dx;
	u8 posx;
	u32 temp;
	float rs;
	p1=(u8*)strstr((const char *)buf,"$GNRMC");//"$GNRMC",经常有&和GNRMC分开的情况,判断GPRMC.
	if(!p1)return; //没有查找成功
	posx=GPS_GetCommaOffset(p1,1);								//得到UTC时间
	if(posx!=0XFF)
	{
		temp=GPS_StrtoNum(p1+posx,&dx)/GPS_GetPow(10,dx);	 	//得到UTC时间,去掉ms
		GPS_DecodingInfo->utc.hour=temp/10000;
		GPS_DecodingInfo->utc.min=(temp/100)%100;
		GPS_DecodingInfo->utc.sec=temp%100;
	}
	posx=GPS_GetCommaOffset(p1,3);								//得到纬度
	if(posx!=0XFF)
	{
		temp=GPS_StrtoNum(p1+posx,&dx);
		GPS_DecodingInfo->latitude=temp/GPS_GetPow(10,dx+2);	//得到°
		rs=(float)(temp%GPS_GetPow(10,dx+2));				//得到'		 
		GPS_DecodingInfo->latitude=(u32)(GPS_DecodingInfo->latitude*GPS_GetPow(10,5)+(rs*GPS_GetPow(10,5-dx))/60);//转换为° 
	}
	posx=GPS_GetCommaOffset(p1,4);								//南纬还是北纬 
	if(posx!=0XFF)GPS_DecodingInfo->nshemi=*(p1+posx);
	posx=GPS_GetCommaOffset(p1,5);								//得到经度
	if(posx!=0XFF)
	{
		temp=GPS_StrtoNum(p1+posx,&dx);
		GPS_DecodingInfo->longitude=temp/GPS_GetPow(10,dx+2);	//得到°
		rs=(float)(temp%GPS_GetPow(10,dx+2));				//得到'		 
		GPS_DecodingInfo->longitude=(u32)(GPS_DecodingInfo->longitude*GPS_GetPow(10,5)+(rs*GPS_GetPow(10,5-dx))/60);//转换为° 
	}
	posx=GPS_GetCommaOffset(p1,6);								//东经还是西经
	if(posx!=0XFF)GPS_DecodingInfo->ewhemi=*(p1+posx);
	posx=GPS_GetCommaOffset(p1,9);								//得到UTC日期
	if(posx!=0XFF)
	{
		temp=GPS_StrtoNum(p1+posx,&dx);		 				//得到UTC日期
		GPS_DecodingInfo->utc.date=temp/10000;
		GPS_DecodingInfo->utc.month=(temp/100)%100;
		GPS_DecodingInfo->utc.year=2000+temp%100;
	}
}


/*
函数功能:分析GNVTG信息
函数参数:GPS_DecodingInfo:nmea信息结构体
		  buf:接收到的GPS数据缓冲区首地址
*/
void GPS_GNVTG_InfoGet(GPS_Msg *GPS_DecodingInfo,u8 *buf)
{
	u8 *p1,dx;
	u8 posx;
	p1=(u8*)strstr((const char *)buf,"$GNVTG");
	if(!p1)return; //没有查找成功
	posx=GPS_GetCommaOffset(p1,7);								//得到地面速率
	if(posx!=0XFF)
	{
		GPS_DecodingInfo->speed=GPS_StrtoNum(p1+posx,&dx);
		if(dx<3)GPS_DecodingInfo->speed*=GPS_GetPow(10,3-dx);	 	 		//确保扩大1000倍
	}
}

/*
函数功能:提取GPS信息
函数参数:GPS_DecodingInfo:nmea信息结构体
		  buf:接收到的GPS数据缓冲区首地址
*/
void GPS_InfoGet(GPS_Msg *GPS_DecodingInfo,u8 *buf)
{
	GPS_GPGSV_InfoGet(GPS_DecodingInfo,buf);	//GPGSV解析-OK
	GPS_BDGSV_InfoGet(GPS_DecodingInfo,buf);	//BDGSV解析-OK
	GPS_GNGGA_InfoGet(GPS_DecodingInfo,buf);	//GNGGA解析-OK 	
	GPS_GPGSA_InfoGet(GPS_DecodingInfo,buf);	//GPNSA解析-OK
	GPS_GNRMC_InfoGet(GPS_DecodingInfo,buf);	//GPNMC解析-OK
	GPS_GNVTG_InfoGet(GPS_DecodingInfo,buf);	//GPNTG解析-OK
}
复制代码;>;>;>;>

2.4 GPS数据打印

/*
函数功能:显示GPS定位信息
*/
void GPS_MsgShow(void)
{
    float tp;
    tp=GPS_DecodingInfo.longitude;
    sprintf((char *)dtbuf,"经度:%.5f %1c",tp/=100000,GPS_DecodingInfo.ewhemi);    //得到经度字符串
    printf("%s\r\n",dtbuf);
    tp=GPS_DecodingInfo.latitude;
    sprintf((char *)dtbuf,"纬度:%.5f %1c",tp/=100000,GPS_DecodingInfo.nshemi);    //得到纬度字符串
    printf("%s\r\n",dtbuf);
    tp=GPS_DecodingInfo.altitude;
    sprintf((char *)dtbuf,"高度:%.1fm",tp/=10);                              //得到高度字符串
    printf("%s\r\n",dtbuf);
    tp=GPS_DecodingInfo.speed;
    sprintf((char *)dtbuf,"速度:%.3fkm/h",tp/=1000);                 //得到速度字符串    
    printf("%s\r\n",dtbuf);
    if(GPS_DecodingInfo.fixmode<=3)                                                         //定位状态
     {
         sprintf((char *)dtbuf,"定位模式:%s",fixmode_tbl[GPS_DecodingInfo.fixmode]);
         printf("%s\r\n",dtbuf);
     }
     sprintf((char *)dtbuf,"GPS+BD 定位的GPS卫星数:%02d",GPS_DecodingInfo.posslnum);           //用于定位的GPS卫星数
     printf("%s\r\n",dtbuf);
     sprintf((char *)dtbuf,"GPS 可见GPS卫星数:%02d",GPS_DecodingInfo.svnum%100);          //可见GPS卫星数
     printf("%s\r\n",dtbuf);
 ​
     sprintf((char *)dtbuf,"BD 可见北斗卫星数:%02d",GPS_DecodingInfo.beidou_svnum%100);         //可见北斗卫星数
     printf("%s\r\n",dtbuf);
 ​
     sprintf((char *)dtbuf,"UTC日期:%04d/%02d/%02d   ",GPS_DecodingInfo.utc.year,GPS_DecodingInfo.utc.month,GPS_DecodingInfo.utc.date);    //显示UTC日期
     printf("%s\r\n",dtbuf);
     sprintf((char *)dtbuf,"显示UTC时间:%02d:%02d:%02d   ",GPS_DecodingInfo.utc.hour,GPS_DecodingInfo.utc.min,GPS_DecodingInfo.utc.sec); //显示UTC时间
     printf("%s\r\n",dtbuf);
 }

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • gps
    gps
    +关注

    关注

    22

    文章

    2895

    浏览量

    166238
  • Linux
    +关注

    关注

    87

    文章

    11304

    浏览量

    209503
  • 电子围栏
    +关注

    关注

    0

    文章

    59

    浏览量

    10731
收藏 人收藏

    评论

    相关推荐

    上海索脉电子围栏设计方案

    本帖最后由 eehome 于 2013-1-5 09:51 编辑 上海索脉电子围栏设计方案
    发表于 08-20 13:50

    电子围栏起源于欧洲吗

    了“电子围栏”的开发和推广。牛羊等遇到“电子围栏”的电击阻挡而退回,很好地起到“牧羊人”的作用,同时也防止圈外的大型动物或猛兽跑进来,对当时
    发表于 04-25 15:40

    北斗+GPS双模定位模块助力ofo小黄车跑通电子围栏技术

    。这是国内首个进入实用阶段的电子围栏试点。而率先完成报备和数据接口调试工作的ofo小黄车,成为了首家跑通电子围栏技术的共享单车企业,而智能锁中的北斗+
    发表于 06-16 16:02

    SKYLAB助力共享单车搭建电子围栏系统

    `为了对共享单车进行智能化管理,引导企业规范管理,用户有序停车。近日,北京在通州和朝阳两区开始试点共享自行车电子围栏,目前已试点400多个,并将继续增加。而拒绝接入的企业将被要求退出。 据悉,国内
    发表于 07-27 11:55

    电子围栏有什么功能?

    电子围栏按其在现场的安装位置,分为独立式,附属式和墙顶式三种基本安装形式。独立式电子围栏,直接架设在地面上。其高度约2米左右,一般安装10-12根线缆。考虑到设备和人身安全,要求在独立
    发表于 10-11 09:01

    作品分享-基于RT-Thread系统和N32G457开发开发电子围栏设计

    基于RT-Thread系统和N32G457开发开发电子围栏设计,主要采用的是N32G457开发板,并搭载AIR724 4G模块作为数据传
    发表于 03-14 14:25

    如何区别电子围栏和电网,科普一下电子围栏的危害

    电子围栏不等于传统电网,脉冲电子围栏并不是电网 电子围栏:目前最先进的周界防盗报警系统就是脉冲
    发表于 07-10 11:02 4714次阅读

    脉冲电子围栏对人体有没有伤害,如何区别电子围栏和电网

    电子围栏不等于传统电网,脉冲电子围栏并不是电网。 电子围栏:目前最先进的周界防盗报警系统就是脉冲
    发表于 08-12 15:38 5494次阅读

    张力式电子围栏与脉冲式电子围栏的功能作用及适用场合

    张力式电子围栏与脉冲式电子围栏相比,在功能上虽然没有脉冲式完善,防盗作用也可能会略逊一筹,但是在报警的细致程度上则要比脉冲式电子
    发表于 09-29 10:46 3023次阅读

    脉冲电子围栏的工作原理及功能特点

    脉冲电子围栏基本原理就是发出高压脉冲,由脉冲发生器(主机)和前端围栏组成的智能型周界系统。具有防盗、报警等高安全等级的周界防范功能。现代公共安全用 电子
    发表于 04-01 11:10 8879次阅读

    浅谈脉冲电子围栏系统的组成及功能

    AILIFU艾礼富脉冲电子围栏系统组成主要由电子围栏主机、前端配件(终端杆、中间承力杆、终端杆绝缘子、承力杆绝子、高压避雷器、高压线、合金线、围栏
    发表于 04-01 11:41 1470次阅读

    脉冲电子围栏的设计与安装

    脉冲电子围栏基本原理就是发出高压脉冲,由脉冲发生器(主机)和前端围栏组成的智能型周界系统。具有防盗、报警等高安全等级的周界防范功能。现代公共安全用 电子
    发表于 06-30 13:52 1024次阅读

    智能脉冲电子围栏的功能特点

    智能脉冲电子围栏是传统周界围栏里用的最多的一种,脉冲电子围栏系统可识别有意入侵和无意入侵,并能智能识别出入侵位置给予有效阻拦,不会造成人身伤
    发表于 07-01 09:42 1374次阅读

    GPS模块的电子围栏功能有什么用

    GPS模块其实属于遥感、物联网技术应用的硬件设备,获取通信卫星的定位信息,除了定位导航功能,还能登录到相应设备的物联网管理后台上,实时查看位置信息,并开启电子围栏功能,也就是防盗报警系统。
    的头像 发表于 02-22 17:33 1305次阅读
    <b class='flag-5'>GPS</b>模块的<b class='flag-5'>电子</b><b class='flag-5'>围栏</b>功能有什么用

    车辆电子围栏系统:守护爱车安全的智能新防线

    大家具体介绍的关于车辆电子围栏系统相关内容。 车辆电子围栏系统其实就是通过GPS定位、无线通信及大数据分析等高科技技术,为车辆设定一个虚拟的
    的头像 发表于 08-20 11:06 464次阅读
    车辆<b class='flag-5'>电子</b><b class='flag-5'>围栏</b>系统:守护爱车安全的智能新防线