急:请帮忙关于模拟gps数据以及虚拟端口的读写开发

jesperzx 2010-09-29 09:56:32
各位大侠,本人写了一个程序,是关于ppc手机基站定位的,现在已经实现了正常获取到基站的经纬度,打算在此基础上,把经纬度实时在第三方的gps地图上定位显示,如在凯立德、城际通等地图上显示,这样就达到了没有gps信号或者没有gps设备的情况下也可以很好的定位了。功能其实类似googleearth,不过google地图要长期联网,数据流量太大,而且速度很慢。现在需要解决的问题是:
1、如何把经纬度转换成可输出的gps格式nmea的数据
2、如何把已经转换的数据向第三方gps地图如凯立德输出。思路是通过模拟gps端口输出。
本人的已经找到一个c++的部分范例,但是本人却不懂c++,想用c#实现。另外对上述两点也不熟悉,万望各位大虾提供思路和帮助。
以下是我写的中文基站定位程序地址:
http://www.52dopod.net/viewthread.php?tid=369567&extra=
...全文
339 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
文斌 2010-09-30
  • 打赏
  • 举报
回复
1,只要把经纬度按NMEA0183协议组织出来就行了,建议可以只用RMC一种数据格式就够了。
2.只是写串口。不过第三方软件中要把串口设对。但问题会存在,比如如果你打开了串口写的时候,第三方软件可能无法再打开串口来读了,这个比较麻烦。
88csdn 2010-09-30
  • 打赏
  • 举报
回复
1、仔细参考GPS的相关文档,就那几种指令,不难
2、串口操作,打开COMx然后写数据,对应设置凯立德等软件的GPS数据读取端口
推荐使用Beeline等小型软件进行测试,自带GPS检测功能~~~
jesperzx 2010-09-30
  • 打赏
  • 举报
回复
以下这个是我看到的c++的代码,适用于虚拟出com端口并且发送数据的,他用了一个virtualcomnport.dll, 其实不虚拟这个端口行不行呢,直接向一个实际存在的端口写数据,不过可能就会第三方gps软件打开读的时候会出现问题了。有没有c#的程序啊,各位。
// CESeries.cpp: implementation of the CCESeries class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "CESeries.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//定义向写线程发送的消息常量
const UINT CM_THREADCOMMWRITE = WM_USER+110;

//类CCESeries构造函数
CCESeries::CCESeries()
{
m_hComm = INVALID_HANDLE_VALUE;

}

//类CCESeries析构函数
CCESeries::~CCESeries()
{

}

/*
*函数介绍:打开串口
*入口参数:pPortOwner :使用此串口类的窗体句柄
portNo :串口号
baud :波特率
parity :奇偶校验
databits :数据位
stopbits :停止位
*出口参数:(无)
*返回值:TRUE:成功打开串口;FALSE:打开串口失败
*/
BOOL CCESeries::OpenPort(CWnd* pPortOwner, /*使用串口类,窗体句柄*/
UINT portNo , /*串口号*/
UINT baud , /*波特率*/
UINT parity , /*奇偶校验*/
UINT databits , /*数据位*/
UINT stopbits /*停止位*/
)
{
DCB commParam;
TCHAR szPort[15];

// 已经打开的话,直接返回
if (m_hComm != INVALID_HANDLE_VALUE)
{
return TRUE;
}
ASSERT(pPortOwner != NULL);

// 虚拟串口
DWORD VirComNO = portNo;
HANDLE hRes = RegisterDevice (L"COM", VirComNO, L"VirtualComPort.dll", (DWORD) VirComNO);


//设置串口名
wsprintf(szPort, L"COM%d:", portNo);
//打开串口
m_hComm = CreateFile(
szPort,
GENERIC_READ | GENERIC_WRITE, //允许读和写
0, //独占方式(共享模式)
NULL,
OPEN_EXISTING, //打开而不是创建(创建方式)
0,
NULL
);

if (m_hComm == INVALID_HANDLE_VALUE)
{
// 无效句柄,返回。
TRACE(_T("CreateFile 返回无效句柄"));
return FALSE;

}

// 得到打开串口的当前属性参数,修改后再重新设置串口。
// 设置串口的超时特性为立即返回。

if (!GetCommState(m_hComm,&commParam))
{
return FALSE;
}

commParam.BaudRate = baud; // 设置波特率
commParam.fBinary = TRUE; // 设置二进制模式,此处必须设置TRUE
commParam.fParity = TRUE; // 支持奇偶校验
commParam.ByteSize = databits; // 数据位,范围:4-8
commParam.Parity = NOPARITY; // 校验模式
commParam.StopBits = stopbits; // 停止位

commParam.fOutxCtsFlow = FALSE; // No CTS output flow control
commParam.fOutxDsrFlow = FALSE; // No DSR output flow control
commParam.fDtrControl = DTR_CONTROL_ENABLE;
// DTR flow control type
commParam.fDsrSensitivity = FALSE; // DSR sensitivity
commParam.fTXContinueOnXoff = TRUE; // XOFF continues Tx
commParam.fOutX = FALSE; // No XON/XOFF out flow control
commParam.fInX = FALSE; // No XON/XOFF in flow control
commParam.fErrorChar = FALSE; // Disable error replacement
commParam.fNull = FALSE; // Disable null stripping
commParam.fRtsControl = RTS_CONTROL_ENABLE;
// RTS flow control
commParam.fAbortOnError = FALSE; // 当串口发生错误,并不终止串口读写

if (!SetCommState(m_hComm, &commParam))
{
TRACE(_T("SetCommState error"));
return FALSE;
}


//设置串口读写时间
COMMTIMEOUTS CommTimeOuts;
GetCommTimeouts (m_hComm, &CommTimeOuts);
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 10;
CommTimeOuts.WriteTotalTimeoutConstant = 1000;

if(!SetCommTimeouts( m_hComm, &CommTimeOuts ))
{
TRACE( _T("SetCommTimeouts 返回错误") );
return FALSE;
}

m_pPortOwner = pPortOwner;

//指定端口监测的事件集
SetCommMask (m_hComm, EV_RXCHAR);

//分配设备缓冲区
SetupComm(m_hComm,512,512);

//初始化缓冲区中的信息
PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);

m_hReadCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
//创建读串口线程
m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID);

TRACE(_T("串口打开成功"));

return TRUE;
}

/*
*函数介绍:关闭串口
*入口参数:(无)
*出口参数:(无)
*返回值: (无)
*/
void CCESeries::ClosePort()
{
//表示串口还没有打开
if (m_hComm == INVALID_HANDLE_VALUE)
{
return ;
}

//关闭读线程
CloseReadThread();

//关闭串口
if (!CloseHandle (m_hComm))
{
m_hComm = INVALID_HANDLE_VALUE;
return ;
}
}


/*
*函数介绍:向串口发送数据
*入口参数:buf : 将要往串口写入的数据的缓冲区
bufLen : 将要往串口写入的数据的缓冲区长度
*出口参数:(无)
*返回值:TRUE:表示成功地将要发送的数据写入到串口。
FALSE:表示将要发送的数据写入到串口失败。
*/
BOOL CCESeries::WritePort(const BYTE *buf,DWORD bufLen)
{
BOOL fWriteStat;
DWORD dwErrorFlags;
DWORD dwError;
COMSTAT ComStat;
DWORD ret = 0;

if(m_hComm == INVALID_HANDLE_VALUE)
{
return FALSE;//串口未打开
}

fWriteStat = WriteFile(m_hComm, buf, (DWORD)bufLen, &ret, NULL);

if( !fWriteStat )
{
//不能写数据
TRACE(TEXT("Can't Write String to Comm\n"));
ret=0;

if(GetLastError() == ERROR_IO_PENDING)
{
dwError = GetLastError();
// an error occurred, try to recover
ClearCommError(m_hComm, &dwErrorFlags, &ComStat ) ;
}
else
{
// some other error occurred
ClearCommError(m_hComm, &dwErrorFlags, &ComStat ) ;
return FALSE;
}
return FALSE;
}

return TRUE;
}

/*
*函数介绍:设置串口读取、写入超时
*入口参数:CommTimeOuts : 指向COMMTIMEOUTS结构
*出口参数:(无)
*返回值:TRUE:设置成功;FALSE:设置失败
*/
BOOL CCESeries::SetSeriesTimeouts(COMMTIMEOUTS CommTimeOuts)
{
ASSERT(m_hComm != INVALID_HANDLE_VALUE);
return SetCommTimeouts(m_hComm,&CommTimeOuts);
}


//串口读线程函数
DWORD CCESeries::ReadThreadFunc(LPVOID lparam)
{
CCESeries *ceSeries = (CCESeries*)lparam;

DWORD evtMask;
BYTE * readBuf = NULL;//读取的字节
DWORD actualReadLen=0;//实际读取的字节数
DWORD willReadLen;

DWORD dwReadErrors;
COMSTAT cmState;

// 清空缓冲,并检查串口是否打开。
ASSERT(ceSeries->m_hComm !=INVALID_HANDLE_VALUE);


//清空串口
PurgeComm(ceSeries->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR );

SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
while (TRUE)
{
if (WaitCommEvent(ceSeries->m_hComm,&evtMask,0))
{
SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
//表示串口收到字符
if (evtMask & EV_RXCHAR)
{

ClearCommError(ceSeries->m_hComm,&dwReadErrors,&cmState);
willReadLen = cmState.cbInQue ;
if (willReadLen <= 0)
{
continue;
}

readBuf = new BYTE[willReadLen];
ReadFile(ceSeries->m_hComm, readBuf, willReadLen, &actualReadLen,0);

//如果读取的数据大于0,
if (actualReadLen>0)
{
//触发读取回调函数
ceSeries->m_OnSeriesRead(ceSeries->m_pPortOwner,readBuf,actualReadLen);
}
}
}
//如果收到读线程退出信号,则退出线程
if (WaitForSingleObject(ceSeries->m_hReadCloseEvent,500) == WAIT_OBJECT_0)
{
break;
}
}
return 0;
}

//关闭读线程
void CCESeries::CloseReadThread()
{
SetEvent(m_hReadCloseEvent);
//设置所有事件无效无效
SetCommMask(m_hComm, 0);
//清空所有将要读的数据
PurgeComm( m_hComm, PURGE_RXCLEAR );
//等待10秒,如果读线程没有退出,则强制退出
if (WaitForSingleObject(m_hReadThread,10000) == WAIT_TIMEOUT)
{
TerminateThread(m_hReadThread,0);
}
m_hReadThread = NULL;
}

7,655

社区成员

发帖
与我相关
我的任务
社区描述
Windows Phone是微软发布的一款手机操作系统,它将微软旗下的Xbox LIVE游戏、Zune音乐与独特的视频体验整合至手机中。
社区管理员
  • Windows客户端开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧