GPS模块实验

2023-05-16

一、GPS简介

全球定位系统(Global Positioning System,GPS)是一种以空中卫星为基础的高精度无线电导航的定位系统,它在全球任何地方以及近
空间都能够提供准确的地理位置、车行速度及精确的时间信息。GPS主要由三大组成部分:空间部分、地面监控部分和用户设备部分
GPS系统具有高精度、全天候、用广泛等特点。
太空卫星部分由多颗卫星组成,分成多个轨道,绕行地球一周约12小时。每个卫星均持续发射载有卫星轨道数据及时间的无线电波,
供地球上的各种接收机来应用。
地面管制部分,这是为了追踪及控制太空卫星运行所设置的地面管制站,主要工作为负责修正与维护每个卫星能够正常运转的各项参
数据,以确保每个卫星都能够提供正确的讯息给使用者接收机来接收使用者接收机(即用户设备),追踪所有的GPS卫星,并实时的计算出接收机所在位置的坐标、移动速度及时间。我们日常接触到的用户设备部分,这里使用到的GPS模块即为用户设备接收机部分。

GPS模块硬件

GPS模块与外部控制器的通讯接口有多种方式,这里我们使用串口进行通讯,波特率为9600bps,1bit停止位,无校验位,无流控,默认每秒输出一次标准格式数据。
GPS模块外观如下图所示,通过排线与控制器进行供电和通讯。该模块为集成模块,没有相关原理图。

GPS模块数据格式

GPS使用多种标准数据格式,目前最通用的GNSS格式是NMEA0183格式。NMEA0183是最终定位格式,即将二进制定位格式转为统
标准定位格式,与卫星类型无关。这是一套定义接收机输出的标准信息,有几种不同的格式,每种都是独立相关的ASCII格式,逗点
开数据流,数据流长度从30-100字符不等,通常以每秒间隔持续输出。
NVMEA0183格式主要针对民用定位导航,与专业RTCM2.3/3.0和CMR+的GNSS数据格式不同。通过NMEA0183格式,可以实现GNSS
收机与PC或PDA之间的数据交换,可以通过USB和COM口等通用数据接口进行数据传输,其兼容性高,数据传输稳定。这里我们使用
口进行是串口通讯,通信框图如下图所示。

我们使用串口接收数据,收到的数据包含:$ GPGGA(GPS定位数据)、$ GPGLL(地理定位信息)、$GPGSA(当前卫星信息)
$ GPGSV(可见卫星状态信息)、$ GPRMC(推荐最小定位信息)、$ GPVTG(地面速度信息)。
这里我们只分析$GPGGA (Global Positioning System Fix Data)即可,它包含了GPS定位经纬度、质量因子、HDOP、高程、参考站号
字段。其标准格式如下:
$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*hh < CR > < LF >

$XXGGA语句各字段的含义和取值范围各字段的含义和取值范围见下表所示,XX取值有:

  • GPGGA:单GPS
  • BDGGA:单北斗
  • GLGGA:单GLONASS
  • GNGGA:多星联合定位
字段含义取值范围
<1>UTC时间hhmmss.ss000000.00~235959.99
<2>纬度,格式:ddmm.mmmm000.00000~8959.9999
<3>南北半球N北纬 S南纬
<4>经度格式dddmm.mmmm00000.0000~17959.9999
<5>东西半球E表示东经 W表示西经
<6>GPS状态0=未定位 1=GPS单点定位固定解 2=差分定位 3=PPS解 4=RTK固定解 5=RTK点解 6=估计值 7=手工输入模式 8=模拟模式
<7>应用解算位置的卫星数00~12
<8>HDOP 水平图形强度因子0.500~99.000(大于6不可用)
<9>海拔高度-9999.9~99999.9
<10>地球椭球面相对大地水准面的高度 (高程异常)-9999.9~99999.9
<11>差分时间从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空
<12>参考站号0000~1023;不使用DGPS时为空

例子:$GPGGA,074529.82,2429.6717,N,11804.6973,E,1,8,1.098,42.110,,,M,,*76

二、代码:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <stdlib.h>

int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop)
{
	struct termios newtio, oldtio;
	
	if(tcgetattr(fd, &oldtio) != 0) {
		perror("SetupSerial 1");
		return -1;
	}

	bzero(&newtio, sizeof(newtio));
	newtio.c_cflag |= CLOCAL|CREAD;
	newtio.c_cflag &= ~CSIZE;

	newtio.c_lflag &= ~(ICANON|ECHO|ECHOE|ISIG);
	newtio.c_oflag &= ~OPOST;

	switch(nBits) {
	case 7:
		newtio.c_cflag |= CS7;
		break;
	case 8:
		newtio.c_cflag |= CS8;
		break;
	}

	switch(nEvent) {
	case 0:
		newtio.c_cflag |= PARENB;
		newtio.c_cflag |= PARODD;
		newtio.c_iflag |= (INPCK | ISTRIP);
		break;
	case 'E':
		newtio.c_iflag |= (INPCK|ISTRIP);
		newtio.c_cflag |= PARENB;
		newtio.c_cflag &= ~PARODD;
		break;
	case 'N':
		newtio.c_cflag &= ~PARENB;
		break;
	}

	switch(nSpeed) {
	case 2400:
		cfsetispeed(&newtio, B2400);
		cfsetospeed(&newtio, B2400);
		break;
	case 4800:
		cfsetispeed(&newtio, B4800);
		cfsetospeed(&newtio, B4800);
		break;
	case 9600:
		cfsetispeed(&newtio, B9600);
		cfsetospeed(&newtio, B9600);
		break;
	case 115200:
		cfsetispeed(&newtio, B115200);
		cfsetospeed(&newtio, B115200);
		break;
	default:
		cfsetispeed(&newtio, B9600);
		cfsetospeed(&newtio, B9600);
		break;
	}


	if(nStop == 1)
		newtio.c_cflag &= ~CSTOPB;
	else if(nStop == 2)
		newtio.c_cflag |= CSTOPB;

	newtio.c_cc[VMIN] = 1;
	newtio.c_cc[VTIME] = 0;

	tcflush(fd, TCIFLUSH);
	if((tcsetattr(fd, TCSANOW, &newtio)) != 0) {
		perror("com set error");
		return -1;
	}

	return 0;
}

int open_port(char *com)
{
	int fd;
	fd = open(com, O_RDWR|O_NOCTTY);
	if(-1 == fd) {
		return -1;
	}

	if(fcntl(fd, F_SETFL, 0) < 0) {
		printf("fcntl failed\n");
		return -1;
	}
	return fd;
}

int read_gps_raw_data(int fd, char *buf)
{
	int i = 0;
	int iRet;
	char c;
	int start = 0;

	while(1) {
		iRet = read(fd, &c, 1);
		if(iRet == 1) {
			if(c=='$') {
				start = 1;
			}
			if(start) {
				buf[i++] = c;
			}
			if(c == '\n' || c == 'r') {
				start = 0;
				return 0;
			}
		} else {
			return -1;
		}
	}
}

/* eg. $GPGGA,074529.82,2429.6717,N,11804.6973,E,1,8,1.098,42.110,,,M,,*76 <CR><LF> */
int parse_gps_raw_data(char *buf, char *time, char *lat, char *ns, char *lng, char *ew)
{
	char tmp[10];

	if(buf[0] != '$') {
		return -1;
	} else if(strncmp(buf+3, "GGA", 3) != 0) {
		return -1;
	} else if(strstr(buf, ",,,,,")) {
		printf("Place the GPS to open area\n");
		return -1;
	} else {
		scanf(buf, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,]",tmp,time,lat,ns,lng,ew);
		return 0;
	}
}

int main(int argc, char *argv[])
{
	int fd;
	int iRet;
	char c;
	char buf[1000];
	char time[100], lat[100], ns[100], lng[100], ew[100];

	float fLat, fLng;

	if(argc != 2) {
		printf("Usage: \n");
		printf("%s </dev/ttySAC1 or other>\n", argv[0]);
		return -1;
	}

	fd = open_port(argv[1]);
	if(fd < 0) {
		printf("open %s err!\n", argv[1]);
		return -1;
	}

	iRet = set_opt(fd, 115200, 8, 'N', 1);
	if(iRet) {
		printf("set port err!\n");
		return -1;
	}

	printf("Enter a char: ");
	while(1) {
		/* read line */
		iRet = read_gps_raw_data(fd, buf);
		/* parse line */
		if(iRet == 0) {
			iRet = parse_gps_raw_data(buf,time,lat,ns,lng,ew);
		}
		/* printf */
		if(iRet == 0) {
			printf("Time :%s\n", time);
			printf("ns:%s\n", ns);
			printf("ew:%s\n", ew);
			printf("lat:%s\n", lat);
			printf("lng:%s\n", lng);
			/* lat ddmm.mmmm */
			scanf(lat+2, "%f", &fLat);
			fLat = fLat / 60;
			fLat += (lat[0]-'0')*10 + (lat[1]-'0');
			/* lng dddmm.mmmm */
			scanf(lng+3, "%f", &fLng);
			fLng = fLng / 60;
			fLng += (lng[0]-'0')*100 +(lng[1]-'0')*10+(lng[2]-'0');
			printf("Lng,Lat: %06f, %06f\n", fLng, fLat);
		}
	}

	return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GPS模块实验 的相关文章

  • 【matlab】矩形窗/三角窗/hanning窗/hamming窗/blackman窗的频率响应图

    File Matlab的窗函数 矩形窗 功能 xff1a 降低旁瓣水平 参数 xff1a N 61 51 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • eclipse无法导入项目由于“某些项目因位于工作空间目录中而被隐藏”

    从eclipse左侧的 资源管理器 中右击选择 删除项目 的方式删除项目后 xff0c 右击 导入项目 导入原来删除了的同名项目时 xff0c 会无法导入项目 xff0c 显示 某些项目因位于工作空间目录中而被隐藏 原因 xff1a ecl
  • 继承中父类与子类的构造与析构顺序

    父类与子类的构造与析构顺序 继承中的顺序如下 xff1a 先构造父类 xff0c 在构造子类 析构顺序与构造顺序相反 span class token macro property span class token directive ke
  • 基于ROS+CANopen的SocketCAN驱动在Ubuntu下的应用说明

    基于ROS 43 CANopen的SocketCAN驱动在Ubuntu20 04 18 04上的应用说明 摘要 Abstract keywords 在Ubuntu 20 04或者18 04里 xff0c 运用ROS下的CANopen消息机制
  • HDFS详解一

    前言 xff1a 一 HDFS的一些基本概念 xff1a 数据块 xff08 block xff09 xff1a 大文件会被分割成多个block进行存储 xff0c block大小默认为128MB 每一个block会在多个datanode上
  • potplayer播放器没有声音的解决方案

    potplayer播放器没有声音的解决方案 最近突然发现电脑上的potplayer播放视频文件的时候只有图像没有声音了 xff0c 卸载后重装依旧如此 经一番摸索 xff0c 解决方法如下 1 在播放界面按一下 m 键 xff0c 可以开启
  • 解决Mysql安装之后没有my.ini配置文件问题

    详记MySql问题大全集 三 安装之后没有my ini配置文件怎么办 系列目录 一 安装MySql 二 安装并破解Navicat 三 没有my in配置文件怎么办 四 设置MySql的大小写敏感 五 重置MySql登陆密码 之前说过 xff
  • 一个简单的环形进度条组件 vue-circleprogressbar

    vue circleprogressbar 一个简单的环形进度条组件 最近在开发可视化大屏项目中经常会用到环形进度条 但是常用的echarts组件对环形进度条的支持不太好 写起来比较麻烦 就想着自己写一个VUE的环形组件 满足自己日常开发需
  • Hbuilder如何创建并运行Vue项目

    在Hbuilder中开发Vue项目是非常快捷的 xff0c 下面小编给大家分享一下如何在Hbuilder中创建并运行Vue项目 方法 步骤 1 首先打开Hbuilder创建一个新项目 xff0c 如下图所示 2 Hbuilder如何创建并运
  • 教大家防止Jar包被反编译

    xff08 待验证 xff09 方法就是 xff0c 向Jar注入无效代码 xff08 不合法的 xff0c 或者根本不是代码的字符串 xff09 那么无效的代码又怎么能正确运行呢 xff1f 答案就是 xff0c 你要保证你的代码永远不会
  • 推荐3个小程序开源组件库——Vant、iView、ColorUI

    推荐3个小程序开源组件库 在进行小程序开发时 xff0c 经常会遇到编写组件方面的阻碍 xff0c 这让我们花费大量的时间在页面以及 CSS 样式编写上 因此可以使用开源组件库 xff0c 有些复杂的组件可以直接拿来使用 xff0c 节省开
  • 试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)

    两种原因 第一种为程序的运行以平台系统位数不匹配 第二种则是该死的VS整出来的 一般在下面三种情景下会发生 1 64位系统上C 调用32位的C 43 43 dll 2 64位系统上IIS发布含有32位的 dll应用程序时 3 64位系统上编
  • 怎么进bios设置硬盘启动顺序|电脑bios硬盘启动设置方法

    怎么在BIOS里设置硬盘启动 xff1f 电脑在启动时会从硬盘寻找引导文件 xff0c 从而启动系统 xff0c 如果硬盘不是第一启动项 xff0c 或者有两个硬盘 xff0c 就会导致系统无法启动 xff0c 这时候就需要进BIOS设置硬
  • Windows计划任务执行时不显示窗口的问题

    最近开发了工具 xff0c 带界面的 xff0c 需要定时执行的 xff0c 为了方便直接用Windows计划任务做定时了 跑了一段时间发现 xff0c 进程中也有 xff0c 就是看不到程序的界面 xff0c 进程的执行貌似也阻塞了 从网
  • JAVA的@EXCEL导出导入常用注解汇总

    在实际开发中经常需要使用导入导出功能来加快数据的操作 在项目中可以使用注解来完成此项功能 在需要被导入导出的实体类属性添加 64 Excel注解 参数类型默认值描述sortintInteger MAX VALUE值越小越靠前readConv
  • MySQL中order by排序将NULL排在最前或最后面

    NULL的意思表示什么都不是 xff0c 或者理解成 未知 也可以 xff0c 它与任何值比较的结果都是false 注意 xff1a 默认情况下 xff0c MySQL会认为NULL值比其他类型的数据小 xff0c 也就是说 xff1a 在
  • C# 如何获取本机IP

    百度搜索的方案 如果你去百度C 如何获取本机IP xff0c 那么大概率的你会得到以下的几段代码 xff0c 第一种就是这样 xff1a string name 61 Dns GetHostName IPAddress ipadrlist
  • winform DevExpress contextMenuStrip右键事件

    span class token keyword private span span class token return type class name span class token keyword void span span sp
  • Linux TCP连接数限制配置

    在进行接口测试时 xff0c 在用户数超过400后 xff0c 就会出现socket connection reset xff0c 明显就是系统无法创建连接 xff0c 查看此时系统建立的TCP连接 xff0c netstat ant gr
  • 摘要认证及实现HTTP digest authentication

    最近工作需要做了摘要认证 xff08 digest authentication xff09 xff0c 下面就工作中遇到的问题及过程做一个总结 第一次客户端请求 GET POST 服务器产生一个随机数nonce xff0c 服务器将这个随

随机推荐

  • HTTPURL Connection及session保存问题

    HTTPURL Connection及session保存问题 HTTPURL Connection是一种多用途 轻量极的HTTP客户端 xff0c 使用它来进行HTTP操作可以适用于大多数的应用程序 虽然HttpURLConnection的
  • SpringBoot 集成redis-jedis

    SpringBoot 集成redis jedis 配置application properties中的redis Redis配置 Redis数据库索引 xff08 默认为0 xff09 spring redis database 61 0
  • Python爬虫常用之登录(三) 使用http请求登录

    前面说了使用浏览器登录较为简单 不需要过多分析 而使用请求登录恰恰就是以分析为主 开发一个请求登录程序的流程 分析请求 gt 模拟请求 gt 测试登录 gt 调整参数 gt 测试登录 gt 登录成功 一 分析网页 从网页着手 打开博客园的登
  • memmove的算法思想

    1 memmove的用法 C 库函数 void memmove void str1 const void str2 size t n 从 str2 复制 n 个字符到str1 如果目标区域和源区域有重叠的话 memmove 能够保证源串在被
  • 菜菜之路-C语言求阶乘和

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 阶乘是什么 xff1f 二 思想 1 思路12 思路2总结 前言 C语言其实要学好并不简单碰到一道题我们有时根本无从下手
  • 题目:将一个正整数分解质因数。例如:输入90,打印出90=2 * 3 * 3 * 5

    思路1 xff1a 首先先提一个这样的思路 假如这个数是90 xff0c 我们让它被2到90之间的数进行整除 xff0c 如90 2 61 45 0 余数 xff0c 90 3 61 30 我们获取这样的除数 但是有问题 xff0c 90每
  • C语言--求比赛名次问题

    题目内容 xff1a 5位运动员参加了10米台跳水比赛 xff0c 有人让他们预测比赛结果 xff1a A选手说 B第二 xff0c 我第三 B选手说 我第二 xff0c E第四 C选手说 我第一 xff0c D第二 D选手说 C最后 xf
  • 编写程序,输入一个较小的实数deta,利用e=1+1/1(嘿哈)+1/2(嘿哈)+1/3(嘿哈)+⋯+1/n(嘿哈)计算e的近似值,直到最后一项的绝对值小于deta时为止,输出此时e的近似值。

    碰到了一种避开惯性思维的写法想分享出来 由于标题不能打叹号 你品一下哈 include lt stdio h gt include lt math h gt int main int n 61 1 double e 61 1 0 term
  • Linux主板支持多机系统的Mark/Space校验

    Linux主板支持多机系统的Mark Space校验 关键词 xff1a Linux 主板摘要 xff1a 英创Linux主板可以通过RS485总线挂载多个单片机组成多机系统 xff0c 当从机设备比较多 传输数据比较频繁的时候 xff0c
  • 库函数memcpy的实现

    1 先看一下memcpy的声明 从str2所指向的内容的n个字节 复制到str1所指向的内容中 注意这里是n个字节 后面实现该库函数时我会详细解释 size t你们可以查一下它的定义 代表着无符号整型 2 好 来看看我们如何实现它 void
  • linux 抓包tcp

    tcpdump是linux下的网络数据包截获分析工具 在linux的日常网络管理中 xff0c tcpdump的使用频率很高 xff0c 熟练掌握对提高工作效率很有帮助 支持针对网络层 协议 主机 网络或端口的过滤 并提供and or no
  • STM32串口中断接收一帧数据

    STM32串口中断接收一帧数据 IDLE即串口空闲中断 xff0c 串口收到一帧数据后 xff0c 发生的中断 比如说给单片机一次发来1个字节 xff0c 或者一次发来8个字节 xff0c 这些一次发来的数据 xff0c 就称为一帧数据 x
  • shell中各种括号的作用()、(())、[]、[[]]、{}

    一 小括号 xff0c 圆括号 xff08 xff09 1 单小括号 命令组 括号中的命令将会新开一个子shell顺序执行 xff0c 所以括号中的变量不能够被脚本余下的部分使用 括号中多个命令之间用分号隔开 xff0c 最后一个命令可以没
  • 双极性(相)四线步进电机TC1508S(双通道直流马达驱动器)

    实验现象 xff1a 下载程序后 xff0c 步进电机旋转 接线说明 xff1a 具体接线图可见开发攻略对应实验的 实验现象 章节 1 xff0c 单片机 gt 四线双极性步进电机模块 P10 gt IA P11 gt IB P12 gt
  • c语言实现广播(udp协议)

    广播 xff1a 顾名思义可以把自己的数据发送给在特定范围内的所有人 xff1b 我们网络编程中的广播一般是通过特定的广播地址把自己的数据发送给局域网内当前在线的客户端 我们可以使用命令查看我们Linux下当前的广播地址 xff1a ifc
  • C++中的结构体与类

    C 43 43 中继承了C语言中的结构体 xff0c 但同时也在C语言的基础上新增了一个类 class 的概念 xff0c 类可以说是C语言中结构体的升级版 这里主要细讲C 43 43 中的类 1 C 43 43 结构体 2 C 43 43
  • 在VMware的Ubuntu18.04搭建vsftp(上传文件)和apache2(http服务)

    在VMware的Ubuntu18 04下 xff1a 搭建vsftp xff08 本机win上传文件 xff09 xff1a 第一步安装vsftp xff1a 直接安装可能会报错Ubuntu 34 E Unable to locate pa
  • 安装ROS时, rosdep update出错解决办法

    网上查了一下 原因基本指向一个 网速问题 按如下步骤进行操作 步骤1 将电脑连接到手机热点 寄希望可以提高网速 依然出错 出错内容大致如下 reading in sources list data from etc ros rosdep s
  • get请求的参数包含中括号[]时,报错400

    1 问题描述 在正式环境中 xff0c 上传文件 2003年鉴 docx 时 xff0c 报错400 但是 xff0c 只有此文件上传时会报错 xff0c 其他文件是正常的 xff08 后文为了方便描述 xff0c 将问题文件称为a xff
  • GPS模块实验

    一 GPS简介 全球定位系统 Global Positioning System GPS 是一种以空中卫星为基础的高精度无线电导航的定位系统 它在全球任何地方以及近 空间都能够提供准确的地理位置 车行速度及精确的时间信息 GPS主要由三大组