STM32使用HAL库获取GPS模块HT1818Z3G5L信息(方法1)

1、写在最前

先了解一下GPRMC的格式
格 式:
GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,A*50
说 明:
字段 0:$GPRMC,语句ID,表明该语句为Recommended Minimum Specific GPS/TRANSIT Data(RMC)推荐最小定位信息
字段 1:UTC时间,hhmmss.sss格式
字段 2:状态,A=定位,V=未定位
字段 3:纬度ddmm.mmmm,度分格式(前导位数不足则补0)
字段 4:纬度N(北纬)或S(南纬)
字段 5:经度dddmm.mmmm,度分格式(前导位数不足则补0)
字段 6:经度E(东经)或W(西经)
字段 7:速度,节,Knots(一节也是1.852千米/小时)
字段 8:方位角,度(二维方向指向,相当于二维罗盘)
字段 9:UTC日期,DDMMYY格式
字段10:磁偏角,(000 - 180)度(前导位数不足则补0)
字段11:磁偏角方向,E=东,W=西
字段12:模式,A=自动,D=差分,E=估测,N=数据无效(3.0协议内容)
字段13:校验值

2、配置

使用STM32F103C8T6的串口1,连接模块的串口。
此模块4个引脚标注为“V G T R”
在这里插入图片描述

功能:
V = 3.3V
G = GND
T = TX
R = RX

STM32CUBE配置如下:
在这里插入图片描述
在这里插入图片描述
记得开启串口中断。

3、程序编写

1、先使用单字节接收方式,因为每个帧的结构都是$开头,0x0d,0x0a结尾。如果使用空闲接收的话,这个模块一次发送的数据比较大,需要大几百字节的缓存。
首先在main函数中,先定义需要的全局变量

uint8_t g_ucRxByte;
uint8_t g_ucRxCnt;
uint8_t g_ucaRx[GPS_BUFF_SIZE];
rtcType_T g_tRtcCN;
float g_fSpeed;

在这里插入图片描述
2、进入主循环之前,开启串口接收

  /* USER CODE BEGIN 2 */HAL_UART_Receive_IT(&huart1,&g_ucRxByte,1);/* USER CODE END 2 */

3、编写GPS.h头文件

#ifndef __GPS_H
#define __GPS_H
#include "main.h"#define GPS_BUFF_SIZE	100typedef struct
{uint16_t usYear;uint8_t ucMonth;uint8_t ucDay;uint8_t ucHour;uint8_t ucMinute;uint8_t ucSecond;
}rtcType_T;extern uint8_t g_ucaGNRMC[GPS_BUFF_SIZE];
extern uint8_t g_ucGNRMCRxSta;uint8_t GPS_GetTime(char *cpRmc,rtcType_T *tpRTC);/*从RMC(推荐最小定位信息)中获取GPS的时间信息,东8区时间*/
rtcType_T GPS_TimeToArea(rtcType_T tTime, uint8_t ucArea);/*转换GPS时间到指定区的时间*/
float GPS_GetSpeed(char *cpRmc);#endif

4、编写GPS.c文件

#include "gps.h"
#include "string.h"
#include "stdlib.h"uint8_t g_ucaGNRMC[GPS_BUFF_SIZE];
uint8_t g_ucGNRMCRxSta;uint8_t GPS_GetTime(char *cpRmc,rtcType_T *tpRTC)
{char *cpStart;uint8_t i;cpStart = strchr(cpRmc,',');tpRTC->ucHour = (cpStart[1]-0x30)*10 + (cpStart[2]-0x30) ;/**/tpRTC->ucMinute = (cpStart[3]-0x30)*10 + (cpStart[4]-0x30);tpRTC->ucSecond = (cpStart[5]-0x30)*10 + (cpStart[6]-0x30);cpStart = cpRmc;for(i = 0;i < 9;i++){cpStart = strchr(cpStart,',');cpStart++;}tpRTC->ucDay = (cpStart[0]-0x30)*10 + (cpStart[1]-0x30);tpRTC->ucMonth = (cpStart[2]-0x30)*10 + (cpStart[3]-0x30);tpRTC->usYear = (cpStart[4]-0x30)*10 + (cpStart[5]-0x30) + 2000;return 1;}rtcType_T GPS_TimeToArea(rtcType_T tTime, uint8_t ucArea)
{rtcType_T tConvertTime;tConvertTime = tTime;tConvertTime.ucHour += ucArea;if(1==tConvertTime.ucMonth||3==tConvertTime.ucMonth||5==tConvertTime.ucMonth||7==tConvertTime.ucMonth||8==tConvertTime.ucMonth||10==tConvertTime.ucMonth||12==tConvertTime.ucMonth)//1,3,5,7,8,9,12月每月为31天{if(24 <= tConvertTime.ucHour){tConvertTime.ucHour -= 24;tConvertTime.ucDay += 1;//如果超过24小时,减去24小时,后再加上一天if(tConvertTime.ucDay > 31){tConvertTime.ucDay -= 31;tConvertTime.ucMonth += 1;}//如果超过31一天,减去31天,后加上一个月}}else if(4==tConvertTime.ucMonth||6==tConvertTime.ucMonth||9==tConvertTime.ucMonth||11==tConvertTime.ucMonth)//4,6,9,11月每月为30天{if(24 <= tConvertTime.ucHour){tConvertTime.ucHour -= 24;tConvertTime.ucDay += 1;//如果超过24小时,减去24小时,后再加上一天if(30 < tConvertTime.ucDay){tConvertTime.ucDay -= 30;tConvertTime.ucMonth += 1;}//如果超过30一天,减去30天,后加上一个月}}else//剩下为2月,闰年为29天,平年为28天{if(24 <= tConvertTime.ucHour){tConvertTime.ucHour -= 24;tConvertTime.ucDay += 1;if((0 == tConvertTime.usYear%400)||(0 == tConvertTime.usYear%4 && 0 != tConvertTime.usYear%100))//判断是否为闰年,年号能被400整除或年号能被4整除,而不能被100整除为闰年{if(29 < tConvertTime.ucDay){tConvertTime.ucDay -= 29;tConvertTime.ucMonth += 1;}}//为闰年else{if(28 < tConvertTime.ucDay){tConvertTime.ucDay -= 28;tConvertTime.ucMonth += 1;}}//为平年}}if(12 < tConvertTime.ucMonth){tConvertTime.ucMonth-=12;tConvertTime.usYear+=1;}return tConvertTime;
}/*GNRMC的第7个字段为速度,节,Knots(一节也是1.852千米/小时)*/
float GPS_GetSpeed(char *cpRmc)
{float fSpeed;char *cpStart,*cpEnd,*ptr;uint8_t i,ucLenth;char caTmp[10];memset(caTmp,0,10);cpStart = cpRmc;for(i = 0;i < 7;i++){cpStart = strchr(cpStart,',');cpStart++;}cpEnd = strchr(cpStart,',');ucLenth = cpEnd - cpStart;memcpy(caTmp,cpStart,ucLenth);caTmp[ucLenth] = '\0';fSpeed = strtof(caTmp,&ptr);fSpeed = fSpeed * 1.852;return fSpeed;
}

文件中使用了字符串转浮点数函数,如果不需要速度,可以取消,同时无需包含#include “stdlib.h”

5、返回主函数,进行中断回调函数的编写。

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(g_ucRxByte == '$'){g_ucRxCnt = 0;}else if(g_ucRxByte == 0x0a)/*一帧结束*/{if(g_ucaRx[0]=='$' && g_ucaRx[4]=='M' && g_ucaRx[5]=='C')/*只提取GNRMC*/{memcpy(g_ucaGNRMC,g_ucaRx,g_ucRxCnt);g_ucGNRMCRxSta = g_ucRxCnt | 0x80;}}g_ucaRx[g_ucRxCnt++] = g_ucRxByte;if(g_ucRxCnt >= GPS_BUFF_SIZE)	{g_ucRxCnt = 0;}HAL_UART_Receive_IT(&huart1,&g_ucRxByte,1);
}
/* USER CODE END 4 */

6、使用模块
在主循环中,解析获取的GNRMC数据。

  /* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if(g_ucGNRMCRxSta & 0x80){g_ucGNRMCRxSta = 0;GPS_GetTime((char *)g_ucaGNRMC,&tRTCGps);g_tRtcCN = GPS_TimeToArea(tRTCGps,8);g_fSpeed = GPS_GetSpeed((char *)g_ucaGNRMC);}}/* USER CODE END 3 */

在这里插入图片描述

7、结果
在这里插入图片描述

4、写在最后

这个模块一般般吧,我把模块放到靠近窗户,定位时有时无,定位成功后,静止状态的速度也会跳动。如果需要获取有效的速度信号,可能需要其他辅助,例如运动检测等判断是否在静止状态。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/796163.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构|排序总结(1)|直接插入排序

排序分类 插入排序&#xff1a;直接插入排序&#xff0c;希尔排序 选择排序&#xff1a;选择排序&#xff0c;堆排序 交换排序&#xff1a;冒泡排序&#xff0c;快速排序 归并排序 插入排序 直接插入排序 相当于摸牌&#xff0c;例如我们现在手上有{2&#xff0c;4&#xff0…

碘浊度法与红外相机联用测定食品中维生素C

&#x1f31e;欢迎来到看论文的世界 &#x1f308;博客主页&#xff1a;卿云阁 &#x1f48c;欢迎关注&#x1f389;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f31f;本文由卿云阁原创&#xff01; &#x1f4c6;首发时间&#xff1a;&#x1f339;2024年4月6日&…

数据库的简单查询

一、检索一列或多列1.检索单独一列 select 列名 from 表名; select order_num from orders; 2.检索多列数据 select 列 1&#xff0c;列 2... from 表名; select order_num,order_date from orders; select order_date,order_num from orders; 3.查询所有字段 select * from…

正排索引 vs 倒排索引 - 搜索引擎具体原理

阅读导航 一、正排索引1. 概念2. 实例 二、倒排索引1. 概念2. 实例 三、正排 VS 倒排1. 正排索引优缺点2. 倒排索引优缺点3. 应用场景 三、搜索引擎原理1. 宏观原理2. 具体原理 一、正排索引 1. 概念 正排索引是一种索引机制&#xff0c;它将文档或数据记录按照某种特定的顺序…

016——DHT11驱动开发(基于I.MX6uLL)

目录 一、 模块介绍 1.1 简介 1.2 电路描述 1.3 通信协议 二、 驱动程序 三、 应用程序 四、 上机实验 一、 模块介绍 1.1 简介 DHT11 是一款可测量温度和湿度的传感器。比如市面上一些空气加湿器&#xff0c;会测量空气中湿度&#xff0c;再根据测量结果决定是否继续加…

Cortex-M7 内存映射模型

1 前言 如图1所示&#xff0c; Cortex-M7最大支持4GB的内存寻址&#xff0c;并对内存映射(memory map)做了初步的规定&#xff0c;将整个内存空间划分为了多个内存区域(region)。每个内存区域有着既定的内存类型(memory type)和内存属性(memory attribute)&#xff0c;这两者决…

物理层习题及其相关知识(谁看谁不迷糊呢)

1. 对于带宽为50k Hz的信道&#xff0c;若有4种不同的物理状态来表示数据&#xff0c;信噪比为20dB 。&#xff08;1&#xff09; 按奈奎斯特定理&#xff0c;信道的最大传输数据速率是多少&#xff1f;&#xff08;2&#xff09; 按香农定理&#xff0c;信道的最大传输数据速度…

基于Springboot+Vue实现前后端分离酒店管理系统

一、&#x1f680;选题背景介绍 &#x1f4da;推荐理由&#xff1a; 近几年来&#xff0c;随着各行各业计算机智能化管理的转型&#xff0c;以及人们经济实力的提升&#xff0c;人们对于酒店住宿的需求不断的提升&#xff0c;用户的增多导致酒店管理信息的不断增多&#xff0c;…

ICLR 2024 | 联邦学习后门攻击的模型关键层

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 联邦学习使多个参与方可以在数据隐私得到保护的情况下训练机器学习模型。但是由于服务器无法…

华为分红出炉,人均超50w!

华为分红 770 亿 4 月 2 日&#xff0c;北京金融资产交易所官网发布了《华为投资控股有限公司关于分配股利的公告》。 公告指出&#xff1a;经公司内部有权机构决议&#xff0c;拟向股东分配股利约 770.945 亿元。 众所周知&#xff0c;华为并不是一家上市公司&#xff0c;这里…

C++从入门到精通——初步认识面向对象及类的引入

初步认识面向对象及类的引入 前言一、面向过程和面向对象初步认识C语言C 二、类的引入C的类名代表什么示例 C与C语言的struct的比较成员函数访问权限继承默认构造函数默认成员初始化结构体大小 总结 前言 面向过程注重任务的流程和控制&#xff0c;适合简单任务和流程固定的场…

自定义实现shell/bash

文章目录 函数和进程之间的相似性shell打印提示符&#xff0c;以及获取用户输入分割用户的输入判断是否是内建命令执行相关的命令 全部代码 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff0c;风趣幽默&#…

Day30 线程安全之窗口售票问题(含代码)

Day30 线程安全之窗口售票问题&#xff08;含代码&#xff09; 一、需求&#xff1a; 铁道部发布了一个售票任务&#xff0c;要求销售1000张票&#xff0c;要求有3个窗口来进行销售&#xff0c; 请编写多线程程序来模拟这个效果&#xff08; 注意&#xff1a;使用线程类的方式…

【Qt 学习笔记】详解Qt中的信号和槽

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 详解Qt中的信号与槽 文章编号&#xff1a;Qt 学习笔记 / 12 文章目录…

红黑树的平衡之道:深入解析右旋操作的原理与实践

红黑树的平衡之道&#xff1a;深入解析右旋操作的原理与实践 一、 红黑树旋转的背景二、右旋&#xff08;RIGHT-ROTATE&#xff09;的原理三、右旋&#xff08;RIGHT-ROTATE&#xff09;的算法步骤四、右旋&#xff08;RIGHT-ROTATE&#xff09;的伪代码五、右旋&#xff08;RI…

ctf_show笔记篇(web入门---jwt)

目录 jwt简介 web345&#xff1a; web346&#xff1a; web347&#xff1a; web348: web349&#xff1a; web350&#xff1a; jwt简介 JSON Web Token&#xff08;JWT&#xff09;通常由三部分组成 Header&#xff08;头部&#xff09;&#xff1a;包含了两部分信息&…

蓝桥杯备考3

P8196 [传智杯 #4 决赛] 三元组 题目描述 给定一个长度为 n 的数列 a&#xff0c;对于一个有序整数三元组 (i,j,k)&#xff0c;若其满足 1≤i≤j≤k≤n 并且&#xff0c;则我们称这个三元组是「传智的」。 现在请你计算&#xff0c;有多少有序整数三元组是传智的。 输入格式…

LRU的原理与实现(java)

介绍 LRU的英文全称为Least Recently Used&#xff0c;即最近最少使用。它是一种内存数据淘汰算法&#xff0c;当添加想要添加数据而内存不足时&#xff0c;它会优先将最近一段时间内使用最少的数据淘汰掉&#xff0c;再将数据添加进来。 原理 LRU的原理在介绍中就已经基本说…

机器学习模型——逻辑回归

https://blog.csdn.net/qq_41682922/article/details/85013008 https://blog.csdn.net/guoziqing506/article/details/81328402 https://www.cnblogs.com/cymx66688/p/11363163.html 参数详解 逻辑回归的引出&#xff1a; 数据线性可分可以使用线性分类器&#xff0c;如果…

蓝桥真题--路径之谜DFS解法

路径之谜 思路 前置知识&#xff1a;深度搜索模板搜索所有可以找的路径&#xff0c;将走过的靶子减去一走到最后一个格子的时候&#xff0c;直接去判断所有的靶子只有除最后一个位置的靶子&#xff0c;其余靶子都归零的时候&#xff0c;判断一个最后一个位置横坐标和纵坐标的靶…