赞
踩
支持GPS模块列表:
代码结构:
GPS_Interface.c
#include "GPS_Interface.h" nmea_msg GPSX; const unsigned int BAUD_id[9]={4800,9600,19200,38400,57600,115200,230400,460800,921600};//模块支持波特率数组 //从buf里面得到第cx个逗号所在的位置 //返回值:0~0XFE,代表逗号所在位置的偏移. // 0XFF,代表不存在第cx个逗号 unsigned char NMEA_Comma_Pos(unsigned char *buf,unsigned char cx) { unsigned char *p=buf; while(cx) { if(*buf=='*'||*buf<' '||*buf>'z')return 0XFF;//遇到'*'或者非法字符,则不存在第cx个逗号 if(*buf==',')cx--; buf++; } return buf-p; } //m^n函数 //返回值:m^n次方. unsigned int NMEA_Pow(unsigned char m,unsigned char n) { unsigned int result=1; while(n--)result*=m; return result; } //str转换为数字,以','或者'*'结束 //buf:数字存储区 //dx:小数点位数,返回给调用函数 //返回值:转换后的数值 int NMEA_Str2num(unsigned char *buf,unsigned char*dx) { unsigned char *p=buf; unsigned int ires=0,fres=0; unsigned char ilen=0,flen=0,i; unsigned char 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,unsigned char *buf) { unsigned char *p,*p1,dx; unsigned char len,i,j,slx=0; unsigned char posx; p=buf; p1=(unsigned char*)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=(unsigned char*)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); //得到卫星编号 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信息 } } //分析BDGSV信息 //gpsx:nmea信息结构体 //buf:接收到的北斗数据缓冲区首地址 void NMEA_BDGSV_Analysis(nmea_msg *gpsx,unsigned char *buf) { unsigned char *p,*p1,dx; unsigned char len,i,j,slx=0; unsigned char posx; p=buf; p1=(unsigned char*)strstr((const char *)p,"$BDGSV"); len=p1[7]-'0'; //得到BDGSV的条数 posx=NMEA_Comma_Pos(p1,3); //得到可见北斗卫星总数 if(posx!=0XFF)gpsx->beidou_svnum=NMEA_Str2num(p1+posx,&dx); for(i=0;i<len;i++) { p1=(unsigned char*)strstr((const char *)p,"$BDGSV"); for(j=0;j<4;j++) { posx=NMEA_Comma_Pos(p1,4+j*4); if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_num=NMEA_Str2num(p1+posx,&dx); //得到卫星编号 else break; posx=NMEA_Comma_Pos(p1,5+j*4); if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_eledeg=NMEA_Str2num(p1+posx,&dx);//得到卫星仰角 else break; posx=NMEA_Comma_Pos(p1,6+j*4); if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_azideg=NMEA_Str2num(p1+posx,&dx);//得到卫星方位角 else break; posx=NMEA_Comma_Pos(p1,7+j*4); if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_sn=NMEA_Str2num(p1+posx,&dx); //得到卫星信噪比 else break; slx++; } p=p1+1;//切换到下一个BDGSV信息 } } //分析GNGGA信息 //gpsx:nmea信息结构体 //buf:接收到的GPS/北斗数据缓冲区首地址 void NMEA_GNGGA_Analysis(nmea_msg *gpsx,unsigned char *buf) { unsigned char *p1,dx; unsigned char posx; p1=(unsigned char*)strstr((const char *)buf,"$GNGGA"); 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); } //分析GNGSA信息 //gpsx:nmea信息结构体 //buf:接收到的GPS/北斗数据缓冲区首地址 void NMEA_GNGSA_Analysis(nmea_msg *gpsx,unsigned char *buf) { unsigned char *p1,dx; unsigned char posx; unsigned char i; p1=(unsigned char*)strstr((const char *)buf,"$GNGSA"); posx=NMEA_Comma_Pos(p1,2); //得到定位类型 if(posx!=0XFF)gpsx->fixmode=NMEA_Str2num(p1+posx,&dx); for(i=0;i<12;i++) //得到定位卫星编号 { 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); } //分析GNRMC信息 //gpsx:nmea信息结构体 //buf:接收到的GPS/北斗数据缓冲区首地址 void NMEA_GNRMC_Analysis(nmea_msg *gpsx,unsigned char *buf) { unsigned char *p1,dx; unsigned char posx; unsigned int temp; float rs; p1=(unsigned char*)strstr((const char *)buf,"GNRMC");//"$GNRMC",经常有&和GNRMC分开的情况,故只判断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)+8; 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); //南纬还是北纬 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; } } //分析GNVTG信息 //gpsx:nmea信息结构体 //buf:接收到的GPS/北斗数据缓冲区首地址 void NMEA_GNVTG_Analysis(nmea_msg *gpsx,unsigned char *buf) { unsigned char *p1,dx; unsigned char posx; p1=(unsigned char*)strstr((const char *)buf,"$GNVTG"); 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,unsigned char *buf) { NMEA_GPGSV_Analysis(gpsx,buf); //GPGSV解析 NMEA_BDGSV_Analysis(gpsx,buf); //BDGSV解析 NMEA_GNGGA_Analysis(gpsx,buf); //GNGGA解析 NMEA_GNGSA_Analysis(gpsx,buf); //GNGSA解析 NMEA_GNRMC_Analysis(gpsx,buf); //GNRMC解析 NMEA_GNVTG_Analysis(gpsx,buf); //GNVTG解析 } char *myitoa(int value, char *string, int radix) { int i, d; int flag = 0; char *ptr = string; /* This implementation only works for decimal numbers. */ if (radix != 10) { *ptr = 0; return string; } if (!value) { *ptr++ = 0x30; *ptr = 0; return string; } /* if this is a negative value insert the minus sign. */ if (value < 0) { *ptr++ = '-'; /* Make the value positive. */ value *= -1; } for (i = 10000; i > 0; i /= 10) { d = value / i; if (d || flag) { *ptr++ = (char)(d + 0x30); value -= (d * i); flag = 1; } } /* Null terminate the string. */ *ptr = 0; return string; } /* NCL_Itoa */
GPS_Interface.h
#ifndef _GPS_INTERFACE_H_ #define _GPS_INTERFACE_H_ #include <stdint.h> #include <string.h> #include <stdio.h> #include "main.h" #include "stdarg.h" #include "string.h" //GPS NMEA-0183协议重要参数结构体定义 //卫星信息 __packed typedef struct { unsigned char num; //卫星编号 unsigned char eledeg; //卫星仰角 unsigned short azideg; //卫星方位角 unsigned char sn; //信噪比 }nmea_slmsg; //北斗 NMEA-0183协议重要参数结构体定义 //卫星信息 __packed typedef struct { unsigned char beidou_num; //卫星编号 unsigned char beidou_eledeg; //卫星仰角 unsigned short beidou_azideg; //卫星方位角 unsigned char beidou_sn; //信噪比 }beidou_nmea_slmsg; //UTC时间信息 __packed typedef struct { unsigned short year; //年份 unsigned char month; //月份 unsigned char date; //日期 unsigned char hour; //小时 unsigned char min; //分钟 unsigned char sec; //秒钟 }nmea_utc_time; //NMEA 0183 协议解析后数据存放结构体 __packed typedef struct { unsigned char svnum; //可见GPS卫星数 unsigned char beidou_svnum; //可见北斗卫星数 nmea_slmsg slmsg[12]; //最多12颗GPS卫星 beidou_nmea_slmsg beidou_slmsg[12]; //暂且算最多12颗北斗卫星 nmea_utc_time utc; //UTC时间 unsigned int latitude; //纬度 分扩大100000倍,实际要除以100000 unsigned char nshemi; //北纬/南纬,N:北纬;S:南纬 unsigned int longitude; //经度 分扩大100000倍,实际要除以100000 unsigned char ewhemi; //东经/西经,E:东经;W:西经 unsigned char gpssta; //GPS状态:0,未定位;1,非差分定位;2,差分定位;6,正在估算. unsigned char posslnum; //用于定位的GPS卫星数,0~12. unsigned char possl[12]; //用于定位的卫星编号 unsigned char fixmode; //定位类型:1,没有定位;2,2D定位;3,3D定位 unsigned short pdop; //位置精度因子 0~500,对应实际值0~50.0 unsigned short hdop; //水平精度因子 0~500,对应实际值0~50.0 unsigned short vdop; //垂直精度因子 0~500,对应实际值0~50.0 int altitude; //海拔高度,放大了10倍,实际除以10.单位:0.1m unsigned short speed; //地面速率,放大了1000倍,实际除以10.单位:0.001公里/小时 }nmea_msg; //SkyTra S1216F8 配置波特率结构体 __packed typedef struct { unsigned short sos; //启动序列,固定为0XA0A1 unsigned short PL; //有效数据长度0X0004; unsigned char id; //ID,固定为0X05 unsigned char com_port; //COM口,固定为0X00,即COM1 unsigned char Baud_id; //波特率(0~8,4800,9600,19200,38400,57600,115200,230400,460800,921600) unsigned char Attributes; //配置数据保存位置 ,0保存到SRAM,1保存到SRAM&FLASH,2临时保存 unsigned char CS; //校验值 unsigned short end; //结束符:0X0D0A }SkyTra_baudrate; //SkyTra S1216F8 配置输出信息结构体 __packed typedef struct { unsigned short sos; //启动序列,固定为0XA0A1 unsigned short PL; //有效数据长度0X0009; unsigned char id; //ID,固定为0X08 unsigned char GGA; //1~255(s),0:disable unsigned char GSA; //1~255(s),0:disable unsigned char GSV; //1~255(s),0:disable unsigned char GLL; //1~255(s),0:disable unsigned char RMC; //1~255(s),0:disable unsigned char VTG; //1~255(s),0:disable unsigned char ZDA; //1~255(s),0:disable unsigned char Attributes; //配置数据保存位置 ,0保存到SRAM,1保存到SRAM&FLASH,2临时保存 unsigned char CS; //校验值 unsigned short end; //结束符:0X0D0A }SkyTra_outmsg; //SkyTra S1216F8 配置位置更新率结构体 __packed typedef struct { unsigned short sos; //启动序列,固定为0XA0A1 unsigned short PL; //有效数据长度0X0003; unsigned char id; //ID,固定为0X0E unsigned char rate; //取值范围:1, 2, 4, 5, 8, 10, 20, 25, 40, 50 unsigned char Attributes; //配置数据保存位置 ,0保存到SRAM,1保存到SRAM&FLASH,2临时保存 unsigned char CS; //校验值 unsigned short end; //结束符:0X0D0A }SkyTra_PosRate; //SkyTra S1216F8 配置输出脉冲(PPS)宽度结构体 __packed typedef struct { unsigned short sos; //启动序列,固定为0XA0A1 unsigned short PL; //有效数据长度0X0007; unsigned char id; //ID,固定为0X65 unsigned char Sub_ID; //0X01 unsigned int width; //1~100000(us) unsigned char Attributes; //配置数据保存位置 ,0保存到SRAM,1保存到SRAM&FLASH,2临时保存 unsigned char CS; //校验值 unsigned short end; //结束符:0X0D0A }SkyTra_pps_width; //SkyTra S1216F8 ACK结构体 __packed typedef struct { unsigned short sos; //启动序列,固定为0XA0A1 unsigned short PL; //有效数据长度0X0002; unsigned char id; //ID,固定为0X83 unsigned char ACK_ID; //ACK ID may further consist of message ID and message sub-ID which will become 3 bytes of ACK message unsigned char CS; //校验值 unsigned short end; //结束符 }SkyTra_ACK; //SkyTra S1216F8 NACK结构体 __packed typedef struct { unsigned short sos; //启动序列,固定为0XA0A1 unsigned short PL; //有效数据长度0X0002; unsigned char id; //ID,固定为0X84 unsigned char NACK_ID; //ACK ID may further consist of message ID and message sub-ID which will become 3 bytes of ACK message unsigned char CS; //校验值 unsigned short end; //结束符 }SkyTra_NACK; int NMEA_Str2num(unsigned char *buf,unsigned char*dx); void GPS_Analysis(nmea_msg *gpsx,unsigned char *buf); void NMEA_GPGSV_Analysis(nmea_msg *gpsx,unsigned char *buf); void NMEA_BDGSV_Analysis(nmea_msg *gpsx,unsigned char *buf); void NMEA_GNGGA_Analysis(nmea_msg *gpsx,unsigned char *buf); void NMEA_GNGSA_Analysis(nmea_msg *gpsx,unsigned char *buf); void NMEA_GNGSA_Analysis(nmea_msg *gpsx,unsigned char *buf); void NMEA_GNRMC_Analysis(nmea_msg *gpsx,unsigned char *buf); void NMEA_GNVTG_Analysis(nmea_msg *gpsx,unsigned char *buf); char *myitoa(int value, char *string, int radix); #endif
在需要的地方加入#include "GPS_Interface.h"
,然后调用
nmea_msg gpsx;
GPS_Analysis(&gpsx,uartDMA_data.bits.uart_buffer);
注意
:uartDMA_data.bits.uart_buffer是你串口通过dma获取到的gps模块发来的数据
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。