#include "gps.h"
#include "sys.h"
#include "string.h"
#include "oled.h"
#include "delay.h"
#include "stdio.h"
//Ԯࠚע̍ۺզȸ
__align(8) uint8_t USART2_TX_BUF[USART_MAX_SEND_LEN]; //ע̍ۺԥ,خճUSART_MAX_SEND_LENؖޚ
uint8_t USART2_RX_BUF[USART_MAX_RECV_LEN]; //ޓ˕ۺԥ,خճUSART_MAX_RECV_LENٶؖޚ.
//Ԯࠚע̍һٶؖޚ
static void Com_SendData(uint8_t data)
{
USART_SendData(USART2, data);//ע̍˽ߝ
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
}
void HAL_UART_Transmit(USART_TypeDef* USARTx, uint8_t *pData, uint16_t Size)
{
uint16_t i;
for(i=0;i<Size;i++)
{
Com_SendData(*(pData+i));
}
}
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;
}
//m^nگ˽
//ܘֵ:m^nՎ.
uint32_t NMEA_Pow(uint8_t m,uint8_t n)
{
uint32_t result=1;
while(n--)result*=m;
return result;
}
//strתۻΪ˽ؖ,Ӕ','ܲ֟'*'ޡ˸
//buf:˽ؖզԢȸ
//dx:С˽֣λ˽,ܘٸַԃگ˽
//ܘֵ:תۻ۳ք˽ֵ
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); //փսπчҠۅ
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);
}
//ؖ϶GPGSAхϢ
//gpsx:nmeaхϢޡٹͥ
//buf:ޓ˕սքGPS˽ߝۺԥȸ˗ַ֘
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++) //փս֨λπчҠۅ
{
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);
}
//ؖ϶GPRMCхϢ
//gpsx:nmeaхϢޡٹͥ
//buf:ޓ˕սքGPS˽ߝۺԥȸ˗ַ֘
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); //ŏγ۹ˇѱγ
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;
}
}
//ؖ϶GPVTGхϢ
//gpsx:nmeaхϢޡٹͥ
//buf:ޓ˕սքGPS˽ߝۺԥȸ˗ַ֘
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ޢ϶
}
//GPSУҩۍ݆̣
//buf:˽ߝۺզȸ˗ַ֘
//len:˽ߝӤ
//cka,ckb:}ٶУҩޡڻ.
void Ublox_CheckSum(uint8_t *buf,uint16_t len,uint8_t* cka,uint8_t*ckb)
{
uint16_t i;
*cka=0;*ckb=0;
for(i=0;i<len;i++)
{
*cka=*cka+buf[i];
*ckb=*ckb+*cka;
}
}
extern uint16_t RX_len;//ޓ˕ؖޚ݆˽
extern void USART_BaudRate_Init(uint32_t Data);
/////////////////////////////////////////UBLOX Ƥ׃պë/////////////////////////////////////
//ݬөCFGƤ׃ִѐȩ࠶
//ܘֵ:0,ACKԉ٦
// 1,ޓ˕Ӭʱխϳ
// 2,ûԐ֒սͬҽؖػ
// 3,ޓ˕սNACKӦհ
uint8_t Ublox_Cfg_Ack_Check(void)
{
uint16_t len=0,i;
uint8_t rval=0;
while(RX_len==0 && len<100)//ֈսޓ˕սӦհ
{
len++;
delay_ms(5);
}
if(RX_len)
{
len=RX_len;
for(i=0;i<len;i++)if(USART2_RX_BUF[i]==0XB5)break;//ө֒ͬҽؖػ 0XB5
if(i==len)rval=2; //ûԐ֒սͬҽؖػ
else if(USART2_RX_BUF[i+3]==0X00)rval=3;//ޓ˕սNACKӦհ
else rval=0; //ޓ˕սACKӦհ
}else rval=1;
return rval;
}
//Ƥ׃ѣզ
//ݫձǰƤ׃ѣզ՚ҿEEPROMoĦ
//ܘֵ:0,ִѐԉ٦;1,ִѐʧќ.
uint8_t Ublox_Cfg_Cfg_Save(void)
{
uint8_t i;
_ublox_cfg_cfg *cfg_cfg=(_ublox_cfg_cfg *)USART2_TX_BUF;
cfg_cfg->header=0X62B5; //cfg header
cfg_cfg->id=0X0906; //cfg cfg id
cfg_cfg->dlength=13; //˽ߝȸӤΪ13ٶؖޚ.
cfg_cfg->clearmask=0; //ȥԽҚëΪ0
cfg_cfg->savemask=0XFFFF; //ѣզҚëΪ0XFFFF
cfg_cfg->loadmask=0; //ݓҚëΪ0
cfg_cfg->devicemask=4; //ѣզ՚EEPROMoĦ
Ublox_CheckSum((uint8_t*)(&cfg_cfg->id),sizeof(_ublox_cfg_cfg)-4,&cfg_cfg->cka,&cfg_cfg->ckb);
HAL_UART_Transmit(USART2, (uint8_t *)&USART2_TX_BUF, sizeof(_ublox_cfg_cfg));
for(i=0;i<6;i++)if(Ublox_Cfg_Ack_Check()==0)break; //EEPROMдɫѨҪ҈ޏ߃ʱݤ,̹ӔlѸƐנՎ
return i==6?1:0;
}
//Ƥ׃NMEAˤԶхϢٱʽ
//msgid:ҪәطքNMEAлϢ͵Ŀ,ߟͥݻЂĦքӎ˽ҭ
// 00,GPGGA;01,GPGLL;02,GPGSA;
// 03,GPGSV;04,GPRMC;05,GPVTG;
// 06,GPGRS;07,GPGST;08,GPZDA;
// 09,GPGBS;0A,GPDTM;0D,GPGNS;
//uart1set:0,ˤԶژҕ;1,ˤԶߪǴ.
//ܘֵ:0,ִѐԉ٦;Ǥ̻,ִѐʧќ.
uint8_t Ublox_Cfg_Msg(uint8_t msgid,uint8_t uart1set)
{
_ublox_cfg_msg *cfg_msg=(_ublox_cfg_msg *)USART2_TX_BUF;
cfg_msg->header=0X62B5; //cfg header
cfg_msg->id=0X0106; //cfg msg id
cfg_msg->dlength=8; //˽ߝȸӤΪ8ٶؖޚ.
cfg_msg->msgclass=0XF0; //NMEAлϢ
cfg_msg->msgid=msgid; //ҪәطքNMEAлϢ͵Ŀ
cfg_msg->iicset=1; //ĬɏߪǴ
cfg_msg->uart1set=uart1set; //ߪژʨ׃
cfg_msg->uart2set=1; //ĬɏߪǴ
cfg_msg->usbset=1; //ĬɏߪǴ
cfg_msg->spiset=1; //ĬɏߪǴ
cfg_msg->ncset=1; //ĬɏߪǴ
Ublox_CheckSum((uint8_t*)(&cfg_msg->id),sizeof(_ublox_cfg_msg)-4,&cfg_msg->cka,&cfg_msg->ckb);
HAL_UART_Transmit(USART2, (uint8_t *)&USART2_TX_BUF, sizeof(_ublox_cfg_msg));
return Ublox_Cfg_Ack_Check();
}
//Ƥ׃NMEAˤԶхϢٱʽ
//baudrate:Ҩ͘Ê,4800/9600/19200/38400/57600/115200/230400
//ܘֵ:0,ִѐԉ٦;Ǥ̻,ִѐʧќ(֢oһܡܘ0)
uint8_t Ublox_Cfg_Prt(uint32_t baudrate)
{
_ublox_cfg_prt *cfg_prt=(_ublox_cfg_prt *)USART2_TX_BUF;
cfg_prt->header=0X62B5; //cfg header
cfg_prt->id=0X0006; //cfg prt id
cfg_prt->dlength=20; //˽ߝȸӤΪ20ٶؖޚ.
cfg_prt->portid=1; //әطԮࠚ1
cfg_prt->reserved=0; //ѣ´ؖޚ,ʨ׃Ϊ0
cfg_prt->txready=0; //TX Readyʨ׃Ϊ0
cfg_prt->mode=0X08D0; //8λ,1ٶֹͣλ,ϞУҩλ
cfg_prt->baudrate=baudrate; //Ҩ͘Êʨ׃
cfg_prt->inprotomask=0X0007;//0+1+2
cfg_prt->outprotomask=0X0007;//0+1+2
cfg_prt->reserved4=0; //ѣ´ؖޚ,ʨ׃Ϊ0
cfg_prt->reserved5=0; //ѣ´ؖޚ,ʨ׃Ϊ0
Ublox_CheckSum((uint8_t*)(&cfg_prt->id),sizeof(_ublox_cfg_prt)-4,&cfg_prt->cka,&cfg_prt->ckb);
HAL_UART_Transmit(USART2, (uint8_t *)&USART2_TX_BUF, sizeof(_ublox_cfg_prt));
delay_ms(200); //ֈսע̍Ϊԉ
USART_BaudRate_Init(baudrate);
return Ublox_Cfg_Ack_Check();//֢oһܡ״ܘ0,ӲΪUBLOXעܘ4քӦհ՚ԮࠚטтԵʼۯքʱ۲ӑޭѻ֪Ǻ.
}
//Ƥ׃UBLOX NEO-6քʱדöԥˤԶ
//interval:öԥݤٴ(us)
//length:öԥ࠭(us)
//status:öԥƤ׃:1,ٟ֧ƽԐЧ;0,ژҕ;-1,֍֧ƽԐЧ.
//ܘֵ:0,ע̍ԉ٦;Ǥ̻,ע̍ʧќ.
uint8_t Ublox_Cfg_Tp(uint32_t interval,uint32_t length,signed char status)
{
_ublox_cfg_tp *cfg_tp=(_ublox_cfg_tp *)USART2_TX_BUF;
cfg_tp->header=0X62B5; //cfg header
cfg_tp->id=0X0706; //cfg tp id
cfg_tp->dlength=20; //˽ߝȸӤΪ20ٶؖޚ.
cfg_tp->interval=interval; //öԥݤٴ,us
cfg_tp->length=length; //öԥ࠭,us
cfg_tp->status=status; //ʱדöԥƤ׃
cfg_tp->timeref=0; //ӎUTC ʱݤ
cfg_tp->flags=0; //flagsΪ0
cfg_tp->reserved=0; //ѣ´λΪ0
cfg_tp->antdelay=820; //ͬПғʱΪ820ns
cfg_tp->rfdelay=0; //RFғʱΪ0ns
cfg_tp->userdelay=0; //ԃۧғʱΪ0ns
Ublox_CheckSum((uint8_t*)(&cfg_tp->id),sizeof(_ublox_cfg_tp)-4,&cfg_tp->cka,&cfg_tp->ckb);
HAL_UART_Transmit(USART2, (uint8_t *)&USART2_TX_BUF, sizeof(_ublox_cfg_tp));
return Ublox_Cfg_Ack_Check();
}
//Ƥ׃UBLOX NEO-6քټт̙Ê
//measrate:ӢʱݤݤٴìեλΪmsìخʙһŜСԚ200msè5Hzé
//reftime:ӎʱݤì0=UTC Timeû1=GPS Timeèһѣʨ׃Ϊ1é
//ܘֵ:0,ע̍ԉ٦;Ǥ̻,ע̍ʧќ.
uint8_t Ublox_Cfg_Rate(uint16_t measrate,uint8_t reftime)
{
_ublox_cfg_rate *cfg_rate=(_ublox_cfg_rate *)USART2_TX_BUF;
if(measrate<200)return 1; //СԚ200msìֱޓԶ
cfg_rate->header=0X62B5; //cfg header
cfg_rate->id=0X0806; //cfg rate id
cfg_rate->dlength=6; //˽ߝȸӤΪ6ٶؖޚ.
cfg_rate->measrate=measrate;//öԥݤٴ,us
cfg_rate->navrate=1; //ռڽ̙Êèלǚéìڌ֨Ϊ1
cfg_rate->timeref=reftime; //ӎʱݤΪGPSʱݤ
Ublox_CheckSum((uint8_t*)(&cfg_rate->id),sizeof(_ublox_cfg_rate)-4,&cfg_rate->cka,&cfg_rate->ckb);
HAL_UART_Transmit(USART2, (uint8_t *)&USART2_TX_BUF, sizeof(_ublox_cfg_rate));
return Ublox_Cfg_Ack_Check();
}
nmea_msg gpsx;
__align(4) uint8_t dtbuf[50]; //Дʾۺԥ
//ДʾGPS֨λхϢ
void Gps_Msg_Show(void)
{
float tp;
tp=gpsx.longitude;
sprintf((char *)dtbuf,":%.5f %1c",tp/=100000,gpsx.ewhemi); //փսޭؖػԮ
OLED_ShowCHinese(0,2,5);//ޭ
OLED_ShowCHinese(16,2,7);//
OLED_ShowString(32,2,dtbuf);
tp=gpsx.latitude;
sprintf((char *)dtbuf,":%.5f %1c",tp/=100000,gpsx.nshemi); //փսγؖػԮ
OLED_ShowCHinese(0,4,6);//γ
OLED_ShowCHinese(16,4,7);//
OLED_ShowString(32,4,dtbuf);
if(gpsx.fixmode<=3) //֨λ״̬
{
gpsx.utc.hour = gpsx.utc.hour + 8; //ӑ֪քUTCʱݤìתۻԉѱީʱݤìӮ8Сʱ
if(gpsx.utc.hour>=24)
{
gpsx.utc.hour-=24;
}
sprintf((char *)dtbuf,":%02d:%02d:%02d",gpsx.utc.hour,gpsx.utc.min,gpsx.utc.sec); //Дʾѱީʱݤ
OLED_ShowCHinese(0,6,8);//ʱ
OLED_ShowCHinese(16,6,9);//ݤ
OLED_ShowString(32,6,dtbuf);
}
}
void GpsDataRead(void)
{
uint16_t i,rxlen;
if( RX_len)
{
rxlen=RX_len;
for(i=0;i<rxlen;i++)USART2_TX_BUF[i]=USART2_RX_BUF[i];
USART2_TX_BUF[i]=0; //ؔ֯ͭݓޡ˸ػ
GPS_Analysis(&gpsx,(uint8_t*)USART2_TX_BUF);//ؖ϶ؖػԮì˽ߝզɫGPSޡٹͥ
Gps_Msg_Show(); //ДʾޭγìʱݤхϢ
请以以上32代码为参考编写基于海思hi3861外接NEO-6M-0-001的VScode代码需要.h文件.c文件template.c(主函数)文件,用的是uart2(io12-RX,io11-TX)在串口助手上显示出当前经纬度,并注释若想要与其他功能如倾斜传感器之类的连接需要修改哪些地方