嵌入式外设集 -- GPS定位模块(ATGM336H)

这篇具有很好参考价值的文章主要介绍了嵌入式外设集 -- GPS定位模块(ATGM336H)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、模块介绍

关注微信公众号--星之援工作室 发送关键字(GPS模块)

 使用的注意事项

 二、如何移植

usart2.c

usart2.h

获取以及解析经纬度

显示经纬度

三、参考


一、模块介绍

ATGM336H是一种高性能的GPS模块,可以在较低功耗下提供高精度、高可靠性的位置信息服务。它采用了SiRFstarIII技术,并支持多种导航卫星系统,包括GPS、GLONASS、Galileo、QZSS和SBAS。ATGM336H可以快速获取卫星信号,提供高达10Hz的位置刷新速率,并能在较弱的GPS信号环境下保持高精度。 ATGM336H小巧轻便,易于安装和集成,适用于各种应用场景,包括车辆定位、智能导航、无人机导航等。它还具有设备保护功能,如过载保护、ESD保护等,能够保护设备免受电气压力和电磁干扰的影响。此外,ATGM336H还配备了一个非易失性存储器,可记录设备的操作历史记录和配置信息,方便用户对设备进行管理和维护。 总之,ATGM336H是一款高性能、高精度的GPS模块,具有卓越的性能和可靠性,并适用于各种导航应用场景。

单片机gps定位模块,嵌入式外设集,单片机,嵌入式硬件,gps定位,c语言,嵌入式外设

欢迎关注微信公众号星之援工作室,公众号不定时开源设计项目

支持单片机,Android系统设计成品定制,项目代做

请联系微信:13648103287

关注微信公众号--星之援工作室 发送关键字(ATGM336H)

➡️🫡🫡🫡🫡🫡🫡🫡🫡➡️

单片机gps定位模块,嵌入式外设集,单片机,嵌入式硬件,gps定位,c语言,嵌入式外设

 使用的注意事项

1.GPS模块首次上电的时候需要获取卫星的定位信息,需要在开阔地带进行程中不难断电,获取成功后我们的GPS模块上的LED会处于闪烁的状态获取,这个获取定位信息的过程大概在1-2分钟

2.GPS模块的串口波特率为9600

3.GPS模块需要稳定的的5V电源,需要注意我们的供电部分是否达到要求。

单片机gps定位模块,嵌入式外设集,单片机,嵌入式硬件,gps定位,c语言,嵌入式外设

单片机gps定位模块,嵌入式外设集,单片机,嵌入式硬件,gps定位,c语言,嵌入式外设

 二、如何移植

1.首先GSP是使用的串口通信,我们第一步需要先配置我们单片机的串口,并将我们的串口波特率配置为9600,这里我自己使用的是串口2进行获取的,代码如下

usart2.c

#include "delay.h"
#include "usart2.h"
#include "stdarg.h"	 	 
#include "stdio.h"	 	 
#include "string.h"	 

char rxdatabufer;
u16 point1 = 0;

_SaveData Save_Data;

#if EN_USART2_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误   	
char USART_RX2_BUF[USART2_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART2_RX_STA=0;       //接收状态标记	  
  
void Usart2_Init(u32 bound)
{
   
	NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	// GPIOB时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); //串口3时钟使能

 	USART_DeInit(USART2);  //复位串口3
		 //USART3_TX   PB10
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PB10
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PB10
   
    //USART3_RX	  PB11
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PB11
	
	USART_InitStructure.USART_BaudRate = bound;//波特率一般设置为9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
  
	USART_Init(USART2, &USART_InitStructure); //初始化串口	3
  

	USART_Cmd(USART2, ENABLE);                    //使能串口 
	
	//使能接收中断
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启中断   
	
	//设置中断优先级
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器


	CLR_Buf();//清空缓存
}

void USART2_IRQHandler(void)                	//串口1中断服务程序
{
	u8 Res;
#ifdef OS_TICKS_PER_SEC	 	//如果时钟节拍数定义了,说明要使用ucosII了.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) 
	{
		Res =USART_ReceiveData(USART2);//(USART1->DR);	//读取接收到的数据
	
	if(Res == '$')
	{
		point1 = 0;	
	}
		

	  USART_RX2_BUF[point1++] = Res;

	if(USART_RX2_BUF[0] == '$' && USART_RX2_BUF[4] == 'M' && USART_RX2_BUF[5] == 'C')			//确定是否收到"GPRMC/GNRMC"这一帧数据
	{
		if(Res == '\n')									   
		{
			memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length);      //清空
			memcpy(Save_Data.GPS_Buffer, USART_RX2_BUF, point1); 	//保存数据
			Save_Data.isGetData = true;
			point1 = 0;
			memset(USART_RX2_BUF, 0, USART2_REC_LEN);      //清空				
		}	
				
	}
	
	if(point1 >= USART2_REC_LEN)
	{
		point1 = USART2_REC_LEN;
	}	  		 
   } 
#ifdef OS_TICKS_PER_SEC	 	//如果时钟节拍数定义了,说明要使用ucosII了.
	OSIntExit();  											 
#endif
}


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

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

void clrStruct()
{
	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);
	
}

#endif	

 




usart2.h

#ifndef __USART2_H
#define __USART2_H
#include "stdio.h"	
#include "sys.h"
#include "string.h"


//V1.5修改说明
//1,增加了对UCOSII的支持
#define USART2_REC_LEN  			200  	//定义最大接收字节数 200
#define EN_USART2_RX 			1		//使能(1)/禁止(0)串口1接收
	  	
extern char  USART_RX2_BUF[USART2_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16 USART2_RX_STA;         		//接收状态标记	



#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;




void Usart2_Init(u32 bound);
extern char rxdatabufer;
extern u16 point1;
extern _SaveData Save_Data;

void CLR_Buf(void);
u8 Hand(char *a);
void clrStruct(void);
#endif



2.移植程序中的主要代码,我直接将我移植好的代码展示在这里,可以直接放到我们的点c文件里面进行获取显示即可

获取以及解析经纬度

void errorLog(U8 num)
{
	while (1)
	{
		printf("ERROR%d\r\n", num);
	}
}
// 获取GPS定位信息
void parseGpsBuffer()
{
	char *subString;
	char *subStringNext;
	char i = 0;
	char usefullBuffer[2];
	if (Save_Data.isGetData)
	{
		Save_Data.isGetData = false;
		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)
				{
					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); // 解析错误
				}
			}
		}
	}
}
F32 longitude_sum, latitude_sum;
U8 longitude_int, latitude_int;
void printGpsBuffer()
{
	// 转化为数字
	longitude_sum = atof(Save_Data.longitude);
	latitude_sum = atof(Save_Data.latitude);
	// printf("维度 = %.5f %.5f\r\n",longitude_sum,latitude_sum);
	// 整数
	longitude_int = longitude_sum / 100;
	latitude_int = latitude_sum / 100;

	// 转化为经纬度
	longitude_sum = longitude_int + ((longitude_sum / 100 - longitude_int) * 100) / 60;
	latitude_sum = latitude_int + ((latitude_sum / 100 - latitude_int) * 100) / 60;

	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("经度 = %s\r\n",Save_Data.longitude);
			// printf("经度 = %.5f\r\n", longitude_sum);
			// printf("维度 = %s\r\n",Save_Data.latitude);
			// printf("纬度 = %.5f\r\n", latitude_sum);
		}
		else
		{
			// printf("GPS DATA is not usefull!\r\n");
		}
	}
}
// 获取数据参数
void Read_Data()
{
	// 经纬度获取
	parseGpsBuffer();
	// 解析经纬度
	printGpsBuffer();

}

3.前两步做完之后就可以使用我们的显示屏或者使用串口进行打印出来了,这样就可以获取我们所在区域的大概经纬度,最后可以再通过平台进行经纬度定位就行啦

显示经纬度

单片机gps定位模块,嵌入式外设集,单片机,嵌入式硬件,gps定位,c语言,嵌入式外设

三、参考

STM32——定位模块ATGM336H,数据解析,提取经纬度https://blog.csdn.net/qq_51963665/article/details/125892763?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170202503816800186588658%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=170202503816800186588658&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-2-125892763-null-null.nonecase&utm_term=ATGM336H&spm=1018.2226.3001.4450

⚠️⚠️END⚠️⚠️文章来源地址https://www.toymoban.com/news/detail-713904.html

到了这里,关于嵌入式外设集 -- GPS定位模块(ATGM336H)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式开发——DMA外设到内存

    加强理解DMA数据传输过程 加强掌握DMA的初始化流程 掌握DMA数据表查询 理解源和目标的配置 理解数据传输特点 能够动态配置源数据 需求 实现串口的数据接收,要求采用dma的方式。 数据交互流程 CPU配置好DMA 外部数据发送给串口外设 串口外设触发中断 CPU处理中断逻辑,通知

    2024年02月03日
    浏览(55)
  • STM32声源定位:实现声源定位的嵌入式解决方案

    声源定位是一项重要的技术,可以帮助我们确定声音的来源位置。在嵌入式系统中,使用STM32微控制器可以实现精确的声源定位。本文将介绍如何使用STM32实现声源定位,并提供相关的源代码。 声源定位的基本原理是通过多个麦克风阵列接收到的声音信号来计算声源的位置。

    2024年04月16日
    浏览(47)
  • 嵌入式学习笔记(17)代码重定位实战 上篇

    3.5.1任务:在iSRAM中将代码从0xd0020010重定位到0xd0024000 注解:本练习对代码本身运行无实际意义,我们做这个重定位纯粹是为了练习重定位技能。但是某些情况重定位就是必须的,譬如在uboot中。 3.5.2思路 (1)通过链接脚本将代码链接到0xd0024000(链接地址) (2)使用dnw下载时将

    2024年02月09日
    浏览(42)
  • 架构-嵌入式模块

    约三分,主要为选择题 冯诺依曼体系结构 程序和数据共用一个存储空间 ,程序指令和数据存放在同一存储器的不同地址上。 单一的地址及数据总线 ,程序指令和数据的总线宽度相同。 串行执行,在传输上会出现瓶颈 。 哈弗体系结构 程序和数据采用不同的存储空间 ,程序

    2024年02月10日
    浏览(43)
  • 【嵌入式模块】MPU6050

      作为惯性传感器中入门级别的器件,MPU6050凭借它出色的性价比成为一款非常常用的角度姿态传感器,在很多科创项目中被使用。我之前也接触过很多次这个器件,也收集了不少资料,趁此机会总结一下学习笔记。   MPU6050包含3轴陀螺仪和3轴加速度计,其中陀螺仪的主

    2024年01月25日
    浏览(36)
  • 【嵌入式 – GD32开发实战指南(ARM版本)】第2部分 外设篇 - 第3章 温度传感器DS18B20

    DS18B20 是 DALLAS 最新单线数字温度传感器,新的\\\"一线器件\\\"体积更小、适用电压更宽、更经济。Dallas 半导体公司的数字化温度传感器 DS1820 是世界上第一片支持 \\\"一线总线\\\"接口的温度传感器。 DS18B20采用的单总线协议,也就是只需占用主机一个I/O口,无需其他外围电路,直接将

    2024年02月21日
    浏览(50)
  • FANUC机器人动作指令的定位类型FINE和CNT详解 嵌入式

    FANUC机器人动作指令的定位类型FINE和CNT详解 嵌入式 FANUC机器人是一种广泛应用于工业领域的机器人系统,它具有高效、精确的动作控制能力。在FANUC机器人的编程中,有两种常用的定位类型,即FINE和CNT。本文将详细解释这两种定位类型的含义和使用方法,并提供相应的源代码

    2024年01月22日
    浏览(180)
  • 上位机图像处理和嵌入式模块部署(开篇)

    【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】         图像处理是现实生活当中很实用的一门技术。工业上一般采用的是机器视觉,以传统算法和光源控制为主,部分采用了深度学习技术。而生活当中,则主要以二维码识别、人脸识别、

    2024年01月22日
    浏览(52)
  • 【蓝桥杯嵌入式】资源拓展板模块详解——数码管

    目录 一、原理 1.1数码管 1.2 74HC595 二、编码说明 2.1 数码管字模 2.2十六进制数字模编码参考 三、程序设计 3.1 原理图 3.2 逻辑分析 3.3 配置方法和参考代码 3.4 参考例程   1.1数码管   扩展板使用3位5161AS数码管。 5161AS数码管引脚图:     5161AS数码管原理图:     从上图可知,

    2024年02月04日
    浏览(44)
  • 【嵌入式Linux内核驱动】内核模块三要素与验证测试

    内核模块 Linux内核模块是一种可以动态加载和卸载的软件组件,用于扩展Linux操作系统的功能。Linux内核本身只包含了必要的核心功能,而内核模块则允许开发者在运行时向内核添加新的功能、驱动程序或文件系统支持,而无需重新编译整个内核或重新启动系统。 内核模块是

    2024年02月06日
    浏览(64)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包