基于STM32的GPS模块驱动(AIR530)

一、概述

         由于做项目要用到GPS定位,于是在某宝购买了这款GPS模块。项目采用的MCU是STM32。废话少说,进入正题。

二、GPS模块简介

        Air530 模块是一款高性能、高集成度的多模卫星定位导航模块。体积小、功耗低,可用于车载导 航、智能穿戴、无人机等 GNSS 定位的应用中。而且提供了和其他模块厂商兼容的软、硬件接口,大幅 减少了用户的开发周期。 模块支持GPS/Beidou/GLONASS/Galileo/QZSS/SBAS。采用了射频基带一体化设计,集成了 DC/DC、 LDO、 LNA、射频前端、基带处理、32 位 RISC CPU、RAM、FLASH 存储、RTC 和电源管理等功能。提供 超高的性能,即使在弱信号的地方,也能快速、准确的定位。

这个模块有五个引脚。如果只是简单的定位玩一下的话,那个1pps引脚不用也可以。

 VDD       供电电源,电压输入 范围 3.3V-5.5V

 TXD       GPS 串口数据输出, 2.8V--5V 自适应

RXD       GPS 串口数据输入, 2.8V--5V 自适应

1PPS      One plus per second(2.8V)

GND      接地

三、STM32驱动程序编写

 1.NMEA协议

       在编写驱动程序前一定要知道NMEA协议。NMEA是(National Marine Electronics Association )为海用电子设备制定的标准格式。NMEA缩写,同时也是数据传输标准工业协会,在这里,实际上应为NMEA 0183。它是一套定义接收机输出的标准信息,有几种不同的格式,每种都是独立相关的ASCII格式,逗点隔开数据流,数据流长度从30-100字符不等,通常以每秒间隔选择输出,最常用的格式为"GGA",它包含了定位时间,纬度,经度,高度,定位所用的卫星数,DOP值,差分状态和校正时段等,其他的有速度,跟踪,日期等。NMEA实际上已成为所有的GPS接收机和最通用的数据输出格式,同时它也被用于与GPS接收机接口的大多数的软件包里。NMEA-0183协议定义的语句非常多,但是常用的或者说兼容性最广的语句只有$GPGGA、$GPGSA、$GPGSV、$GPRMC、$GPVTG、$GPGLL等。

       AIR530 模块支持 NMEA 0183 V4.1 协议并兼容以前版本,关于 NMEA 0183 V4.1 的详细信息请参照 NMEA 0183 V4.1 官方文档。

        GGA:时间、位置、卫星数量

        GLL:经度、纬度、 UTC 时间

        GSA:GPS 接收机操作模式,定位使用的卫星,DOP 值,定位状态

        GSV:可见 GPS 卫星信息、仰角、方位角、信噪比

        RMC:时间、日期、位置、速度 VTG:地面速度信息

 2.驱动开发

gps头文件

/*****************************************************
消息 :$GPRMC,100646.000,A,3109.9704,N,12123.4219,E,0.257,335.62,291216,,,A*59
ID :            $GPRMC RMC                  协议头
UTC时间:         100646.000                  hhmmss.sss
状态:            A                           A=数据有效;V=数据无效
纬度 :           2109.9704                   ddmm.mmmm
N/S:              N                          N=北,S=南
经度:           11123.4219                   dddmm.mmmm
E/W :             E                          W=西,E=东
地面速度:        0.257                        Knot(节)
方位:           335.62                        度
日期            291216                        ddmmyy
磁变量           无
校验和           *59
<CR><LF>                                     消息结束
******************************************************/
#ifndef __GPS__H
#define __GPS__H
#include "sys.h"
#include "usart.h"
#include "stdint.h"
#include "string.h"
#include "stdlib.h"
//启动命令

#define  HotStart     "$PGKC030,1,1*2C\r\n"      //Gps系统热启动
#define  WarmStart    "$PGKC030,2,1*2F\r\n"      //Gps系统温启动
#define  ColdStart    "$PGKC030,3,1*2E\r\n"      //Gps系统冷启动
#define  ReColdStart  "$PGKC030,4,1*29\r\n"      //Gps系统重置冷启动

// 卫星定位模式设置
#define  SingleGps    "$PGKC115,1,0,0,0*2B\r\n"      //单 GPS
#define  GPSandBEIDOU   "$PGKC115,1,0,1,0*2A\r\n"      //GPS+BEIDOU
#define  GPSandGLONASS  "$PGKC115,1,1,0,0*2A\r\n"      //GPS+GLONASS

// 低功耗模式设置       
#define  LPsleep  "$PGKC051,1*36\r\n"    //  sleep 模式     
#define  LPstop   "$PGKC051,0*37\r\n"    //  stop 模式 

/******************************************
//配置输出 NMEA 消息的间隔(ms 单位)  
Arg1: 200-10000
******************************************/
#define  delay1sNMEA  "$PGKC101,1000*02\r\n" // 间隔1ms


/******************************************
//开启或关闭 QZSS NMEA格式输出  
Arg1: “0”,关闭
      “1”,开启
******************************************/
#define  OpenNMEA    "$PGKC113,1*31\r\n"
#define  CloseNMEA   "$PGKC113,0*30\r\n"


//设置 NMEA 输出波特率
#define  SetBps115200   "$PGKC147,115200*06\r\n"
//加速定位信息
#define  MoreFast   "$PGKC639,34.093145,108.542323,0,2019,05,04,02,43,54*05\r\n"

/*******************************************
设置 NMEA 语句输出使能
Arg1: GLL “0”,关闭; “1”,打开
Arg2: RMC “0”,关闭; “1”,打开
Arg3: VTG “0”,关闭; “1”,打开
Arg4: GGA “0”,关闭; “1”,打开
Arg5: GSA “0”,关闭; “1”,打开
Arg6: GSV “0”,关闭; “1”,打开
Arg7: GRS “0”,关闭; “1”,打开
Arg8: GST “0”,关闭; “1”,打开
Arg9~ Arg19: 保留
*******************************************/
#define  EnableRMC   "$PGKC242,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*36\r\n"


//擦除 flash 中的辅助定位数据
#define  DeleteFlash   "$PGKC040*2B\r\n"


//开启或关闭 SBAS 功能
#define  CloseSBAS   "$PGKC239,1*3A\r\n"//关闭SBAS 功能
#define  OpenSBAS   "$PGKC239,0*3B\r\n"//开启SBAS 功能

//RMC_DATA结构体
typedef struct RMC_DATA{
	char    time[12];  //UTC时间
	char    state[12]; //状态 
  char	  lat[12];  //纬度
	char    NS[2];    //N/S指示
	char    WE[2];     //W/E指示
	char	  lng[12];  //经度
	char    date[12];  //日期
}rmc_data;
//错误信息上传数据帧
typedef struct WARNING{
	char start;//帧头
	u8 WarningFlag;//从最低位到最高为分别表示:电池电量警告,GPS定位失败警告,电子围栏越界警告,跌倒警告,其他暂时预留。
	 char end;//结束标志
}Warning;
//定位信息上传数据帧
typedef struct OPSITIONDATA{
  char    start;
	char    time[12];  //UTC时间
	char    state[12]; //状态 
  char	  lat[12];  //纬度
	char    NS[2];    //N/S指示
	char	  lng[12];  //经度	
	char    WE[2];     //W/E指示
	char    date[12];  //日期
  char     end;
}OpsitionData;
//心率信息上传数据帧
typedef struct HEARTRATEDATA{
	char start;
  u8   HeartRate;//心率次数
	 char end;
}HeartRateData;

extern rmc_data  RecRMC; 
extern rmc_data * const pRecRMC; //RMC解析输出缓存区,该指针指向固定的地址
void SendAtToGps(u8 *cmd);
u8   GpsAckChack(u8 *str);
void Gps_Init(void);
void AnalysisRMC(rmc_data *pRecRMC);
void GpsRMCdataShow(void);
u8 OverStepArea(rmc_data *pRecRMC);
void mixGpsdate(char * ULdate,rmc_data *pRecRMC);
#endif

GPS驱动函数

#include "gps.h"
/*************************************
功能:发送数据到Gps模块
作者:贺远
日期:2019.03.05
参数:cmd  AT命令
返回值:无
**************************************/
void SendAtToGps(u8 *cmd)
{
	while(*cmd!='\0')
	{
	 USART_SendData(USART1,*cmd++);
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==Bit_RESET);	//发送数据结束
	}
}
/*************************************
功能://检查GPS模块应答是否符合预期
作者:贺远
日期:2019.03.05
参数:str  正确的应答
返回值:无
**************************************/
u8 GpsAckChack(u8 *str)
{
		//u8 str[225];
	  delay_ms(500);
		if(USART1_RX_STA!=0)
		{
			 USART1_RX_STA=0;
			   
			 if(strstr((const char*)USART1_RX_BUF,(const char*)str)) { memset(USART1_RX_BUF,0, sizeof USART1_RX_BUF);        return 0;}//符合预期
			 else                                                    { memset(USART1_RX_BUF,0, sizeof USART1_RX_BUF);     return 1;}//不符合预期      
                                //清空数组  			
		} 
		else { memset(USART1_RX_BUF,0, sizeof USART1_RX_BUF);   return  1;}
}
/*************************************
功能:Gps模块初始化
作者:贺远
日期:2019.03.05
参数:无
返回值:无
**************************************/
void Gps_Init()
{
	cmd1:SendAtToGps(ColdStart);   //GPS冷启动
       delay_ms(50);	
	     if (!GpsAckChack("$PGKC001,30,3*1E"))  ; 
	     else goto  cmd1;
	cmd2:SendAtToGps(GPSandBEIDOU);//GPS+BEIDOU
       delay_ms(50);	
	     if (!GpsAckChack("$PGKC001,115,3,1,0,0,0,1,49*15"))  ; 
	     else goto  cmd2;

	cmd3:SendAtToGps(OpenSBAS);    //开启SBAS 功能
	     delay_ms(50);	
			 if (!GpsAckChack("$PGKC001,239,3*25"))  ; 
	     else goto  cmd3;
	cmd4:SendAtToGps(delay1sNMEA); //配置输出 NMEA 消息的间隔 1s
       delay_ms(50);	
	     if (!GpsAckChack("$PGKC001,101,3*2D"))  ; 
	     else goto  cmd4;
	cmd5:SendAtToGps(EnableRMC);   //设置 NMEA 语句输出使能  使能RMC
       delay_ms(50);	
	     if (!GpsAckChack("$PGKC001,242,3*29"))  ; 
	     else goto  cmd5;
       
			 SendAtToGps(MoreFast);//加速定位信息


}
rmc_data  RecRMC; 
rmc_data * const pRecRMC=&RecRMC; //RMC解析输出缓存区,该指针指向固定的地址
/*************************************
功能:GPSRMC数据解析
作者:贺远
日期:2019.03.09
参数:无
返回值:无
**************************************/
void AnalysisRMC(rmc_data *pRecRMC)//GPSRMC数据解析
{
	int i,n=0;
	if(USART1_RX_STA!=0)
		{
			 USART1_RX_STA=0;
			 for(i=0;USART1_RX_BUF[i]!='\0';i++)
			 {
				 if(USART1_RX_BUF[i]==',')  
				 {
					 n++;
					 i++;// 跳过 “,”
				 //strncpy(sub, string+12,13);   将string从string[12]开始,截取13个复制到sub中
				 if(n==1)  { strncpy(pRecRMC->time,  USART1_RX_BUF+i,10); 	i=i+9; }//i=i+10;目的是为了减少循环次数,提高效率
				 if(n==2)  { strncpy(pRecRMC->state, USART1_RX_BUF+i,1);           }
				 if(n==3)  { strncpy(pRecRMC->lat,   USART1_RX_BUF+i,9);    i=i+8; }  
				 if(n==4)  { strncpy(pRecRMC->NS,    USART1_RX_BUF+i,1); 				   }
				 if(n==5)  { strncpy(pRecRMC->lng,   USART1_RX_BUF+i,10);   i=i+9; }
				 if(n==6)  { strncpy(pRecRMC->WE,    USART1_RX_BUF+i,1);           }
				 if(n==9)  { strncpy(pRecRMC->date,  USART1_RX_BUF+i,6);    i=i+5; }
			  }
			 }
		 }
    memset(USART1_RX_BUF,0, sizeof USART1_RX_BUF);    //清空接收缓存区 			
	
	
}
/*************************************
功能:GPS解析数据显示
作者:贺远
日期:2019.03.09
参数:无
返回值:无
**************************************/

//void GpsRMCdataShow()

//{
//delay_ms(400);	
//		 AnalysisRMC(pRecRMC);
//		
//		 LCD_ShowString(10,70,250,16,16,"UTC  :");
//		 LCD_ShowString(60,70,250,16,16, (u8*)pRecRMC->time);
//		
//		 LCD_ShowString(10,90,250,16,16,"state:");
//		 LCD_ShowString(60,90,250,16,16,(u8*)pRecRMC->state);
//		
//		 LCD_ShowString(10,110,250,16,16,"lat  :");
//		 LCD_ShowString(60,110,250,16,16,(u8*)pRecRMC->lat);
//		 LCD_ShowString(150,110,250,16,16,(u8*)pRecRMC->NS);
//		
//		 LCD_ShowString(10,130,250,16,16,"lng  :");
//		 LCD_ShowString(60,130,250,16,16,(u8*)pRecRMC->lng);
//		 LCD_ShowString(150,130,250,16,16,(u8*)pRecRMC->WE);
//		
// 	   LCD_ShowString(10,150,250,16,16,"date :");
//	   LCD_ShowString(60,150,250,16,16,(u8*)pRecRMC->date);
//		 memset(pRecRMC,0, sizeof pRecRMC);    //清空接收缓存区 	
//}
/*************************************
功能:GPS电子围栏超出检测
作者:贺远
日期:2019.03.10
参数:无
返回值:0/1
**************************************/
u8 OverStepArea(rmc_data *pRecRMC)
{
	float a,b,c,a1=3415.2645,b1=10925.2235,c1;
	a=atof(pRecRMC->lat); //字符串转float
	b=atof(pRecRMC->lng);
	c=(a-a1)*(a-a1)+(b-b1)*(b-b1);
	c1=0.5555*0.5555+0.6666*0.6666;//圆形区域
  if(c1>=c) return 0;//未越界
	else return 1;
}
/*************************************
功能:GPS定位信息上传数据组帧
作者:贺远
日期:2019.03.10
参数:无
返回值:无
说明:char *strcat(char *dest, const char *src);
      strcat() 会将参数 src 字符串复制到参数 dest 所指的字符串尾部;
      dest 最后的结束字符 NULL 会被覆盖掉,并在连接后的字符串的尾部再增加一个 NULL。
**************************************/
void mixGpsdate(char * ULGpsdate,rmc_data *pRecRMC)
{
	ULGpsdate=strcat(ULGpsdate,pRecRMC->date);
	ULGpsdate=strcat(ULGpsdate,pRecRMC->time);
	ULGpsdate=strcat(ULGpsdate,pRecRMC->state);
	ULGpsdate=strcat(ULGpsdate,pRecRMC->lat);
	ULGpsdate=strcat(ULGpsdate,pRecRMC->NS);
	ULGpsdate=strcat(ULGpsdate,pRecRMC->lng);
	ULGpsdate=strcat(ULGpsdate,pRecRMC->WE);
	
}







 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 25
    点赞
  • 283
    收藏
    觉得还不错? 一键收藏
  • 20
    评论
STM32是一种微控制器芯片系列,适用于各种应用领域和项目。GPS模块是一种用于接收全球定位系统信号的设备。 编写STM32 GPS模块代码需要进行以下步骤: 1. 建立UART通信:首先,将GPS模块连接到STM32芯片,并创建一个UART通信连接。通过UART通信,可以接收来自GPS模块的数据。 2. 配置UART参数:设置UART的波特率、数据位、停止位和校验位等参数,以确保数据传输的准确性。 3. 接收GPS数据:通过UART接收数据,将GPS模块发送过来的数据存储到缓冲区中。 4. 解析GPS数据:从缓冲区中解析出有用的GPS数据,比如经度、纬度、海拔高度等信息。 5. 处理GPS数据:根据需求,可以对GPS数据进行处理,比如计算两点之间的距离、计算航向角等。 6. 输出结果:将处理后的数据通过串口、LCD显示屏或其他适配器进行输出,以便用户可视化查看或进行其他操作。 在编写STM32 GPS模块代码时,需要熟悉STM32的编程语言(如C语言)和硬件资源的使用,同时了解GPS模块的通信协议和数据格式。可以使用开发工具,如Keil MDK或CubeMX等进行代码编写和调试。另外,还可以参考官方文档、示例代码和其他开源项目来加快开发进程。 需要注意的是,GPS模块的参数配置和数据解析可能会因不同型号和厂家而有所差异,因此要根据具体的GPS模块型号和数据格式进行相应的代码编写。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值