【VC开源代码栏目提醒】:网学会员为需要VC开源代码的朋友们搜集整理了GPS.CPP相关资料,希望对各位网友有所帮助!
#include "stdafx.h"
#include "GPSManager.h"
#include "GPS.h"
#include "MainFrm.h"
#include "GPSManagerDoc.h"
#include "GPSManagerView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/*************************************************************************
*
* 函数名称:
* GPSDataProc()
*
* 参数:
* LPVOID lpVoid - 参数指针
*
* 返回值:
* UINT - 线程返回代码
*
* 说明:
* 本函数为线程处理函数,所完成的功能为异步数据接收
*
************************************************************************/
UINT GPSDataProc(LPVOID lpVoid)
{
CGPS* pGPS = (CGPS*)lpVoid;
if (pGPS == NULL)
return 1003;
// 参数复位
pGPS->ParamReset();
// GPS数据处理
pGPS->DoDataProc();
return 1004;
}
/////////////////////////////////////////////////////////////////////////////
// CGPS
CGPS::CGPS()
{
m_pView = NULL;
m_hCom = INVALID_HANDLE_VALUE;
m_hExitListenEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
ParamReset();
}
CGPS::~CGPS()
{
m_hCom = INVALID_HANDLE_VALUE;
m_pReadThread = NULL;
CloseHandle(m_hExitListenEvent);
}
BEGIN_MESSAGE_MAP(CGPS, CWnd)
//{{AFX_MSG_MAP(CGPS)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGPS message handlers
/*************************************************************************
*
* 函数名称:
* DoReadProc()
*
* 参数:
* 无
*
* 返回值:
* 无
*
* 说明:
* 对端口进行异步读取
*
************************************************************************/
void CGPS::DoDataProc()
{
// 中间变量
DWORD dwErrorMask;
DWORD dwEvtMask = 0;
// 清空缓冲区
memset(m_cFrameBuf, 0, sizeof(m_cFrameBuf));
// 串口状态结构对象
COMSTAT comstat;
// 异步结构对象
OVERLAPPED ov, ovEvent;
ov.Internal = 0;
ov.InternalHigh = 0;
ov.Offset = 0;
ov.OffsetHigh = 0;
ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
ovEvent.Internal = 0;
ovEvent.InternalHigh = 0;
ovEvent.Offset = 0;
ovEvent.OffsetHigh = 0;
ovEvent.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
// 设置事件驱动的类型
if (!SetCommMask(m_hCom, EV_RXCHAR | EV_TXEMPTY))
return;
while (true)
{
// 等待接收事件
if (WaitCommEvent(m_hCom, &dwEvtMask, &ovEvent) == FALSE)
{
if (GetLastError() == ERROR_IO_PENDING)
WaitForSingleObject(ovEvent.hEvent, INFINITE);
}
// 终止侦听线程
if (m_bExitListen == TRUE)
{
// 线程退出事件置位
SetEvent(m_hExitListenEvent);
return;
}
// 数据到达事件发生后进行接收处理
if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
{
do
{
// 确定接收缓冲中处于等待的字节数
ClearCommError(m_hCom, &dwErrorMask, &comstat);
if (comstat.cbInQue == 0)
break;
// 异步读取数据到帧缓冲
if (!ReadFile(m_hCom, m_cFrameBuf + m_dwPoint, comstat.cbInQue, &m_dwActRead, &ov))
{
if (GetLastError() == ERROR_IO_PENDING)
{
// 检测数据是否接收完毕
while (!GetOverlappedResult(m_hCom, &ov, &m_dwActRead, FALSE))
{
// 数据尚未接收完毕
if (GetLastError() == ERROR_IO_INCOMPLETE)
continue;
}
// 接收数据处理
RecvDataProc();
// 手动复位
ResetEvent(ov.hEvent);
}
}
else
{
// 接收数据处理
RecvDataProc();
// 手动复位
ResetEvent(ov.hEvent);
}
} while (comstat.cbInQue > 0);
}
}
}
/*************************************************************************
*
* 函数名称:
* OpenPort()
*
* 参数:
* CString sPort - 串口号("COM1","COM2","COM3","COM4")
* DWORD dwBaud - 波特率
*
* 返回值:
* BOOL - 打开成功与否
*
* 说明:
* 异步打开指定串口
*
************************************************************************/
BOOL CGPS::OpenPort(CString sPort, DWORD dwBaud)
{
// 打开串口
m_hCom = CreateFile(sPort,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
if (m_hCom == INVALID_HANDLE_VALUE)
return FALSE;
// 得到当前串口配置
DCB dcb;
dcb.DCBlength = sizeof(dcb);
GetCommState(m_hCom, &dcb);
// 基本配置
dcb.BaudRate = dwBaud;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
// 不使用DSR--DTR流控方式
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fNull = FALSE;
dcb.fAbortOnError = FALSE;
dcb.fTXContinueOnXoff = FALSE;
// 二进制传输
dcb.fBinary = TRUE;
// 配置串口设置
SetCommState(m_hCom, &dcb);
// 超时设置
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0 ;
CommTimeOuts.WriteTotalTimeoutMultiplier = 2 * 9600 / dcb.BaudRate;
CommTimeOuts.WriteTotalTimeoutConstant = 25;
SetCommTimeouts(m_hCom, &CommTimeOuts);
// 设置缓冲区大小
SetupComm(m_hCom, 8192, 8192);
// 开启数据接收线程
m_bExitListen = FALSE;
m_pReadThread = AfxBeginThread(GPSDataProc, this, THREAD_PRIORITY_TIME_CRITICAL);
return TRUE;
}
/*************************************************************************
*
* 函数名称:
* ClosePort()
*
* 参数:
* 无
*
* 返回值:
* BOOL - 端口成功关闭与否
*
* 说明:
* 结束正在进行的数据收发任务后关闭端口
*
************************************************************************/
BOOL CGPS::ClosePort()
{
// 关闭端口释放资源
if (m_hCom != INVALID_HANDLE_VALUE)
{
// 关闭侦听线程
m_bExitListen = TRUE;
TerminateRecv();
// 终止端口操作,清空缓冲区
PurgeComm(m_hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
CloseHandle(m_hCom);
// 端口复位
m_hCom = INVALID_HANDLE_VALUE;
}
return TRUE;
}
/*************************************************************************
*
* 函数名称:
* RecvDataProc()
*
* 参数:
* 无
*
* 返回值:
* 无
*
* 说明:
* 对接收数据的处理过程
*
************************************************************************/
void CGPS::RecvDataProc()
{
// 当前缓冲区末尾
m_dwPoint += m_dwActRead;
if (m_dwActRead == 0 || m_dwActRead + m_dwPoint < 30)
return;
if (m_bInfoStart == FALSE)
{
// 寻找GPS帧头
CString sData = (CString)m_cFrameBuf;
int nHead = sData.Find("$GPRMC", 0);
if ( nHead >= 0)
{
// 清除信息前的垃圾数据
for (DWORD i = nHead; i < m_dwPoint; i++)
m_cFrameBuf[i - nHead] = m_cFrameBuf[i];
m_dwPoint -= nHead;
m_dwActRead = 0;
m_cFrameBuf[m_dwPoint] = 0;
// 标记为找到帧头
m_bInfoStart = TRUE;
// LF个数清零
m_nLFNum = 0;
}
else
上一篇:
loupan.pas
下一篇:
群体性突发事件论文:“边界冲突”:农村群体性事件的县域分析