stm32驱动GT-U7 GPS

STM32驱动GT-U7 GPS模块

一些参数

可到淘宝链接上查看。(因为放的是图片,审核时认为是广告)

用户手册

4,$GPRMC(推荐定位信息,Recommended Minimum Specific GPS/Transit Data) $GPRMC 语句的基本格式如下: $GPRMC,(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)*hh(CR)(LF)

(1) UTC 时间,hhmmss(时分秒)

(2) 定位状态,A=有效定位,V=无效定位

(3) 纬度 ddmm.mmmmm(度分)

(4) 纬度半球 N(北半球)或 S(南半球)

(5) 经度 dddmm.mmmmm(度分)

(6) 经度半球 E(东经)或 W(西经)

(7) 地面速率(000.0~999.9 节)

(8) 地面航向(000.0~359.9 度,以真北方为参考基准)

(9) UTC 日期,ddmmyy(日月年)

(10) 磁偏角(000.0~180.0 度,前导位数不足则补 0)

(11) 磁偏角方向,E(东)或 W(西)

(12) 模式指示(A=自主定位,D=差分,E=估算,N=数据无效)

举例如下: $GPRMC,023543.00,A,2308.28715,N,11322.09875,E,0.195,240213,A*78

过程

​ 我用串口DMA中断一直读取不到正确的数据,后来去看底层usart.h才发现原来是我波特率搞错了。我把波特率设置为了38400,而正确的应该是9600,这就导致我读取的的数据一直没有其实帧($),所以就一直卡在这里。

​ 改好了波特率以后问题解决,接下来需要对数据处理一下,毕竟数据有点漂(精度2.5m)。

问题

​ 搜星速度有点慢,通信稳定的基础上反馈频率1s一次,感觉有点慢,不过精度感觉还行。等下去室外试看一下。

代码

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//采用串口DMA中断
{
	if(huart == &huart1)
	{
		static int i = 0;
		HAL_UART_Receive_DMA(&huart1,&GPS_begin,1);
		i++;
		if(GPS_begin == '$')//判断起始帧
		{			
			i = 0;
			single = 1;
		}
		GPS_data[i] = GPS_begin;
		if(i == 67)
		{
			single = 1;		
		}
	}
}

gps.h文件

#ifndef _GPS_H_
#define _GPS_H_

#include "stm32f1xx.h"

__packed typedef struct  
{										    
 	uint8_t num;		
	uint8_t eledeg;	
	uint16_t azideg;	
	uint8_t sn;			   
}nmea_slmsg;  

__packed typedef struct  
{										    
 	uint16_t year;	
	uint8_t month;	
	uint8_t date;	
	uint8_t hour; 	
	uint8_t min; 
	uint8_t sec; 
}nmea_utc_time;   	   

__packed typedef struct  
{										    
 	uint8_t svnum;					
	nmea_slmsg slmsg[12];		
	nmea_utc_time utc;			
	uint32_t latitude;			
	uint8_t nshemi;								  
	uint32_t longitude;			  
	uint8_t ewhemi;					
	uint8_t gpssta;					
  
 	uint8_t posslnum;				
 	uint8_t possl[12];				
	uint8_t fixmode;				
	uint16_t pdop;					
	uint16_t hdop;					
	uint16_t vdop;					

	int altitude;			 	 
	uint16_t speed;						 
}nmea_msg; 

extern nmea_msg GPSX;

void GPS_Analysis(nmea_msg *gpsx,uint8_t *buf);
void NMEA_GPRMC_Analysis(nmea_msg *gpsx,uint8_t *buf);

#endif

gps.c文件(里面是ASICC码的注释,所以乱码)

#include "gps.h"
#include "string.h"

nmea_msg GPSX;



uint8_t NMEA_Comma_Pos(uint8_t *buf,uint8_t cx)
{	 		    
	uint8_t *p=buf;
	while(cx)
	{
		if(*buf=='*'||*buf<' '||*buf>'z')return 0XFF;//Óöµ½'*'»òÕß·Ç·¨×Ö·û,Ôò²»´æÔÚµÚcx¸ö¶ººÅ
		if(*buf==',')cx--;
		buf++;
	}
	return buf-p;	 
}

uint32_t NMEA_Pow(uint8_t m,uint8_t n)
{
	uint32_t result=1;	 
	while(n--)result*=m;    
	return result;
}

int NMEA_Str2num(uint8_t *buf,uint8_t*dx)
{
	uint8_t *p=buf;
	uint32_t ires=0,fres=0;
	uint8_t ilen=0,flen=0,i;
	uint8_t mask=0;
	int res;
	while(1) //µÃµ½ÕûÊýºÍСÊýµÄ³¤¶È
	{
		if(*p=='-'){mask|=0X02;p++;}//ÊǸºÊý
		if(*p==','||(*p=='*'))break;//Óöµ½½áÊøÁË
		if(*p=='.'){mask|=0X01;p++;}//Óöµ½Ð¡ÊýµãÁË
		else if(*p>'9'||(*p<'0'))	//ÓзǷ¨×Ö·û
		{	
			ilen=0;
			flen=0;
			break;
		}	
		if(mask&0X01)flen++;
		else ilen++;
		p++;
	}
	if(mask&0X02)buf++;	//È¥µô¸ººÅ
	for(i=0;i<ilen;i++)	//µÃµ½ÕûÊý²¿·ÖÊý¾Ý
	{  
		ires+=NMEA_Pow(10,ilen-1-i)*(buf[i]-'0');
	}
	if(flen>5)flen=5;	//×î¶àÈ¡5λСÊý
	*dx=flen;	 		//СÊýµãλÊý
	for(i=0;i<flen;i++)	//µÃµ½Ð¡Êý²¿·ÖÊý¾Ý
	{  
		fres+=NMEA_Pow(10,flen-1-i)*(buf[ilen+1+i]-'0');
	} 
	res=ires*NMEA_Pow(10,flen)+fres;
	if(mask&0X02)res=-res;		   
	return res;
}	  							
//·ÖÎöGPGSVÐÅÏ¢
//gpsx:nmeaÐÅÏ¢½á¹¹Ìå
//buf:½ÓÊÕµ½µÄGPSÊý¾Ý»º³åÇøÊ×µØÖ·
void NMEA_GPGSV_Analysis(nmea_msg *gpsx,uint8_t *buf)
{
	uint8_t *p,*p1,dx;
	uint8_t len,i,j,slx=0;
	uint8_t posx;   	 
	p=buf;
	p1=(uint8_t*)strstr((const char *)p,"$GPGSV");
	len=p1[7]-'0';								//µÃµ½GPGSVµÄÌõÊý
	posx=NMEA_Comma_Pos(p1,3); 					//µÃµ½¿É¼ûÎÀÐÇ×ÜÊý
	if(posx!=0XFF)gpsx->svnum=NMEA_Str2num(p1+posx,&dx);
	for(i=0;i<len;i++)
	{	 
		p1=(uint8_t*)strstr((const char *)p,"$GPGSV");  
		for(j=0;j<4;j++)
		{	  
			posx=NMEA_Comma_Pos(p1,4+j*4);
			if(posx!=0XFF)gpsx->slmsg[slx].num=NMEA_Str2num(p1+posx,&dx);	//µÃµ½ÎÀÐDZàºÅ
			else break; 
			posx=NMEA_Comma_Pos(p1,5+j*4);
			if(posx!=0XFF)gpsx->slmsg[slx].eledeg=NMEA_Str2num(p1+posx,&dx);//µÃµ½ÎÀÐÇÑö½Ç 
			else break;
			posx=NMEA_Comma_Pos(p1,6+j*4);
			if(posx!=0XFF)gpsx->slmsg[slx].azideg=NMEA_Str2num(p1+posx,&dx);//µÃµ½ÎÀÐÇ·½Î»½Ç
			else break; 
			posx=NMEA_Comma_Pos(p1,7+j*4);
			if(posx!=0XFF)gpsx->slmsg[slx].sn=NMEA_Str2num(p1+posx,&dx);	//µÃµ½ÎÀÐÇÐÅÔë±È
			else break;
			slx++;	   
		}   
 		p=p1+1;//Çл»µ½ÏÂÒ»¸öGPGSVÐÅÏ¢
	}   
}
//·ÖÎöGPGGAÐÅÏ¢
//gpsx:nmeaÐÅÏ¢½á¹¹Ìå
//buf:½ÓÊÕµ½µÄGPSÊý¾Ý»º³åÇøÊ×µØÖ·
void NMEA_GPGGA_Analysis(nmea_msg *gpsx,uint8_t *buf)
{
	uint8_t *p1,dx;			 
	uint8_t posx;    
	p1=(uint8_t*)strstr((const char *)buf,"$GPGGA");
	posx=NMEA_Comma_Pos(p1,6);								//µÃµ½GPS״̬
	if(posx!=0XFF)gpsx->gpssta=NMEA_Str2num(p1+posx,&dx);	
	posx=NMEA_Comma_Pos(p1,7);								//µÃµ½ÓÃÓÚ¶¨Î»µÄÎÀÐÇÊý
	if(posx!=0XFF)gpsx->posslnum=NMEA_Str2num(p1+posx,&dx); 
	posx=NMEA_Comma_Pos(p1,9);								//µÃµ½º£°Î¸ß¶È
	if(posx!=0XFF)gpsx->altitude=NMEA_Str2num(p1+posx,&dx);  
}

void NMEA_GPRMC_Analysis(nmea_msg *gpsx,uint8_t *buf)
{
	uint8_t *p1,dx;			 
	uint8_t posx;     
	uint32_t temp;	   
	float rs;  
	p1=(uint8_t*)strstr((const char *)buf,"GPRMC");//"$GPRMC",¾­³£ÓÐ&ºÍGPRMC·Ö¿ªµÄÇé¿ö,¹ÊÖ»ÅжÏGPRMC.
	posx=NMEA_Comma_Pos(p1,1);								//µÃµ½UTCʱ¼ä
	if(posx!=0XFF)
	{
		temp=NMEA_Str2num(p1+posx,&dx)/NMEA_Pow(10,dx);	 	//µÃµ½UTCʱ¼ä,È¥µôms
		gpsx->utc.hour=temp/10000;
		gpsx->utc.min=(temp/100)%100;
		gpsx->utc.sec=temp%100;	 	 
	}	
	posx=NMEA_Comma_Pos(p1,3);								//µÃµ½Î³¶È
	if(posx!=0XFF)
	{
		temp=NMEA_Str2num(p1+posx,&dx);		 	 
		gpsx->latitude=temp/NMEA_Pow(10,dx+2);	//µÃµ½¡ã
		rs=temp%NMEA_Pow(10,dx+2);				//µÃµ½'		 
		gpsx->latitude=gpsx->latitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//ת»»Îª¡ã 
	}
	posx=NMEA_Comma_Pos(p1,4);								//ÄÏγ»¹ÊDZ±Î³ 
	if(posx!=0XFF)gpsx->nshemi=*(p1+posx);					 
 	posx=NMEA_Comma_Pos(p1,5);								//µÃµ½¾­¶È
	if(posx!=0XFF)
	{												  
		temp=NMEA_Str2num(p1+posx,&dx);		 	 
		gpsx->longitude=temp/NMEA_Pow(10,dx+2);	//µÃµ½¡ã
		rs=temp%NMEA_Pow(10,dx+2);				//µÃµ½'		 
		gpsx->longitude=gpsx->longitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//ת»»Îª¡ã 
	}
	posx=NMEA_Comma_Pos(p1,6);								//¶«¾­»¹ÊÇÎ÷¾­
	if(posx!=0XFF)gpsx->ewhemi=*(p1+posx);		 
	posx=NMEA_Comma_Pos(p1,9);								//µÃµ½UTCÈÕÆÚ
	if(posx!=0XFF)
	{
		temp=NMEA_Str2num(p1+posx,&dx);		 				//µÃµ½UTCÈÕÆÚ
		gpsx->utc.date=temp/10000;
		gpsx->utc.month=(temp/100)%100;
		gpsx->utc.year=2000+temp%100;	 	 
	} 
}
void NMEA_GPGSA_Analysis(nmea_msg *gpsx,uint8_t *buf)
{
	uint8_t *p1,dx;			 
	uint8_t posx; 
	uint8_t i;   
	p1=(uint8_t*)strstr((const char *)buf,"$GPGSA");
	posx=NMEA_Comma_Pos(p1,2);								//µÃµ½¶¨Î»ÀàÐÍ
	if(posx!=0XFF)gpsx->fixmode=NMEA_Str2num(p1+posx,&dx);	
	for(i=0;i<12;i++)										//µÃµ½¶¨Î»ÎÀÐDZàºÅ
	{
		posx=NMEA_Comma_Pos(p1,3+i);					 
		if(posx!=0XFF)gpsx->possl[i]=NMEA_Str2num(p1+posx,&dx);
		else break; 
	}				  
	posx=NMEA_Comma_Pos(p1,15);								//µÃµ½PDOPλÖþ«¶ÈÒò×Ó
	if(posx!=0XFF)gpsx->pdop=NMEA_Str2num(p1+posx,&dx);  
	posx=NMEA_Comma_Pos(p1,16);								//µÃµ½HDOPλÖþ«¶ÈÒò×Ó
	if(posx!=0XFF)gpsx->hdop=NMEA_Str2num(p1+posx,&dx);  
	posx=NMEA_Comma_Pos(p1,17);								//µÃµ½VDOPλÖþ«¶ÈÒò×Ó
	if(posx!=0XFF)gpsx->vdop=NMEA_Str2num(p1+posx,&dx);  
}
void NMEA_GPVTG_Analysis(nmea_msg *gpsx,uint8_t *buf)
{
	uint8_t *p1,dx;			 
	uint8_t posx;    
	p1=(uint8_t*)strstr((const char *)buf,"$GPVTG");							 
	posx=NMEA_Comma_Pos(p1,7);								//µÃµ½µØÃæËÙÂÊ
	if(posx!=0XFF)
	{
		gpsx->speed=NMEA_Str2num(p1+posx,&dx);
		if(dx<3)gpsx->speed*=NMEA_Pow(10,3-dx);	 	 		//È·±£À©´ó1000±¶
	}
}  

//ÌáÈ¡NMEA-0183ÐÅÏ¢
//gpsx:nmeaÐÅÏ¢½á¹¹Ìå
//buf:½ÓÊÕµ½µÄGPSÊý¾Ý»º³åÇøÊ×µØÖ·
void GPS_Analysis(nmea_msg *gpsx,uint8_t *buf)
{
	NMEA_GPGSV_Analysis(gpsx,buf);	//GPGSV½âÎö
	NMEA_GPGGA_Analysis(gpsx,buf);	//GPGGA½âÎö 	
	NMEA_GPGSA_Analysis(gpsx,buf);	//GPGSA½âÎö
	NMEA_GPRMC_Analysis(gpsx,buf);	//GPRMC½âÎö
	NMEA_GPVTG_Analysis(gpsx,buf);	//GPVTG½âÎö
}
  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值