cubemx hal stm32 atgm336h GPS 北斗 定位 模块 驱动代码

news2024/11/15 18:47:42

模块样图

代码部分

atgm336h.c

#include "atgm336h.h"
#include "stdio.h"
#include "string.h"

char rxdatabufer;
u16 point1 = 0;

_SaveData Save_Data;
LatitudeAndLongitude_s g_LatAndLongData =
{
	.E_W = 0,
	.N_S = 0,
	.latitude = 0.0,
	.longitude = 0.0
};

// 串口1中断服务程序
// 注意,读取USARTx->SR能避免莫名其妙的错误
char USART_RX_BUF[USART_REC_LEN];	// 接收缓冲,最大USART_REC_LEN个字节.
uint8_t uart_A_RX_Buff;

// 接收状态
// bit15,	接收完成标志
// bit14,	接收到0x0d
// bit13~0,	接收到的有效字节数目
u16 USART_RX_STA=0;	// 接收状态标记

void atgm336h_init(void)
{
	clrStruct();
	HAL_UART_Receive_IT(&huart2, &uart_A_RX_Buff, 1);
}

void atgm336h_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == USART2)
	{
//		printf("%c", uart_A_RX_Buff);
		if(uart_A_RX_Buff == '$')
		{
			point1 = 0;
		}
		USART_RX_BUF[point1++] = uart_A_RX_Buff;

		if(USART_RX_BUF[0] == '$' && USART_RX_BUF[4] == 'M' && USART_RX_BUF[5] == 'C')	//确定是否收到"GPRMC/GNRMC"这一帧数据
		{
			if(uart_A_RX_Buff == '\n')
			{
				memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length);      //清空
				memcpy(Save_Data.GPS_Buffer, USART_RX_BUF, point1); 	//保存数据
				Save_Data.isGetData = true;
				point1 = 0;
				memset(USART_RX_BUF, 0, USART_REC_LEN);      //清空
			}
		}
		if(point1 >= USART_REC_LEN)
		{
			point1 = USART_REC_LEN;
		}

		HAL_UART_Receive_IT(&huart2, &uart_A_RX_Buff, 1);
	}
}

u8 Hand(char *a)	// 串口命令识别函数
{
    if(strstr(USART_RX_BUF, a)!=NULL)
	    return 1;
	else
		return 0;
}

void CLR_Buf(void)	// 串口缓存清理
{
	memset(USART_RX_BUF, 0, USART_REC_LEN);	//清空
  point1 = 0;
}

void clrStruct(void)
{
	Save_Data.isGetData = false;
	Save_Data.isParseData = false;
	Save_Data.isUsefull = false;
	memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length);	//清空
	memset(Save_Data.UTCTime, 0, UTCTime_Length);
	memset(Save_Data.latitude, 0, latitude_Length);
	memset(Save_Data.N_S, 0, N_S_Length);
	memset(Save_Data.longitude, 0, longitude_Length);
	memset(Save_Data.E_W, 0, E_W_Length);
}

void errorLog(int num)
{

	while (1)
	{
	  	printf("ERROR%d\r\n",num);
	}
}

void parseGpsBuffer(void)
{
	char *subString;
	char *subStringNext;
	char i = 0;

	uint16_t Number=0, Integer=0, Decimal=0;


	if (Save_Data.isGetData)
	{
		Save_Data.isGetData = false;
		printf("**************\r\n");
		printf("%s\r\n", Save_Data.GPS_Buffer);

		for (i = 0 ; i <= 6 ; i++)
		{
			if (i == 0)
			{
				if ((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL)
					errorLog(1);	//解析错误
			}
			else
			{
				subString++;
				if ((subStringNext = strstr(subString, ",")) != NULL)
				{
					char usefullBuffer[2];
					switch(i)
					{
						case 1:memcpy(Save_Data.UTCTime, subString, subStringNext - subString);break;	//获取UTC时间
						case 2:memcpy(usefullBuffer, subString, subStringNext - subString);break;	//获取UTC时间
						case 3:memcpy(Save_Data.latitude, subString, subStringNext - subString);break;	//获取纬度信息
						case 4:memcpy(Save_Data.N_S, subString, subStringNext - subString);break;	//获取N/S
						case 5:memcpy(Save_Data.longitude, subString, subStringNext - subString);break;	//获取经度信息
						case 6:memcpy(Save_Data.E_W, subString, subStringNext - subString);break;	//获取E/W

						default:break;
					}
					subString = subStringNext;
					Save_Data.isParseData = true;
					if(usefullBuffer[0] == 'A')
						Save_Data.isUsefull = true;
					else if(usefullBuffer[0] == 'V')
						Save_Data.isUsefull = false;
				}
				else
				{
					errorLog(2);	//解析错误
				}
			}
		}

		if (Save_Data.isParseData)
		{
			if(Save_Data.isUsefull)
			{
				// 获取 N/S 和 E/W
				g_LatAndLongData.N_S = Save_Data.N_S[0];
				g_LatAndLongData.E_W = Save_Data.E_W[0];

				// 获取纬度
				for(uint8_t i=0; i<9; i++)
				{
					if(i<2)
					{
						Number *= 10;
						Number += Save_Data.latitude[i]-'0';
					}
					else if(i<4)
					{
						Integer *= 10;
						Integer += Save_Data.latitude[i]-'0';
					}
					else if(i==4);
					else if(i<9)
					{
						Decimal *= 10;
						Decimal += Save_Data.latitude[i]-'0';
					}
				}
				g_LatAndLongData.latitude = 1.0*Number + (1.0*Integer+1.0*Decimal/10000)/60;

				Number = 0;
				Integer = 0;
				Decimal = 0;

				// 获取经度
				for(uint8_t i=0; i<10; i++)
				{
					if(i<3)
					{
						Number *= 10;
						Number += Save_Data.longitude[i]-'0';
					}
					else if(i<5)
					{
						Integer *= 10;
						Integer += Save_Data.longitude[i]-'0';
					}
					else if(i==5);
					else if(i<10)
					{
						Decimal *= 10;
						Decimal += Save_Data.longitude[i]-'0';
					}
				}
				g_LatAndLongData.longitude = 1.0*Number + (1.0*Integer+1.0*Decimal/10000)/60;
			}
		}
	}
}

void printGpsBuffer(void)
{
	if (Save_Data.isParseData)
	{
		Save_Data.isParseData = false;

		printf("Save_Data.UTCTime = %s\r\n", Save_Data.UTCTime);

		if(Save_Data.isUsefull)
		{
			Save_Data.isUsefull = false;
			printf("Save_Data.latitude = %s\r\n", Save_Data.latitude);
			printf("Save_Data.N_S = %s", Save_Data.N_S);
			printf("Save_Data.longitude = %s", Save_Data.longitude);
			printf("Save_Data.E_W = %s\r\n", Save_Data.E_W);

			printf("latitude: %c,%.4f\r\n", g_LatAndLongData.N_S, g_LatAndLongData.latitude);
			printf("longitude: %c,%.4f\r\n", g_LatAndLongData.E_W, g_LatAndLongData.longitude);
		}
		else
		{
			printf("GPS DATA is not usefull!\r\n");
		}
	}
}

atgm336h.h

#ifndef __ATGM336H_H
#define __ATGM336H_H

#include "usart.h"
#include "sys.h"
#include "stdbool.h"

#define USART_REC_LEN  		200	//定义最大接收字节数 200
#define EN_USART1_RX 			1		//使能(1)/禁止(0)串口1接收

//#define false 0
//#define true 1

//定义数组长度
#define GPS_Buffer_Length 80
#define UTCTime_Length 11
#define latitude_Length 11
#define N_S_Length 2
#define longitude_Length 12
#define E_W_Length 2



typedef struct SaveData
{
	char GPS_Buffer[GPS_Buffer_Length];
	char isGetData;		//是否获取到GPS数据
	char isParseData;	//是否解析完成
	char UTCTime[UTCTime_Length];		//UTC时间
	char latitude[latitude_Length];		//纬度
	char N_S[N_S_Length];		//N/S
	char longitude[longitude_Length];		//经度
	char E_W[E_W_Length];		//E/W
	char isUsefull;		//定位信息是否有效
} _SaveData;

// 经纬度数据
typedef struct _LatitudeAndLongitude_s
{
	float latitude;			// 纬度
	float longitude;		// 经度

	char N_S;	// 北南
	char E_W;	// 东西
}LatitudeAndLongitude_s;


extern char rxdatabufer;
extern u16 point1;
extern _SaveData Save_Data;
extern LatitudeAndLongitude_s g_LatAndLongData;

// 放入串口接收中断中
void atgm336h_UART_RxCpltCallback(UART_HandleTypeDef *huart);

// 初始化
void atgm336h_init(void);

// 清除结构体数据
void clrStruct(void);

// 解包函数
void parseGpsBuffer(void);

// 打印函数
void printGpsBuffer(void);

#endif	// __ATGM336H_H


使用

main.c

#include "atgm336h.h"
#include "stdio.h"


int fputc(int ch, FILE *fp)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	atgm336h_UART_RxCpltCallback(huart);
}

int main(void)
{
  atgm336h_init();

  while (1)
  {
	if (Save_Data.isParseData)
	{
		Save_Data.isParseData = false;
		if(Save_Data.isUsefull)
		{
			Save_Data.isUsefull = false;
			printf("latitude: %c,%.4f\r\n", g_LatAndLongData.N_S, g_LatAndLongData.latitude);
			printf("longitude: %c,%.4f\r\n", g_LatAndLongData.E_W, g_LatAndLongData.longitude);
		}
		else
		{
			printf("GPS DATA is not usefull!\r\n");
		}
	}
	HAL_Delay(30);
  }
}

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

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

相关文章

Docker网络架构三剑客CNM,Libnetwork和Driver

Docker网络架构主要由三部分组成&#xff1a;CNM&#xff0c;Libnetwork和Driver。 1.CNM CNM&#xff08;Container Network Model&#xff09;是一种网络模型&#xff0c;用于定义容器的网络架构和实现容器之间的通信。 这其中也有三要素&#xff1a; 沙盒&#xff1a;Sand…

基于matlab使用无限阵列分析对大型阵列中的互耦进行建模(附源码)

一、前言 此示例使用无限数组分析对大型有限数组进行建模。晶胞上的无限阵列分析揭示了特定频率下的扫描阻抗行为。此信息与隔离元件图案和阻抗的知识一起使用&#xff0c;以计算扫描元件图案。然后&#xff0c;使用数组中的每个元素都具有相同扫描元素模式的假设对大型有限数组…

造纸工厂配电室环境监控系统的应用案例与硬件选型

摘要&#xff1a;智能配电室环境监控系统可实现自动巡检、自动预警等功能&#xff0c;减少人员到现场巡视次数&#xff0c;能及早发现设备的潜在风险&#xff0c;迅速检测故障&#xff0c;节约维护保养时长&#xff0c;为配电生产检修、运行、各业务的标准化、规范化管理提供有…

1:即使设计-ui:尺寸和单位

一&#xff1a; 1: 一倍尺寸 378*812 2:二倍尺寸 750*1624 3:三倍尺寸 1125*2436 二&#xff1a;PX和PT px&#xff1a;物理像素 pt&#xff1a;逻辑像素 pt只存在一倍图中 在一倍图&#xff0c;ptpx&#xff0c;二倍图 1px2pt 三&#xff1a;DP和SP

AI开源路在何方丨2023智源大会精彩回顾

导读 当下&#xff0c;AI开源已经成为了人类开源创新的主战场&#xff0c;是超大规模人类智力协同的最佳组织形式。得益于开源协作持续不断地推进&#xff0c;AI在这个时代飞速发展。可以说如果没有开源社区建设&#xff0c;就不会有今天人工智能的成就。 在2023智源大会AI开源…

【python】基于multiprocessing.Pool实现python并行化的坑和解决方案

坑1&#xff1a;apply_async调用的子函数不执行或执行不彻底的解决方案 解决&#xff1a;使用apply_async时传入error_callback检查报错 from multiprocessing import Pooldef processFolder(idx, folders, o_dir):train_mesh TrainMeshes(folders)output_path os.path.join…

python小游戏——骰子猜大小

❄️作者介绍&#xff1a;奇妙的大歪❄️ &#x1f380;个人名言&#xff1a;但行前路&#xff0c;不负韶华&#xff01;&#x1f380; &#x1f43d;个人简介&#xff1a;云计算网络运维专业人员&#x1f43d; 前言 我们已经基本学完了&#xff0c;逻辑判断和循环的用法&#…

Maven历史版本的下载

Maven历史版本的下载 打开Maven官网https://maven.apache.org/ 点击Download 点击Maven 3 archives

持续优化 XView 性能,大促弹窗搭投实践 | 京东云技术团队

背景 618 大促来了&#xff0c;对于业务团队来说&#xff0c;最重要的事情莫过于各种大促营销。如会场、直播带货、频道内营销等等。而弹窗作为一个极其重要的强触达营销工具&#xff0c;通常用来渲染大促氛围、引流主会场、以及通过频道活动来提升频道复访等。因此&#xff0…

Apache JMeter配置步骤压力测试实例

一. 安装环境&#xff1a;................................................................................................................ 2 二&#xff0e;安装步骤&#xff1a;...................................................................................…

QGis出图

工程——新建打印布局。 水平垂直参考线的妙用&#xff0c;很好用。 【【QGIS出图教程】免费软件&#xff01;地理科研论文制图&#xff0c;出研究区位图&#xff0c;比Arcgis出图好使】

快速入门SringCloud

认识微服务 微服务是一种经过良好架构设计的分布式架构方案&#xff0c;微服务的特征有&#xff1a; 单一职责&#xff1a;微服务拆分粒度小&#xff0c;每一个服务都对应唯一的业务能力&#xff0c;做到单一职责&#xff0c;避免重复开发面向服务&#xff1a;微服务对外暴露…

linux 资源包安装详细教程

linux 资源包安装详细教程 一、离线下载安装1.1 下载1.2 安装1.3 错误&#xff1a;依赖检测失败 - 解决方案1.4 查看安装的包情况 二、在线安装 一、离线下载安装 1.1 下载 点击进入网页&#xff1a;linux资源包下载链接&#xff1a;pkgs.org在搜索栏输入需要的包&#xff0c…

d3dcompiler_47.dll丢失怎么解决(解决方案)

d3dcompiler_47.dll在Windows操作系统和 DirectX应用程序中使用此 DLL 文件,包括游戏&#xff0c;图形处理软件&#xff0c;CAD软件和其他3D应用程序中。如果电脑提示“由于找不到d3dcompiler_47.dll&#xff0c;无法继续执行此代码”&#xff0c;“d3dcompiler_47.dll缺失”&a…

C#多语言切换

第一步建立工程 第二步&#xff1a;拖拽控件 第三步选择窗体 第四步修改窗体localizable 属性为 true 如下图 第五步 修改language 属性 如下图 第六步&#xff1a;修改各个控件的字符名称 会出现下面的资源文件&#xff08;注意之前是没有资源文件的&#xff09; 第七步&…

Druid 数据库密码加密-代码详解

这次来详细说下 Druid 数据库密码加密-代码详解 第一种方法使用原生加解密 首先需要使用druid的密码加密功能加密密码 > 找到druid jar文件地址 执行 加密命令 java -cp druid-1.2.10.jar com.alibaba.druid.filter.config.ConfigTools you_password 会得到以下信息 priva…

回顾 | Learn From Microsoft Build Ⅱ:Data

点击蓝字 关注我们 编辑&#xff1a;Alan Wang 排版&#xff1a;Rani Sun 微软 Reactor 为帮助广开发者&#xff0c;技术爱好者&#xff0c;更好的学习 .NET Core, C#, Python&#xff0c;数据科学&#xff0c;机器学习&#xff0c;AI&#xff0c;区块链, IoT 等技术&#xff0…

动态隐藏显示底部Tab栏

方式1 路由源信息 方式2 css样式 css功能&#xff1a;让盒子盖住整个页面 给div.city添加.page-cover的类&#xff08;让div.city盖住页面的tabbar&#xff09; /* 让盒子盖住整个页面 */ .page-cover {position: relative;z-index: 2;height: 100vh;background-color: #fff;…

计算机组成原理(期末或考研备考)-计算机系统概述重点

1.1计算机发展历程 1946第一台电子数字计算机(ENIAC)第一代计算机&#xff08;1946-1957&#xff09;-- 电子管&#xff1b;体积大&#xff0c;容量小&#xff0c;成本高&#xff0c;速度慢。第二代计算机&#xff08;1958-1964&#xff09;-- 晶体管&#xff1b;运算速度提升…

java之路—— SpringMVC的基本详解

文章目录 前言一、 核心的组件二、基本实现流程三、MVC的基本配置使用 前言 Spring MVC是一个用于构建Web应用程序的基于MVC&#xff08;Model-View-Controller&#xff09;设计模式的框架。 它是Spring Framework的一部分&#xff0c;提供了一种灵活、可扩展且功能强大的方式…