可到淘宝链接上查看。(因为放的是图片,审核时认为是广告)
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½âÎö
}