STM32F4驱动GPS(寄存器版)

2023-05-16

本次使用STM32F4的USART1对GPS模块进行驱动,并且将GPS的时间、经纬度通过串口打印出来。

gps模块
在这里插入图片描述
gps模块与接线图
注意:GPS 模块需放到窗户边/阳台,否则可能收不到 GPS 信号。

1、GPS驱动配置(gps.c)

#include "includes.h"

//定义接收信息结构体变量
struct GPS_Data Save_Data;
/*****************************
函数名:clrStruct
函数参数:无

函数返回值:无
函数功能:清除接收结构体信息
函数描述:
*****************************/ 
void clrStruct(void)
{
	Save_Data.isGetData = false;
	Save_Data.isParseData = false;
	Save_Data.isUsefull = false;
	memset(Save_Data.GPS_Buffer, 0, 200);      //清空
	memset(Save_Data.UTCTime, 0, 20);
	memset(Save_Data.latitude, 0, 20);
	memset(Save_Data.N_S, 0, 2);
	memset(Save_Data.longitude, 0, 20);
	memset(Save_Data.E_W, 0, 2);
	
}
/*****************************
函数名:parseGpsBuffer
函数参数:无

函数返回值:无
函数功能:解析接收结构体信息
函数描述:
*****************************/
void parseGpsBuffer(void)
{
	char *subString=NULL;
	char *subStringNext=NULL;
	char i = 0;
	if (Save_Data.isGetData)
	{
		Save_Data.isGetData = false;//串口中断接收一次。解析一次
//		printf(Save_Data.GPS_Buffer);
    //解析数据信息
		for (i = 0 ; i <= 9 ; 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;	//定位信息是否有效
						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
            			case 7:break;
						case 8:break;
						case 9:memcpy(Save_Data.UTCDay, subString, subStringNext - subString);break;	//获取UTC日期
						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);	//解析错误
				}
			}
		}
	}
}
/*****************************
函数名:printGpsBuffer
函数参数:无

函数返回值:无
函数功能:打印接收的数据信息
函数描述:
*****************************/
void printGpsBuffer(void)
{
	u8 year,month,day,hour,minute,second,week;
	double latitude,longitude;
	if (Save_Data.isParseData)
	{
		Save_Data.isParseData = false;
		//获得时间
		hour =(Save_Data.UTCTime[0]-'0')*10+(Save_Data.UTCTime[1]-'0')+8;
		minute =(Save_Data.UTCTime[2]-'0')*10 +(Save_Data.UTCTime[3]-'0');
		second =(Save_Data.UTCTime[4]-'0')*10 +(Save_Data.UTCTime[5]-'0');
		if(Save_Data.isUsefull)
		{
			Save_Data.isUsefull = false;
			//获得纬度
			latitude= atof( Save_Data.latitude);
			latitude/=100;
     		//获得经度
			longitude= atof( Save_Data.longitude);
			longitude/=100;
			//获得日期
			year =(Save_Data.UTCDay[4]-'0')*10+(Save_Data.UTCDay[5]-'0');
			month =(Save_Data.UTCDay[2]-'0')*10 +(Save_Data.UTCDay[3]-'0');
			day =(Save_Data.UTCDay[0]-'0')*10 +(Save_Data.UTCDay[1]-'0');
			
			
			printf("当前时间: 20%d-%d-%d %d:%d:%d\r\n",year,month,day,hour,minute,second);
			printf("当前纬度 %s:%f°\r\n",Save_Data.N_S,latitude);
			printf("当前经度 %s:%f°\r\n",Save_Data.E_W,longitude);
		 }
		else
		{
			printf("GPS DATA is not usefull!\r\n");
		}
		
	}
}
void errorLog(int num)
{
	while (1)
	{
	  	printf("ERROR%d\r\n",num);
	}
}

2、GPS函数声明(gps.h)

#ifndef   GPS_H
#define   GPS_H

#include "stm32f4xx.h"


#define false 0
#define true 1

//GPS接收帧格式结构体
struct GPS_Data 
{
	char GPS_Buffer[200];	//整体数据长度
	char isGetData;			//是否获取到GPS数据
	char isParseData;		//是否解析完成
	char UTCTime[20];		//UTC时间
	char latitude[20];		//纬度
	char N_S[2];			//N/S
	char longitude[20];		//经度
	char E_W[2];			//E/W
	char isUsefull;			//定位信息是否有效
	char UTCDay[20];		//UTC日期
};

extern struct GPS_Data Save_Data;
void clrStruct(void);
void errorLog(int num);
void parseGpsBuffer(void);
void printGpsBuffer(void);

#endif

3、串口驱动配置(usart1.c)注意串口中断函数

#include "includes.h"

/*****************************
函数名:USART1_init
函数参数:
int boand : TX/RX 的波特率
函数返回值:无
函数功能:实现开发板对应USART1的发送/接收初始化配置
函数描述:
USART1_TX  :PA9
USART1_RX : PA10
*****************************/
void USART1_init(int boand )
{
	int OVER8 =0 ; 
	float USARTDIV ;//放入波特率寄存器中的数值
	int DIV_Fraction; //表示USARTDIV的小数部分
	int DIV_Mantissa ;//表示USARTDIV的整数部分
	/*****对USART1的TX RX管脚 复用配置******/
	//打开PA的外设时钟
	RCC->AHB1ENR |=(1<<0);
	/******USART1_TX PA9复用功能配置*****/
	//模式寄存器
	GPIOA->MODER &=~(0X3<<18); //清零
	GPIOA->MODER |=(0X2<<18);  //复用功能
	//具体的复用功能配置
	GPIOA->AFR[1] &=~(0XF<<4); //清零
	GPIOA->AFR[1] |=(0X7<<4);  //复用成USART1_TX
	
	/******USART1_RX PA10复用功能配置*****/
	//模式寄存器
	GPIOA->MODER &=~(0X3<<20); //清零
	GPIOA->MODER |=(0X2<<20);  //复用功能
	//具体的复用功能配置
	GPIOA->AFR[1] &=~(0XF<<8); //清零
	GPIOA->AFR[1] |=(0X7<<8);  //复用成USART1_RX
	
	/******USART1的发送/接收控制功能配置****/
	//打开USART1的外设时钟
	RCC->APB2ENR |=(1<<4);
	//串口工作使能
	USART1->CR1 |=(1<<13);
	//禁止奇偶校验
	USART1->CR1 &=~(1<<10);
	//发送器使能
	USART1->CR1 |=(1<<3);
	//接收器使能
	USART1->CR1 |=(1<<2);
	//不发送断路字符
	USART1->CR1 &=~(1<<0);
#ifdef   MY_OVER8  //16倍
   USART1->CR1 &=~(1<<15);
	 OVER8 =0;
#else    //8倍
   USART1->CR1 |=(1<<15);
	 OVER8 =1;
#endif


	/*****TX/RX的波特率配置*****/
	USARTDIV =(float)84000000/(8*(2-OVER8)*boand);
	DIV_Mantissa =USARTDIV;
  DIV_Fraction =(USARTDIV-DIV_Mantissa)*8*(2-OVER8);
	USART1->BRR = DIV_Mantissa<<4 | DIV_Fraction;
	
	
	/*******接收中断相关配置 *******/
	//接收中断使能
	USART1->CR1 |=(1<<5);
	//USART1 NVIC中断配置 分组值: 7-2  
  MY_NVIC_init(7-2,1,1,USART1_IRQn);
}

/*****************************
函数名:USART1_Sendbyte
函数参数:
u8 data :要发送的数据
函数返回值:无
函数功能:实现串口1发送一个字节数据
函数描述:
*****************************/
void USART1_Sendbyte(u8 data)
{
	 //等待上次数据发送完
	 while((USART1->SR &(1<<6))==0)
	 {
		 ;
	 }
	 //发送该次数据
	 USART1->DR =data;
}

/*****************************
函数名:USART1_Sendstring
函数参数:
u8  *buf : 字符指针,
     表示要发送字符串的首地址
函数返回值:无
函数功能:实现串口1发送一个字符串
函数描述:
*****************************/
void USART1_Sendstring(u8 *buf)
{
	 while(*buf !='\0')
	 {
		  USART1_Sendbyte(*buf);
		  buf++;
	 }
	 USART1_Sendbyte('\r');
	 USART1_Sendbyte('\n');
}

/*****************************
函数名:USART1_Receivebyte
函数参数:无

函数返回值:u8 data :接收到的数据
函数功能:实现串口1接收一个字节数据
函数描述:
*****************************/
u8 USART1_Receivebyte(void)
{
	 u8 data;
	 //等待接收到数据
	 while((USART1->SR &(1<<5))==0)
	 {
		 ;
	 }
	//读出接收到的数据
	data =USART1->DR;
	//把接收到的数据返回出去
	return data;	
}

/*****************************
函数名:USART1_Receivestring
函数参数:u8 *buf :接收到的数据

函数返回值:无
函数功能:实现串口1接收一个字符串
函数描述:
用户自定义结束标志
*****************************/  
void USART1_Receivestring(u8 *buf)
{
	 u8 ch; 
	 while(1)
	 {
		  ch =USART1_Receivebyte();
		 //判断接收到的是否是结束标志
		 if(ch ==' ' || ch =='\r' || ch=='\n')
		 {
			 break;
		 }
		 *buf =ch;
		 buf++;
	 }
	 *buf ='\0';//添加一个结束标志 
}

#pragma import(__use_no_semihosting_swi) //取消半主机状态

struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;

int fputc(int ch, FILE *f) {
	USART1_Sendbyte(ch);
  return (ch);
}
int ferror(FILE *f) {
  /* Your implementation of ferror */
  return EOF;
}

void _ttywrch(int ch) {
  USART1_Sendbyte(ch);
}


u16 point1 = 0;
char USART_RX_BUF[200];     //接收缓冲,
//中断服务函数
void USART1_IRQHandler(void)
{
	 u8 Res;
	 Res =USART1->DR;	//读取接收到的数据
	if(Res == '$') 		//重新开始接收数据
	{
		point1 = 0;	
	}
  USART_RX_BUF[point1++] = Res;
	//确定是否收到"GPRMC"这一帧数据
	if(USART_RX_BUF[0] == '$' && USART_RX_BUF[4] == 'M' && USART_RX_BUF[5] == 'C')			
	{
		if(Res == '\n')	//接收到该帧	数据的最后一个						   
		{
			memset(Save_Data.GPS_Buffer, 0, 100);      				//清空
			memcpy(Save_Data.GPS_Buffer, USART_RX_BUF, point1); 	//保存数据
			Save_Data.isGetData = true;
			point1 = 0;
			memset(USART_RX_BUF, 0, 200);     						 //清空				
		}					
	}	
	if(point1 >= 200)
	{
		point1 = 200;
	}	
}

4、串口函数声明(usart1.h)

#ifndef   USART1_H
#define   USART1_H

#include "stm32f4xx.h"
//如果采用16倍过采样,定义该宏
//如果采用8倍过采样,屏蔽冠宏
#define MY_OVER8

void USART1_init(int boand );
void USART1_Sendbyte(u8 data);
void USART1_Sendstring(u8 *buf);
u8 USART1_Receivebyte(void);
void USART1_Receivestring(u8 *buf);
#endif

5、主函数(main.c)

#include "includes.h"

int main()
{ 
  	//串口初始化
	USART1_init(9600);
	//清除接受结构体信息
	clrStruct();
	while(1)
	{
		//解析数据
		parseGpsBuffer();
		//打印数据
		printGpsBuffer();
	}
	return 0;
}

整个程序代码与使用手册上传至:https://download.csdn.net/download/qq_37619128/84225570

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

STM32F4驱动GPS(寄存器版) 的相关文章

  • Cartographer(二)使用思岚rplidar雷达进行cartographer建图

    一 修改launch文件和lua配置文件 xff08 1 xff09 修改revo lds lua 到目录下 xff0c 打开文件 home meng xx catographer ws src cartographer ros carto
  • 数字电路硬件设计系列(三)之缓启电路设计

    针对设计过程中的问题 xff0c 如有疑问 xff0c 欢迎留言评论 xff01 点我返回目录 1 简介 在一些大电压 大电流的产品中 xff0c 上电的瞬间通常会有较大的电流冲击 xff0c 下图是一款产品上电过程中波形 最大的电流达到1
  • 数字电路硬件设计系列(十)之RS485电路设计

    针对设计过程中的问题 xff0c 如有疑问 xff0c 欢迎留言评论 xff01 点我返回目录 1 简介 RS485通信属于串口通信中的半双工通信 xff0c RS485具有支持多节点 xff08 32个节点 xff09 传输距离远 xff
  • 数字电路硬件设计系列(五)之AT89C51/C52最小系统设计

    针对设计过程中的问题 xff0c 如有疑问 xff0c 欢迎留言评论 xff01 点我返回目录 1 简介 AT89C51 C52是指两个系列的产品 xff0c 具体包含AT89C51 AT89C52 xff0c 但是最小系统的组成基本上相差
  • 1.18 接地设计问题(非常实用)

    目录 1 简介 2 接地的分类 3 接地的目的 3 1 对地阻抗低 3 2 地平面稳定 3 3 对地均衡 4 共地耦合干扰 5 常用的基地方式 6 安全地 防雷击浪涌接地的接法 1 简介 在电路设计的过程中 xff0c 接地是一个老生常谈的
  • 1.0 硬件设计基础(面试题)

    1 滤波磁珠和滤波电感的区别 磁珠由导线穿过铁氧体组成 xff0c 直流电阻很小 xff0c 在低频时阻抗也很小 xff0c 对直流信号几乎没有影响 在高频 xff08 几十兆赫兹以上 xff09 时磁珠阻抗比较大 xff0c 高频电磁场在
  • 1.19 旁路电容与去耦电容

    1 简介 旁路电容和旁路电容是电路设计过程中十分常见 xff0c 但是很多应将工程师都没有真正区分这两者的功能 xff0c 我们先来看看这两个单词在英文中的意思 xff1a 电容英文中文解释旁路电容Bypass抄近道去耦电容couple是一
  • vins运行1

    vins fusion 运行笔记 安装code utils 1 fatal error elfutils libdw h 没有那个文件或目录 没有安装 sudo apt get install libdw dev 2 fatal error
  • 四旋翼无人机汇报

    我主要负责的是四旋翼无人机的组装和飞控参数的调试 遇到的问题 当初焊接时由于时间紧张用的是比较细的焊条 xff0c 虽然焊接成功 xff0c 但是导致了后续插拔导线时容易接触不良 xff0c 后来在焊点处重新焊接 由于未在地面站软件中修改无
  • 载波相位差分定位

    x1f30e 我接触差分定位是通过暑期在南京北斗一段时间的实习 x1f30e 我把 Lambda算法的zip和rar上传到了这里 x1f30e https wwi lanzoui com b01bp70yj x1f30e 再推荐一个gith
  • nRF SPI 与 TWI 操作相关 (BMI088 与 MLX90614 举例)

    SPI0 与 TWI0 的 ID相同 xff0c SPI0 与 TWI0 的 ID相同 编译时有报错 若要避免 xff0c 有两个方法 1 使用不同ID外设 2 使用模拟SPI或模拟IIC nRF SPI 初始化 sdk config h
  • ros(13):ros找不到包报错及解决办法--Config.cmake

    目录 一 基础包 1 1 rospy包 1 2 tf包 1 3 grid map包 1 4 serial 二 专有包 2 1 dynamic reconfigure包 2 2 rosparam handler包 2 3 qt build包
  • stm32 esp8266 ota升级-自建mqtt和文件服务器动态AB面升级

    stm32 esp8266 ota系列文章 xff1a stm32 esp8266 ota 快速搭建web服务器之docker安装openresty stm32 esp8266 ota升级 tcp模拟http stm32 esp8266 o
  • win系统C++的udp通信(接收并发送)详细教程、win下inet_pton和inet_ntop无法使用解决方法

    对UDP编程0基础的可以参考这篇记录博文 我做的是同一个程序中接收指定IP地址和端口号的信息作为输入 xff0c 通过程序的算法进行处理 xff0c 处理后的信息再通过另一个指定IP地址和端口号进行发送 也就是需要做两个udp一个接收数据
  • postman下载与汉化(附直接下载链接)

    想用英文版本的可以直接点击如下链接下载最新版本 官网最新版本 无法汉化 xff1a Download Postman Get Started for Free 如果想要汉化的就不能使用最新版本 xff0c 因为最新版本没有汉化包可以用 汉化
  • Qt 自定义流程图 diagram

    Qt 自定义流程图 diagram 前言程序执行效果程序源码下载图形视图框架成员介绍重写QGraphicsItem程序源码介绍重点代码 前言 本文将对QGraphicsScene QGraphicsView QGraphicsItem这三个
  • 用C语言实现简单的HTTP数据请求

    我的博客 xff1a https blog csdn net qq 37388044我的知乎 xff1a https www zhihu com people bbtganmin联系方式 xff1a 知乎私信 转载或者引用本文内容请注明来源
  • rosserial移植到STM32(CUBEMX+HAL库)

    使用cubemx 43 HAL库将rosserial移植到STM32 rosserial的作用需要实现的功能移植步骤我创建的工程没有积分的可以到github下载 rosserial的作用 使用过ros的话都会了解过ros特殊的通信机制 xf
  • STM32基础(10)串口重定向

    原理 C 语言中 printf 函数默认输出设备是显示器 xff0c 如果要实现在串口或者 LCD 上显示 xff0c 必须重定义标准库函数里调用的与输出设备相关的函数 重定向 xff1a 重写库函数 xff0c 对原函数进行覆盖 xff0
  • pcl_conversions

    CMake Error at opt ros melodic share catkin cmake catkinConfig cmake 83 find package Could not find a package configurat

随机推荐

  • 在 Ubuntu 上安装 Bazel

    在 Ubuntu 上安装 Bazel 链接 https github com bazelbuild bazel 本页面介绍了在 Ubuntu 上安装 Bazel 的选项 此外 xff0c 它还提供指向 Bazel 完成脚本和二进制安装程序的
  • slam算法有哪些

    1 基于激光雷达的SLAM算法 xff1a Hector SLAM Gmapping Cartographer Karto SLAM Horn SLAM等 xff1b 激光雷达传感器作为主要感知设备来进行SLAM Hector SLAM是一
  • ubuntu(15):对‘casadi::MX::MX(casadi::MX const&)’未定义的引用

    catkin build 编译报错 xff0c 找不到CASADI的头文件目录CASADI INCLUDE DIRS或者库文件也达不到CASADI LIBRARIES xff1b 对 casadi MX horzsplit casadi M
  • Cmake修改FetchContent_Declare为本地代码构建

    在构建代码时 xff0c 某些项目可能需要额外下载第三方库 然而 xff0c 由于网络不稳定 xff0c 克隆过程可能会出现问题 在这种情况下 xff0c 您需要手动修改项目配置 xff0c 将其指向已经下载到本地的库文件 Fetch do
  • OTA开源代码

    有许多开源项目可用于实现 OTA xff08 Over The Air xff09 更新 以下是一些流行的开源 OTA 更新项目 xff0c 您可以根据自己的需求和设备类型选择合适的项目 xff1a Mender xff08 适用于嵌入式
  • 摄像头接口标准

    UVC xff08 USB Video Class xff09 xff1a UVC是一种通用的USB摄像头接口标准 xff0c 使得摄像头设备能够与各种操作系统兼容 xff0c 实现即插即用的功能 CSI xff08 Camera Seri
  • win10安装Anaconda、cuda9.0、cudnn、tensorflow-gpu=1.12.0详细步骤

    最近刚想起写自己的博客 xff0c 每天遇到了问题都会阅览博客 xff0c 也想把自己遇到了的一些问题写成文章给博友们参考 xff0c 所以我想从最基础的配置环境开始写起 xff0c 如看到问题也请多多指教 准备工作 Anaconda下载地
  • 【SpringSecurity教程】认证 1.Basic认证

    前言 Basic 认证是在请求接口之前要输入账号密码 xff0c 是简单的Http验证模式 本章主要描述 xff1a SpringBoot如何整合Basic认证 后端Okhttp和前端Vue Axios如何请求Basic认证的接口 Spri
  • 【SpringSecurity教程】认证 2.Digest摘要认证

    前言 Digest xff08 摘要 xff09 认证是在请求接口之前要输入账号密码 xff0c 是在Basic认证传输账号密码的基础上加密 SpringBoot整合Digest pom xml span class token tag s
  • VIM3刷系统

    一 升级到最新系统 如果你的板子上已经运行的是官方发布的Ubuntu固件 xff0c 那么你可以通过如下命令升级系统到最新版本 span class token function sudo span span class token fun
  • 设置Chrome页面为黑色

    文章目录 1 设置主题2 设置页面 1 设置主题 设置 gt 外观 gt 主题背景 gt 选择一个黑色的主题 2 设置页面 输入chrome flags enable force dark将其设置为Enable即可
  • 网线每根的含义以及类别和距离传输问题

    文章目录 1 八芯线每根的含义2 传输距离限制3 双绞线的主要分类 1 八芯线每根的含义 网线采用8根线芯 xff0c 主要是为了减少电磁信号的相互干扰 xff0c 只用四根 xff0c 另外四根可做备份使用 每两根按一定的密度缠绞在一起
  • Windows快捷键

    文章目录 1 创建虚拟桌面2 虚拟桌面间切换3 虚拟桌面关闭4 锁住PC5 显示桌面6 从任务栏打开新应用7 两个应用分屏8 应用切换9 打开文件管理视窗10 打开放大镜11 截取屏幕12 打开操作中心13 进入设置14 与Cortana或
  • ubuntu(18):对‘pthread_create’未定义的引用

    报错 xff1a 对 pthread create 未定义的引用 usr local lib libbenchmark a benchmark runner cc o xff1a 在函数 benchmark internal Benchma
  • Git修改与删除commit记录

    Git修改与删除commit记录 修改commit信息删除未push的commit删除已push的commit 修改commit信息 1 修改最近一次commit的信息 git commit span class token operato
  • 电机转矩、功率、转速之间的关系及计算公式

    P 61 W T 61 FS T 61 FV T 61 F R V 61 2 RN N 转速 所以 P 61 FV 61 T R 2 RN 61 2 TN T 61 P 2 n 用千瓦 xff08 KW xff09 和转 分 xff08 r
  • 使用示波器测量串口波特率

    使用示波器测量串口波特率 波特率和bit时间计算关系基础概念基础知识 xff1a 测量结果 波特率和bit时间计算关系 基础概念 简而言之 xff0c 串口传输的波特率即为每秒钟传输二进制的位数 脱离枯燥乏味的文字描述 xff0c 我们用波
  • 雷达基本原理和组成

    雷达由天线辐射电磁波 xff0c 并通过天线接收目标反射回的电磁波 目标回波 xff0c 然后通过接收机和信号处理机从目标回波中提取信息 提取的目标信息主要包括距离 方位 俯仰和速度等 雷达系统的主要组成如图所示 xff0c 主要由发射机
  • 雷达坐标转换

    function r azimuth elevation flag AE r a etrue flag AE Truenum coordinate conversion XYZ t Angle Az Angle El 1 a 雷达直角坐标系
  • STM32F4驱动GPS(寄存器版)

    本次使用STM32F4的USART1对GPS模块进行驱动 xff0c 并且将GPS的时间 经纬度通过串口打印出来 gps模块与接线图 注意 xff1a GPS 模块需放到窗户边 阳台 xff0c 否则可能收不到 GPS 信号 1 GPS驱动