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

📄 gps_receive c++.c

📁 这是一个基于ARM7的GPS处理源代码
💻 C
字号:

/*GPS的每帧数据以'$'开始,以'\r\n'结尾。中间以','分隔每字段。
需要处理的帧数据有:分别以"$GPRMC", "$GPGGA","$GPGSV"开始的数据帧。
只需将经度、纬度、卫星个数、速度等字段取出保存即可。

1、GPRMC
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,*hh<CR><LF>
<1>定位时UTC时间hhmmss 格式
<2>状态A=定位V=导航
<3>纬度dd mm mmmm 格式(非0)
<4>纬度方向 N或S
<5>经度ddd mm mmmm 格式(非0)
<6>经度方向E或W
<7>速率
<8>方位敬爱(二维方向指向,相当于二维罗盘)
<9>当前UTC日期ddmmyy 格式
<10>太阳方位
<11>太阳方向

2、GPGGA
$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M, <11>,<12>*hh<CR><LF>
<1>UTC时间,hh mm ss格式(定位它的)
<2>纬度dd mm mmmm 格式(非0)
<3>纬度方向 N或S
<4>经度ddd mm mmmm 格式(非0)
<5>经度方向E或W
<6>GPS状态批示0-未定位 1-无差分定位信息 2-带差分定位信息
<7>使用卫星号(00~08)
<8>精度百分比
<9>海平面高度
<10>*大地随球面相对海平面的高度
<11>差分GPS信息
<12>差分站ID号 0000-123

3、GPGSV
$GPGSV,<1>,<2>,<3>,<4>,<5>,<6>,<7><4>,<5>,<6>,<7>*hh<CR><LF>
<1>GSV语句的总数目
<2>当前GSV语句数目
<3>显示卫星的总数目00~12
<4>卫星的PRV号星号
<5>卫星仰角
<6>卫星旋角
<7>信操比             */

//4、参考代码
void CThreadGPS::DealWithRecv(std::deque<unsigned char>& _dRecvBuf)
{
	assert(GetCurrentThreadId() == m_dwThreadId);
	std::deque<unsigned char>::iterator iter, iterbegin, iterend;
	iterbegin = _dRecvBuf.begin();
	iterend   = _dRecvBuf.begin();
	for (iter = _dRecvBuf.begin(); iter != _dRecvBuf.end(); ++iter)
	{
		if (*iter == '$')							// 开始符
		{
			iterbegin = iter;
		}
		else if ((iter - iterbegin)	>= 2 &&	*(iter-1)	== '\r' &&	*iter	== '\n')// 结束符
		{
			iterend = iter + 1;
			if (iterend > iterbegin)
			{
				m_strFrame.erase();
				std::deque<unsigned char>::iterator i;
				for (i = iterbegin; i != iterend-2; ++i)
				{
					m_strFrame += *i;
				}
				DealWithFrame(m_strFrame);
			}
		}
	}
	_dRecvBuf.erase(_dRecvBuf.begin(), iterend);
}

void CThreadGPS::DealWithFrame(std::string& _strFrame)
{
	assert(GetCurrentThreadId() == m_dwThreadId);
	std::string strTemp;
	//*********************************
	std::string strSign;	//hdw
	//*********************************
	//////////////////////////////////////////////////////////////////////////
	// 记录前一个点,用来判断是否移动了
	m_ptGPSpre.dLon = m_stGPSDataTemp.dLon;
	m_ptGPSpre.dLat = m_stGPSDataTemp.dLat;

	if (_strFrame.find("$GPRMC") == 0)
	{
		//'****************************************************************
		//'        最简特性 (RMC)
		//'        $GPRMC、<1>、<2>、<3>、<4>、<5>、<6>、<7>、<8>、<9>、<10>、<11>、*hh<CR><LF>
		//'        <1>定位时UTC时间hhmmss 格式
		//'        <2>状态A=定位V=导航
		//'        <3>纬度dd mm mmmm 格式(非0)
		//'        <4>纬度方向 N或S
		//'        <5>经度ddd mm mmmm 格式(非0)
		//'        <6>经度方向E或W
		//'        <7>速率
		//'        <8>方位敬爱(二维方向指向,相当于二维罗盘)
		//'        <9>当前UTC日期ddmmyy 格式
		//'        <10>太阳方位
		//'        <11>太阳方向
		//'****************************************************************
		//读取经度
		if (ExtractSubString(strTemp,_strFrame.c_str(), 5, ','))
		{
			int iLon = atoi(strTemp.c_str()) / 100;
			double dLon = (atof(strTemp.c_str()) - iLon * 100) / 60.0+iLon;
			if (dLon != 0)
			{
				//hdw**************************************
				ExtractSubString(strSign,_strFrame.c_str(), 6, ',');
				if(strSign.find("W")==0)
					m_stGPSDataTemp.dLon = -1.0*dLon;//填充CGPS结构
				else
					m_stGPSDataTemp.dLon = dLon;//填充CGPS结构
			}
		}
		//读取纬度
		if (ExtractSubString(strTemp,_strFrame.c_str(), 3, ','))
		{
			int iLat = atoi(strTemp.c_str()) / 100;
			double dLat = (atof(strTemp.c_str()) - iLat * 100) / 60.0+iLat;
			if (dLat != 0)
			{
				//hdw**************************************
				ExtractSubString(strSign,_strFrame.c_str(), 4, ',');
				if(strSign.find("S")==0)
					m_stGPSDataTemp.dLat = -1*dLat;//填充CGPS结构
				else
					m_stGPSDataTemp.dLat = dLat;//填充CGPS结构
			}
		}
		//读取速率
		if (ExtractSubString(strTemp,_strFrame.c_str(), 7, ','))
		{
			m_stGPSDataTemp.fSpeed = atof(strTemp.c_str())*1.852;
		}
	}
	else if (_strFrame.find("$GPGGA") == 0) 
	{
		//'**************************************************************************
		//'GPGGA,083859,2214.495,N,11334.389,E,1,04,2.1,140.5,M,-3.1,M,,*5E
		//'$GPGGA、<1>、<2>、<3>、<4>、<5>、<6>、<7>、<8>、<9>、M, <11>、<12>*hh<CR><LF>
		//'    <1>UTC时间,hh mm ss格式(定位它的)
		//'    <2>纬度dd mm mmmm 格式(非0)
		//'    <3>纬度方向 N或S
		//'    <4>经度ddd mm mmmm 格式(非0)
		//'    <5>经度方向E或W
		//'    <6>GPS状态批示0-未定位 1-无差分定位信息 2-带差分定位信息
		//'    <7>使用卫星号(00~08)
		//'    <8>精度百分比
		//'    <9>海平面高度
		//'    <10>*大地随球面相对海平面的高度
		//'    <11>差分GPS信息
		//'    <12>差分站ID号 0000-123
		//'**************************************************************************
		//读取经度
		if (ExtractSubString(strTemp,_strFrame.c_str(), 4, ','))
		{
			int iLon = atoi(strTemp.c_str()) / 100;   // "STDLIB.H"         //atoi() 把字符串转成整数
			double dLon = (atof(strTemp.c_str()) - iLon * 100) / 60.0+iLon; //atof() 把字符串换成双精度数
			if (dLon != 0)
			{
				//hdw**************************************
				ExtractSubString(strSign,_strFrame.c_str(), 6, ',');
				if(strSign.find("W")==0)
					m_stGPSDataTemp.dLon = -1.0*dLon;//填充CGPS结构
				else
					m_stGPSDataTemp.dLon = dLon;//填充CGPS结构
			}
		}
		//读取纬度
		if (ExtractSubString(strTemp,_strFrame.c_str(), 2, ','))
		{
			int iLat = atoi(strTemp.c_str()) / 100;
			double dLat = (atof(strTemp.c_str()) - iLat * 100) / 60.0+iLat;
			if (dLat != 0)
			{
				//hdw**************************************
				ExtractSubString(strSign,_strFrame.c_str(), 4, ',');
				if(strSign.find("S")==0)
					m_stGPSDataTemp.dLat = -1*dLat;//填充CGPS结构
				else
					m_stGPSDataTemp.dLat = dLat;//填充CGPS结构
			}
		}
		//读取海平面高度
		if (ExtractSubString(strTemp,_strFrame.c_str(),9,','))
		{
			m_stGPSDataTemp.fHeight = atof(strTemp.c_str());
		}
	}
	else if (_strFrame.find("$GPGSV") == 0) 
	{
		//'******************************************************************
		//'        当前GPS卫星状态 (GSV)
		//'        $GPGSV、<1>、<2>、<3>、<4>、<5>、<6>、<7><4>、<5>、<6>、<7>*hh<CR><LF>
		//'        <1>GSV语句的总数目
		//'        <2>当前GSV语句数目
		//'        <3>显示卫星的总数目00~12
		//'        <4>卫星的PRV号星号
		//'        <5>卫星      仰角
		//'        <6>卫星      旋角
		//'        <7>信操比
		//'******************************************************************
		//读取卫星的总数目00~12
		if (ExtractSubString(strTemp,_strFrame.c_str(),3,','))
		{
			m_stGPSDataTemp.chState = char(atoi(strTemp.c_str()));
		}
	}

	//////////////////////////////////////////////////////////////////////////
	// 判断是否移动了
	if((m_ptGPSpre.dLat-m_stGPSDataTemp.dLat>0.0000001 || m_ptGPSpre.dLat-m_stGPSDataTemp.dLat<-0.0000001)
		||(m_ptGPSpre.dLon-m_stGPSDataTemp.dLon>0.0000001 || m_ptGPSpre.dLon-m_stGPSDataTemp.dLon<-0.0000001))
	{
		// 改变了
		::EnterCriticalSection(&m_syncGPSData);
		m_stGPSData = m_stGPSDataTemp;
		::LeaveCriticalSection(&m_syncGPSData);

		// 通知主模块去读取
		assert(m_hWndRecv);
		assert(m_uMsgGPSPoint);
		if (!::PostMessage(m_hWndRecv, m_uMsgGPSPoint, 0, 0))
		{
			assert(false);
		}

		// 通知接收线程保存成文件
		assert(m_dwRecvThreadId);
		assert(m_uMsgRecvThreadSaveGPS);
		if (!::PostThreadMessage(m_dwRecvThreadId, m_uMsgRecvThreadSaveGPS, 0, 0))
		{
			assert(false);
		}
	}
}

// 取得由分隔符分隔的子字符串
bool CThreadGPS::ExtractSubString(std::string& rString, const char* lpszFullString,int iSubString, char chSep)
{
	if (lpszFullString == NULL)
		return false;

	while (iSubString--)
	{
		lpszFullString = strchr(lpszFullString, chSep);
		if (lpszFullString == NULL)
		{
			return false;
		}
		lpszFullString++;       // point past the separator
	}
	char* lpchEnd = strchr(lpszFullString, chSep);
	int nLen = (lpchEnd == NULL) ?
				strlen(lpszFullString) : (int)(lpchEnd - lpszFullString);
	assert(nLen >= 0);
	rString.assign(lpszFullString, nLen);
	return true;
}
	// 接收数据
	CSerialToThread m_SerialToThread;								// 串口
	enum {m_RecvBufLen = 1024};										// 接收串口缓冲区的大小
	unsigned char m_byRecvBuf[m_RecvBufLen];						// 接收串口缓冲区
	std:: deque<unsigned char> m_dRecvBuf;							// 接收串口缓冲区队列
	std:: string m_strFrame;			// 从上队列分解出来的一帧数据。GPS数据是字符串

	//////////////////////////////////////////////////////////////////////////
	//
	HWND m_hWndRecv;												// 

⌨️ 快捷键说明

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