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

📄 gps.c

📁 51单片机的c语言GPS解码程序
💻 C
字号:
//建议将 关于缓冲区的指针使用函数进行封装。减少全局变量的使用。??
#pragma large
#include "public.h"

UCHAR xdata gGpsOk;
UCHAR xdata gGpsRcvCnt;
st_GpsData  xdata GpsData;
const unsigned char xdata gGPRMC[]="GPRMC";
unsigned char xdata gGpsReceiveFullFrame;//是否接收了一个完整的数据包
unsigned char xdata mGpsFrameBuf[102];//GPS解码缓冲区
unsigned char  xdata mReturn[31][11];
unsigned char xdata mGpsFramePoint;//GPS解码缓冲区指针
unsigned char xdata gGpsActiveNum;//GPS超时计数器,收到数据后只置为10 表示10秒钟没有收到数据就进行复位
//unsigned char xdata gGpsSendBuffer[200];
unsigned char xdata  gGpsUartWrite;//gps发送缓冲区写指针
unsigned char xdata  gGpsUartRead;//gps发送缓冲区读指针
unsigned char xdata gGpsUartNull;//Gps发送缓冲区是否空
//unsigned char xdata gGpsReadPoint;//Gps接收缓冲区读指针
//unsigned char xdata gGpsWritePoint;//Gps接收缓冲区写指针
//unsigned char xdata gGpsReceiveBuf[GPS_RX_SIZE + 2 ];//receive buffer max length 2048
unsigned char xdata gGpsReceiveHead;//是否收到$
unsigned char xdata gGpsSendLen;
unsigned char xdata gGpsSendCnt;
UCHAR xdata gGpsNoSignalFlag;
unsigned char xdata gGpsRxBuffer[GPS_RX_SIZE ];
struct QUEUE_STRUCT xdata gGpsRxQ;

/*
UCHAR SendToUart2(unsigned char * buf, unsigned char len)
{
    MyMemCpy(gGpsSendBuffer,buf,len);
    gGpsSendLen = len;
    if(gGpsUartNull==1)
    {
        SBUF = gGpsSendBuffer[0];   //发送第一个字符
        gGpsSendCnt = 1;
        gGpsUartNull=0; //指示发送缓冲区不为空
        return TRUE;
    }
    else
    	return FALSE;
}
*/
//转换字符串为整数,返回整数,和小数位数 参数:字符串,返回小数位数
/*unsigned long GpxStrToLong(unsigned char * buf,unsigned char *num)
{
	double tmp;
	int i,j;
	char * p;
        SendToUart2(buf, 10);
	i = strlen(buf);

	p = (char * )strchr(buf,'.');   //取得小数点的位置
	if(p!=NULL)
		i = i-(p-buf+1);
	tmp = atof(buf);
	for(j=0;j<i;j++)
		tmp = tmp *10;
	*num = i;

	return ((unsigned int) tmp);
}*/

//init GPS receive var
void InitGpsVar()
{
       // gGpsReadPoint =1;
       // gGpsWritePoint = 1;
        gGpsOk= 0;
        gGpsRcvCnt=0;
        gGpsActiveNum =100;
        mGpsFramePoint = 0;
        gGpsUartRead = 0;
        gGpsUartWrite = 0;
        gGpsUartNull = 1;
        InitQ(&gGpsRxQ, GPS_RX_SIZE , gGpsRxBuffer);
        //gMainNum=0;
}
//此函数的作用是什么? 超时的时间是否能够在函数的参数中指明??
void  TimeOut(void)
{
        if(GpsData.time!=0)
        {
		    //单点布警时间超时,返回布警失败

		    //黑匣子存储间隔
		    if(s_StateMsg.STATE.STATEBIT.BOX==1)
		    {
		    	if((GpsData.time-gBoxTimeStart)>s_StateMsg.BoxInterval)
		    	{
		    		gBoxTimeStart = GpsData.time;
		    		gBoxFlag = TRUE;
		    	}
		    }

		    //定时回报间隔
		    if(s_StateMsg.STATE.STATEBIT.FIXTIME==1)
		    {
		    	if((GpsData.time-gFixTimeStart)>s_StateMsg.FixTime)
		    	{
		    		if(gFixTimeStart!=0)
		    		{
		    			gFixTimeTxFlag = TRUE;
		    			gFixTimeStart = GpsData.time;
		    		}
		    		else
		    		{
		    			gFixTimeStart = GpsData.time;
		    	    }
		    	}
		    }
		    /*if(gFixTimeFlag)
		    {
		    	if(gFixTime>0)
		    	{
		    		gFixTime--;
		    	}
		    	else
		    	{
		    		gFixTimeTxFlag = TRUE;
		    		gFixTimeFlag = FALSE;
		    		gFixTime = s_StateMsg.FixTime;
		    	}
		    }*/
		    //显示部分GPS数据定时上传
		    if(s_Disp.STATE.STATEBIT.Disp_GpsFlag==1)
		    {
		    	if((GpsData.time-gDispGpsTimeStart)>s_Disp.Disp_GpsInterval)
		    	{
		    		gDisp_GpsTxFlag = TRUE;
		    		gDispGpsTimeStart = GpsData.time;
		    	}
		    }
		    /*
		    if(gDisp_GpsFlag)
		    {
		    	gDisp_GpsCounter++;
		    	if(gDisp_GpsCounter>s_Disp.Disp_GpsInterval)
		    	{
		    		gDisp_GpsFlag = FALSE;
		    		gDisp_GpsCounter = 0;
		    		gDisp_GpsTxFlag = TRUE;
		    	}
		    }
		    */
		    //显示部分状态信息定时上传
		    if(s_Disp.STATE.STATEBIT.Disp_StateFlag==1)
		    {
		    	if((GpsData.time-gDispStateTimeStart)>s_Disp.Disp_StateInterval)
		    	{
		    		gDisp_StateTxFlag = TRUE;
		    		gDispStateTimeStart = GpsData.time;
		    	}
		    }
		    /*
		    if(gDisp_StateFlag)
		    {
		    	gDisp_StateCounter++;
		    	if(gDisp_StateCounter>s_Disp.Disp_StateInterval)
		    	{
		    		gDisp_StateFlag = FALSE;
		    		gDisp_StateCounter = 0;
		    		gDisp_StateTxFlag = TRUE;
		    	}
		    }
		    */
		    //显示部分校时信息定时上传
		    if(s_Disp.STATE.STATEBIT.Disp_ChkTimeFlag==1)
		    {
		    	if((GpsData.time-gDispChkTimeStart)>s_Disp.Disp_ChkTimeInterval)
		    	{
		    		gDisp_ChkTimeTxFlag = TRUE;
		    		gDispChkTimeStart = GpsData.time;
		    	}
		    }
		    /*
		    if(gDisp_ChkTimeFlag)
		    {
		    	gDisp_ChkTimeCounter++;
		    	if(gDisp_ChkTimeCounter>s_Disp.Disp_ChkTimeInterval)
		    	{
		    		gDisp_ChkTimeFlag = FALSE;
		    		gDisp_ChkTimeCounter = 0;
		    		gDisp_ChkTimeTxFlag = TRUE;
		    	}
		    }
		    */
		}
}

void GpxStrToDate(const char * Sbuf,unsigned char * mYear,unsigned char * mMonth,unsigned char * mDay)
{

	unsigned char xdata buf[3];

	memset(buf, 0,3);
	memcpy(buf,Sbuf, 2);
	*mDay = atoi((const char * )buf);   //计算日

	memset(buf, 0,3);
	memcpy(buf,Sbuf+2, 2);
	*mMonth = atoi((const char * )buf); //计算月

	memset(buf, 0,3);
	memcpy(buf,Sbuf+4, 2);
	*mYear = atoi((const char * )buf);  //计算年

}

//如果只是在本文件中使用的,是否采用 local前缀??
unsigned char StrStr(unsigned char * s1,unsigned char * s2)
{

   unsigned int  i,j=0,k=0;
    while ( s1[j] ) {
        for ( i = 0,k=j; s1[k] && s2[i] && (s1[k] == s2[i]); i++,k++);
        if (s2[i] == '\0')
            return (1);
        j++;
    }
    return (0);

}




void GpxStrToTime(const char * Sbuf,unsigned char * mHour,unsigned char * mMinute,unsigned char * mSecond)
{
	unsigned char xdata buf[3];
	memset(buf, 0,3);
	memcpy(buf,Sbuf, 2);
	*mHour = atoi((const char * )buf);     //计算小时

	memset(buf, 0,3);
	memcpy(buf,Sbuf+2, 2);
	*mMinute = atoi((const char * )buf);   //计算分

	memset(buf, 0,3);
	memcpy(buf,Sbuf+4, 2);
	*mSecond = atoi((const char * )buf);   //计算秒

}

//==========================================
//===此函数负责分离出各字段=================
//==========================================
int SeperateOutData1(unsigned char* mBuf)
{
	unsigned char * p,*q;
	int i,Return_Num;
	Return_Num=0;
	for(i=0;i<=30;i++)
	{
		memset(mReturn[i],0,11);//清空缓冲区
 	}
	p = mBuf;
	p++;//去掉$
	q=(unsigned char *)strchr((const char *)p,',');//查找第一个逗号
	while(q!=NULL)
	{
		if(q!=NULL)
		{
			if((q-p)<=10)
			{
				//if((q-p)!=1)
			    memcpy(mReturn[Return_Num],p,q-p);
			}
		}
		p=q+1;
		q=(unsigned char *)strchr((const char *)p,',');
		Return_Num+=1;
		if(Return_Num>30) break;
	}
	return Return_Num;

}
//校验的结果应该采用结构指针的方式返回。 对此函数的功能进行具体的描述。并给出
//这个函数的流程图。
void AnalyGpsData()
{
	int len,i;
    double mDoubleTmp;
    unsigned char flag, tmp;
    unsigned long mLongTmp;
   // float  mFloatTmp;
	unsigned char xorNum;
	unsigned char xorResualt;
	unsigned char buf[3]={0};
	unsigned char mGpsReceiveAFrame;   //是否收到一个完整的GPS语句
       // unsigned char xdata   mGpsWritePoint ;
    mGpsReceiveAFrame=0;
    flag = ReadQ(&gGpsRxQ, &tmp);
	while(flag==1)
	{
        // SendToUart0Buffer(COMM1, &tmp,1) ;
        //memset(mGpsFrameBuf,0,150);
		if(mGpsFramePoint>99) mGpsFramePoint = 0;//防止缓冲区溢出
		if(tmp=='$')  //包头
		{
			mGpsFramePoint=0;
            gGpsReceiveHead=1;
 			mGpsFrameBuf[mGpsFramePoint++] = tmp;
		}
		else if(tmp=='\n')
		{
            if(gGpsReceiveHead==1)
            {
                mGpsFrameBuf[mGpsFramePoint++] = tmp;//收到帧尾
                //if(mGpsFramePoint>99) mGpsFramePoint = 0;
                //mGpsFrameBuf[mGpsFramePoint] = 0;
				mGpsReceiveAFrame = 1;
                gGpsReceiveHead = 0;
            }
			break;
		}
		else
		{
              if(gGpsReceiveHead==1)//如果收到了帧头则进行处理
              {
              		mGpsFrameBuf[mGpsFramePoint++] = tmp;
              }
 		}
        flag = ReadQ(&gGpsRxQ, &tmp);
	}
	if(mGpsReceiveAFrame==0) return;   //没有收到一个完整的帧则退出
	if(StrStr((unsigned char *)mGpsFrameBuf,gGPRMC)!=0) //收到GPRMC的处理 推荐定位信息
 	{
		TimeOut();
		gGpsActiveNum = 100;//复位GPS超时计数器
		memcpy(buf, mGpsFrameBuf+mGpsFramePoint-4, 2);//拷贝校验码
		if(buf[0]>='0' && buf[0]<= '9')
			xorResualt = (buf[0]-'0');
		else
			xorResualt = (buf[0]-'A'+10);
		xorResualt *=16;
		if(buf[1]>='0' && buf[1]<= '9')
			xorResualt += (buf[1]-'0');
		else
			xorResualt += (buf[1]-'A'+10);
		xorNum = mGpsFrameBuf[1];       //
		for(i=2;i<mGpsFramePoint-5;i++)
		{
			xorNum^=mGpsFrameBuf[i];     //进行校验
		}
		if(xorResualt !=  xorNum  )      //如果校验不通过,忽略改命令
		{
              mGpsFramePoint=0;
              return;
		}
        //TimeOut();
        //显示超时暂时注掉
        /*
        if(gGpsOk==0)
        {
        	gGpsOk=1;
        }*/
		len=SeperateOutData1(mGpsFrameBuf);
		if(mReturn[2][0] =='A')//判断是否有效定位
		{
			GpsData.avData  = 1;
		}
		else
        {
			GpsData.avData  = 0;
            //return;
        }
        mDoubleTmp= atof(&(mReturn[3][0]));//纬度
        mLongTmp= mDoubleTmp*10000 ;
        //mLongTmp=mLongTmp*10+6;
        GpsData.latitude = (unsigned long)mLongTmp;
        mDoubleTmp= atof(&(mReturn[5][0]));//经度
        mLongTmp= mDoubleTmp*10000 ;
        GpsData.longitude = (unsigned long)mLongTmp;
		GpxStrToTime((unsigned char*)&mReturn[1][0],&GpsData.hour,&GpsData.minute ,&GpsData.second );//时间
		GpxStrToDate((const char*)&mReturn[9][0],&GpsData.year,&GpsData.month ,&GpsData.day );//日期

        mLongTmp= FloatStringToUL(&(mReturn[7][0]),10,0);//速度
        //mLongTmp = mDoubleTmp*1.852;
        //mLongTmp = mDoubleTmp;
        GpsData.speed = (UINT)(mLongTmp);
        //GpsData.speed = atoi(&(mReturn[7][0]));//速度

		GpsData.direction = (UINT)FloatStringToUL(&(mReturn[8][0]),10,0);//方向
		GpsData.time = DateToSec(GpsData.year+2000,GpsData.month,GpsData.day,GpsData.hour,GpsData.minute,GpsData.second);
        mGpsFramePoint=0;
	}
/*	else if(StrStr((const char *)mGpsFrameBuf,"$GPGGA")!=0 )//收到GPGGA的处理
	{
        if(GpsData.avData  ==0) return;//如果数据无效则不处理
		memcpy(buf, mGpsFrameBuf+mGpsFramePoint-4, 2);//拷贝校验码
		if(buf[0]>='0' && buf[0]<= '9')
			xorResualt = (buf[0]-'0');
		else
			xorResualt = (buf[0]-'A'+10);
		xorResualt *=16;
		if(buf[1]>='0' && buf[1]<= '9')
			xorResualt += (buf[1]-'0');
		else
			xorResualt += (buf[1]-'A'+10);
		xorNum = mGpsFrameBuf[1];       //
		for(i=2;i<mGpsFramePoint-5;i++)
		{
			xorNum^=mGpsFrameBuf[i];     //进行校验

		}
                //mGpsFramePoint=0;
		if(xorResualt !=  xorNum  )      //如果校验不通过,忽略改命令
		{
			return;
		}
		len=SeperateOutData1(mGpsFrameBuf);
        mDoubleTmp= atof(&(mReturn[9][0]));    //经度
        mLongTmp= mDoubleTmp*10;
        mLongTmp=mLongTmp*10+1;
        GpsData.altitude = (unsigned long)mLongTmp;
		//GpsData.altitude = GpxStrToLong((const char*)&(mReturn[9]),&num);//高度
	    //	GpsData.altitude = GpsData.altitude*10+num;
        SendToUart2(mGpsFrameBuf, mGpsFramePoint);
        mGpsFramePoint=0;
		num=0;
	}  */
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -