⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gps.c

📁 51的GPS开发的NMEA数据读取与解析.rar
💻 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 + -