?? gps.c
字號:
/*************************************************/
//項 目:水利數碼通
//文件名:UART.C
//功 能: 串口0、1數據收發處理,軟件串口處理
//作 者:楊世峰
//日 期:2004-03-13
/*************************************************/
#include "upsd3300.h"
#include "hardware.h"
#include "gps.h"
#include "uart.h"
#include "string.h"
#include "const.h"
//////////////////////////////////
//====================變量定義=====================
extern uchar idata ucGpsCommandStatus;//GPS信息處理狀態機
extern uchar xdata ucGPSCommand[8];//GPS命令標識頭
extern uchar xdata ucGPSDataBuff[82];//GPS數據緩存
extern uchar xdata ucCheckSum[2];//GPS命令校驗字節
extern uchar idata ucGPSBuffCnt;
//每月最大天數表
extern uchar xdata GPS_Date[];
extern uint idata unInBufCntComm1; //緩沖區計數
extern union ByteToFloatOrLong xdata ByteChang;
///////////////////////////////////
extern INFO_GPS xdata InfoGPS;
extern INFO_GPS xdata NowInfoGPS;//實時gps 信息
extern INFO_STAR xdata ucSNR[12];
////////////////////////////////////
//=================================================
//GPS數據處理主循環
//=================================================
void GPS_ProcessNMEA(void)
{
uchar idata uch0;
while(unInBufCntComm1)
{
switch (ucGpsCommandStatus)
{
case 0:
{
ReadCharComm1(&uch0);
if (uch0=='$')
{
ucGpsCommandStatus++;
}
break;
}
case 1:
{
ReadCharComm1(&uch0);
if (uch0=='G')
ucGpsCommandStatus++;
else
ucGpsCommandStatus=0;
break;
}
case 2:
{
ReadCharComm1(&uch0);
if (uch0=='P')
ucGpsCommandStatus++;
else
ucGpsCommandStatus=0;
break;
}
case 3:
{
if(unInBufCntComm1 >= 3)
{
ReadCharComm1(&ucGPSCommand[0]);
ReadCharComm1(&ucGPSCommand[1]);
ReadCharComm1(&ucGPSCommand[2]);
ucGPSCommand[3] = '\0';
ucGPSDataBuff[0] = 'G';
ucGPSDataBuff[1] = 'P';
strcpy(ucGPSDataBuff+2,ucGPSCommand);
ucGPSBuffCnt = 5;
ucGpsCommandStatus++;
}
break;
}
case 4: //process command
{
if(unInBufCntComm1 < 2)
break;
else
{
if(ucGPSBuffCnt>80)
{
ucGpsCommandStatus = 0;
break;
}
ReadCharComm1(ucGPSDataBuff+ucGPSBuffCnt);
ReadCharComm1(ucGPSDataBuff+ucGPSBuffCnt+1);
if((ucGPSDataBuff[ucGPSBuffCnt] =='\r')\
&&(ucGPSDataBuff[ucGPSBuffCnt+1] =='\n'))
{
ucCheckSum[0] =ucGPSDataBuff[ucGPSBuffCnt-2] - 0x30;
ucCheckSum[1] =ucGPSDataBuff[ucGPSBuffCnt-1] - 0x30;;
if(GPS_CheckCommand())
{
ProcessGPSCommand();
}
ucGpsCommandStatus=0;
break;
}
else
{
if(ucGPSDataBuff[ucGPSBuffCnt+1] =='\r')
ucGpsCommandStatus++;
}
ucGPSBuffCnt+=2;
}
break;
}//end of case 4
case 5:
{
if(ucGPSBuffCnt>81)
{
ucGpsCommandStatus = 0;
break;
}
ReadCharComm1(ucGPSDataBuff+ucGPSBuffCnt);
if(ucGPSDataBuff[ucGPSBuffCnt] =='\n');
{
ucCheckSum[0] =ucGPSDataBuff[ucGPSBuffCnt-3] - 0x30;
ucCheckSum[1] =ucGPSDataBuff[ucGPSBuffCnt-2] - 0x30;;
if(GPS_CheckCommand())
{
ProcessGPSCommand();
}
}
ucGpsCommandStatus=0;
break;
}
default :
ucGpsCommandStatus=0;
}//end of switch1
}//end of if
}
////////////////////////
void ProcessGPSCommand(void)
{
if(strcmp(ucGPSCommand,"GGA") == 0)
{
GPS_ProcessGGA();
}
else if(strcmp(ucGPSCommand,"GSV") == 0)
{
GPS_ProcessGSV();
}
else if(strcmp(ucGPSCommand,"RMC") == 0)
{
GPS_ProcessRMC();
}
}
//--------------------------------------------------
//GPS命令異或校驗
//--------------------------------------------------
uchar GPS_CheckCommand( void )
{
uchar idata uci;
uint idata Sum = 0;
if(ucCheckSum[0]>0x0f) ucCheckSum[0] -=0x07;
if(ucCheckSum[1]>0x0f) ucCheckSum[1] -=0x07;
Sum = ucCheckSum[0] << 4;
Sum +=ucCheckSum[1];
for(uci=0; (ucGPSDataBuff[uci] != '*') && (uci < 80);uci++)
Sum ^= ucGPSDataBuff[uci];
if (Sum != 0)
return FALSE;
else
return TRUE;
}
//----------------------------------------
// GPS變量清空
//----------------------------------------
void GPS_ClearData(PINFO_GPS pInfoGPS)
{
uchar xdata i;
uchar *pb;
pb = pInfoGPS->Reserved;
for(i = 0;i < sizeof(INFO_GPS) - 16;i++)
*pb++ = 0;
for(i=0;i<12;i++)
{
ucSNR[i].ucNumber = 0;
ucSNR[i].ucElevation = 0;
ucSNR[i].unAzimuth = 0;
ucSNR[i].ucSNR = 0;
}
}
//////////////////////////////////
//得到第ucSum個都號的位置
///////////////////////////////////
uchar GetNComma(uchar ucNum)
{
uchar idata i,j;
//*,c1,c2,\r,\n
for(i = 5,j=0;i<77;i++)
{
if(ucGPSDataBuff[i] == ',')
{
j++;
if(j == ucNum)
return i;
}
}
return 0;
}
//------------------------------------------------
// 處理GGA命令
//------------------------------------------------
void GPS_ProcessGGA(void)
{
uchar idata i,sign;
//latitude
i=GetNComma(2);
if(i>0)
i++;
else
return;
if(ucGPSDataBuff[i]!=',')
{
NowInfoGPS.Info_Lat.ucDegree = (ucGPSDataBuff[i] - 0x30)*10+\
(ucGPSDataBuff[i+1]-0x30);
NowInfoGPS.Info_Lat.ucMinute = (ucGPSDataBuff[i+2] -0x30)*10+\
(ucGPSDataBuff[i+3]-0x30);
NowInfoGPS.Info_Lat.unSecond = (uint)((ucGPSDataBuff[i+5]-0x30)*1000+\
(ucGPSDataBuff[i+6]-0x30)*100+\
(ucGPSDataBuff[i+7]-0x30)*10+\
(ucGPSDataBuff[i+8]-0x30))*6;
i += 10;
}
else
{
NowInfoGPS.Info_Lat.ucDegree = 0x00;
NowInfoGPS.Info_Lat.ucMinute = 0x00;
NowInfoGPS.Info_Lat.unSecond = 0x00;
i++;
}
if(ucGPSDataBuff[i]!=',')
{
if(ucGPSDataBuff[i] == 'S')
NowInfoGPS.Info_Lat.ucSign = 1;//s
else
NowInfoGPS.Info_Lat.ucSign = 0;//n
i += 2;
}
else
{
i++;
}
//longitude
if(ucGPSDataBuff[i]!=',')
{
NowInfoGPS.Info_Lon.ucDegree = (ucGPSDataBuff[i]-0x30)*100+\
(ucGPSDataBuff[i+1]-0x30)*10+\
(ucGPSDataBuff[i+2]-0x30);
NowInfoGPS.Info_Lon.ucMinute = (ucGPSDataBuff[i+3]-0x30)*10+\
(ucGPSDataBuff[i+4]-0x30);
NowInfoGPS.Info_Lon.unSecond = (uint)((ucGPSDataBuff[i+6]-0x30)*1000+\
(ucGPSDataBuff[i+7]-0x30)*100+\
(ucGPSDataBuff[i+8]-0x30)*10+\
(ucGPSDataBuff[i+9]-0x30))*6;
i+=11;
}
else
{
NowInfoGPS.Info_Lon.ucDegree = 0x00;
NowInfoGPS.Info_Lon.ucMinute = 0x00;
NowInfoGPS.Info_Lon.unSecond = 0x00;
i++;
}
if(ucGPSDataBuff[i]!=',')
{
if(ucGPSDataBuff[i]=='W')
NowInfoGPS.Info_Lon.ucSign = 1;//w
else
NowInfoGPS.Info_Lon.ucSign = 0;//e
i+=2;
}
else
{
i++;
}
if(ucGPSDataBuff[i]!=',')
{
NowInfoGPS.ucDStatue = ucGPSDataBuff[i]-0x30;
i+=2;
}
else
{
NowInfoGPS.ucDStatue = 0x00;
i++;
}
if(ucGPSDataBuff[i]!=',')
{
NowInfoGPS.ucSvSum = (ucGPSDataBuff[i]-0x30)*10+\
(ucGPSDataBuff[i+1]-0x30);
i+=3;
}
else
{
NowInfoGPS.ucSvSum = 0x00;
i++;
}
if(ucGPSDataBuff[i]!=',')
{
NowInfoGPS.unDop =(uint)((ucGPSDataBuff[i]-0x30)*10+\
(ucGPSDataBuff[i+2]-0x30));
i+=4;
}
else
{
NowInfoGPS.unDop = 0x00;
i++;
}
NowInfoGPS.iHigh = 0;
if(ucGPSDataBuff[i] == '-')
{
sign = 1;
i++;
}
for(; (ucGPSDataBuff[i]!='.') && (ucGPSDataBuff[i]!=','); i++)//舍去高度的小數
{
NowInfoGPS.iHigh *= 10;
NowInfoGPS.iHigh += (ucGPSDataBuff[i]-0x30);
}
if(sign ==1)
NowInfoGPS.iHigh *= -1;
if(NowInfoGPS.iHigh > 90000)
NowInfoGPS.iHigh = 0;
}
//-------------------------------------------------
//處理GSV命令
//-------------------------------------------------
void GPS_ProcessGSV(void)
{
uchar idata i,frame,j,k,Statellite,cnt;
frame = 0;
i=GetNComma(2);
if(i>0)
i++;
else
return;
if(ucGPSDataBuff[i]!=',')
{
frame = ucGPSDataBuff[i]-0x30;
i+=2;
}
else
{
return;
}
Statellite = 0;
for(;ucGPSDataBuff[i]!=',';i++)
{
Statellite *= 10;
Statellite += ucGPSDataBuff[i]-0x30;
}
i++;
if(ucGPSDataBuff[i]!=',')
{
k = (frame -1)*4;
for(j=0;j<4;j++)
{
ucSNR[j+k].ucNumber = 0;
ucSNR[j+k].unAzimuth = 0;
ucSNR[j+k].ucElevation = 0;
ucSNR[j+k].ucSNR = 0;
}
if(Statellite>=frame*4)
cnt = 4;
else
cnt = Statellite - k;
for(j=0;j<cnt;j++)
{
for(;ucGPSDataBuff[i]!=',';i++)
{
ucSNR[j+k].ucNumber *= 10;
ucSNR[j+k].ucNumber += ucGPSDataBuff[i]-0x30;
}
i++;
for(;ucGPSDataBuff[i]!=',';i++)
{
ucSNR[j+k].ucElevation *= 10;
ucSNR[j+k].ucElevation += ucGPSDataBuff[i]-0x30;
}
i++;
for(;ucGPSDataBuff[i]!=',';i++)
{
ucSNR[j+k].unAzimuth *= 10;
ucSNR[j+k].unAzimuth += ucGPSDataBuff[i]-0x30;
}
i++;
for(;(ucGPSDataBuff[i]!=',')&&(ucGPSDataBuff[i]!='*');i++)
{
ucSNR[j+k].ucSNR *=10;
ucSNR[j+k].ucSNR += ucGPSDataBuff[i]-0x30;
}
i++;
}
}
}
//-------------------------------------------------
//處理RMC命令
//-------------------------------------------------
void GPS_ProcessRMC(void)
{
uchar idata i;
uint idata temp;
i=GetNComma(1);
if(i>0)
i++;
else
return;
/////////////////hhmmss
if(ucGPSDataBuff[i]!=',')
{
NowInfoGPS.Info_DateTime.ucHour = (ucGPSDataBuff[i]-0x30)*10+(ucGPSDataBuff[i+1]-0x30);
//調整為北京時間
NowInfoGPS.Info_DateTime.ucHour += 8;
NowInfoGPS.Info_DateTime.ucHour%=24;
NowInfoGPS.Info_DateTime.ucMinute = (ucGPSDataBuff[i+2]-0x30)*10+(ucGPSDataBuff[i+3]-0x30);
NowInfoGPS.Info_DateTime.ucSecond = (ucGPSDataBuff[i+4]-0x30)*10+(ucGPSDataBuff[i+5]-0x30);
i += 11;
}
else
{
NowInfoGPS.Info_DateTime.ucHour = 0x00;
NowInfoGPS.Info_DateTime.ucMinute = 0x00;
NowInfoGPS.Info_DateTime.ucSecond = 0x00;
i++;
}
//////////////
i=GetNComma(9);
if(i>0)
i++;
else
return;
if(ucGPSDataBuff[i]!=',')
{
NowInfoGPS.Info_DateTime.ucDay = (ucGPSDataBuff[i]-0x30)*10+(ucGPSDataBuff[i+1]-0x30);
NowInfoGPS.Info_DateTime.ucMonth = (ucGPSDataBuff[i+2]-0x30)*10+(ucGPSDataBuff[i+3]-0x30);
NowInfoGPS.Info_DateTime.ucYear = (ucGPSDataBuff[i+4]-0x30)*10+(ucGPSDataBuff[i+5]-0x30);
//時區調整
//每天的凌晨0點0分0秒至早上7點59分59秒這段時間需要調整
if(NowInfoGPS.Info_DateTime.ucHour < 8)
{
NowInfoGPS.Info_DateTime.ucDay ++;
//天數如果大于本月的最大天數,月加1,天數返回1
if(NowInfoGPS.Info_DateTime.ucDay > GPS_Date[NowInfoGPS.Info_DateTime.ucMonth])
{
//閏年的2月的最大天數處理
if(NowInfoGPS.Info_DateTime.ucMonth == 2)
{
temp = 2000+NowInfoGPS.Info_DateTime.ucYear;
if(((temp%4 == 0) && (temp%100 != 0)) || (temp%400 == 0))//閏年
{
//閏年2月29日的處理
if(NowInfoGPS.Info_DateTime.ucDay > 29)
{
NowInfoGPS.Info_DateTime.ucDay = 1;
NowInfoGPS.Info_DateTime.ucMonth ++;
}
}
else//非閏年
{
NowInfoGPS.Info_DateTime.ucDay = 1;
NowInfoGPS.Info_DateTime.ucMonth ++;
}
}
//其它月份的天數處理
else
{
NowInfoGPS.Info_DateTime.ucDay = 1;
NowInfoGPS.Info_DateTime.ucMonth ++;
//12月最大天數,年加1
if(NowInfoGPS.Info_DateTime.ucMonth > 12)
{
NowInfoGPS.Info_DateTime.ucYear ++;
NowInfoGPS.Info_DateTime.ucMonth = 1;
}
}
}
}
}
else
{
NowInfoGPS.Info_DateTime.ucDay = 0x00;
NowInfoGPS.Info_DateTime.ucMonth = 0x00;
NowInfoGPS.Info_DateTime.ucYear = 0x00;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -