📄 gpsdevice.cpp
字号:
// GPSDevice.cpp: implementation of the CGPSDevice class.
//
#include "stdafx.h"
#include "comm.h"
#include "GPSDevice.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CGPSDevice::CGPSDevice()
{
// Init handle to NULL
m_hPort = NULL;
m_hThread = NULL;
m_nPortNr=0;
m_hWnd=NULL;
m_strReceived="";
m_longitude="";
m_latitude="";
}
CGPSDevice::~CGPSDevice()
{
// release resources
//DWORD dwExitCode;
if(m_hPort !=NULL)
CloseHandle(m_hPort);
m_hPort = NULL;
if(m_hWnd!=NULL)
CloseHandle(m_hWnd);
m_hWnd = NULL;
/* Force Exit Thread.
if(m_hThread!=NULL)
{
GetExitCodeThread(m_hThread,&dwExitCode);
ExitThread(dwExitCode);
}
*/
StopReadThread();
m_hThread=NULL;
}
BOOL CGPSDevice::InitializePort(HWND hWnd,CString PortNum,UINT Baud, CString Parity, UINT DataBits, UINT StopBits)
{
CString Nnn;
// initialize critical section
InitializeCriticalSection(&m_cs);
// now it critical!
EnterCriticalSection(&m_cs);
// Empty Port Handle.
if(m_hPort!=NULL)
{
CloseHandle(m_hPort);
m_hPort = NULL;
}
if(m_hThread!=NULL)
{
CloseHandle(m_hThread);
m_hThread = NULL;
}
if(m_hWnd!=NULL)
{
CloseHandle(m_hWnd);
m_hWnd = NULL;
}
// format port num.
if(PortNum==L"COM1") m_nPortNr=1;
if(PortNum==L"COM2") m_nPortNr=2;
Nnn = PortNum + ":";
// set message Handle.
m_hWnd=hWnd;
// Clear RX Buffer.
// memset(m_RXBuff,0,512);
m_hPort = CreateFile (Nnn, // Pointer to the name of the port
GENERIC_READ | GENERIC_WRITE,
// Access (read-write) mode
0, // Share mode
NULL, // Pointer to the security attribute
OPEN_EXISTING, // How to open the serial port
0, // Port attributes
NULL); // Handle to port with attribute
// to copy
if (m_hPort == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("can't open port!"));
return FALSE;
}
// Get Comm DCB
if(!GetCommState(m_hPort,&m_dcb)) return FALSE;
// Set Comm DCB
m_dcb.BaudRate = Baud;
if(Parity == "NONE") m_dcb.Parity = 0;
if(Parity == "ODD") m_dcb.Parity = 1;
if(Parity == "EVEN") m_dcb.Parity = 2;
m_dcb.ByteSize = DataBits;
if(StopBits == 1) m_dcb.StopBits = ONESTOPBIT;
if(StopBits == 1.5) m_dcb.StopBits = ONE5STOPBITS;
if(StopBits == 2) m_dcb.StopBits = TWOSTOPBITS;
if(!SetCommState(m_hPort,&m_dcb)) return FALSE;
// Get Comm Timeouts
if(!GetCommTimeouts(m_hPort,&m_CommTimeouts)) return FALSE;
// Set Comm Timeouts
m_CommTimeouts.ReadIntervalTimeout = 500;
m_CommTimeouts.ReadTotalTimeoutMultiplier = 500;
m_CommTimeouts.ReadTotalTimeoutConstant = 1000;
m_CommTimeouts.WriteTotalTimeoutMultiplier = 500;
m_CommTimeouts.WriteTotalTimeoutConstant = 1000;
if(!SetCommTimeouts(m_hPort,&m_CommTimeouts))
return FALSE;
// Set Comm Mask
if(!SetCommMask(m_hPort,EV_RXCHAR | EV_CTS | EV_DSR | EV_RING))
return FALSE;
// flush the port
PurgeComm(m_hPort, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
// release critical section
LeaveCriticalSection(&m_cs);
return TRUE;
}
DWORD WINAPI CGPSDevice::GPSReadThread(LPVOID lpParam)
{
CGPSDevice *p=(CGPSDevice *)lpParam;
DWORD dwCommStatus = 0; // comm event
BOOL bResult = FALSE; // waitcommevent result
BOOL bClear = FALSE; // clearcomm result
BOOL bReadResult = FALSE; // readfile result
DWORD dwNumBytesRead = 0; // number readed
COMSTAT comstat; // COMSTAT struct
DWORD dwError; // error message
unsigned char RXBuff; // receive buffer
// check if the port is opened,then clear buffer first.
if (p->m_hPort)
PurgeComm(p->m_hPort, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
else
return 0;
// clear buffer again,maybe it is no necessary.
PurgeComm(p->m_hPort, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
while (1)
{
// Wait for an event to occur for the port.
bResult = WaitCommEvent (p->m_hPort, &dwCommStatus, NULL);
if (bResult && (dwCommStatus & EV_RXCHAR))
{
do
{
// now it critical!
EnterCriticalSection(&p->m_cs);
// Clear port Error message.
bClear = ClearCommError(p->m_hPort, &dwError, &comstat);
if(comstat.cbInQue ==0) break;
// clear RX Buffer and count
dwNumBytesRead = 0;
RXBuff = 0;
bReadResult = ReadFile(p->m_hPort , // Handle to COMM port
&RXBuff, // RX Buffer Pointer
1, // Read one byte
&dwNumBytesRead, // Stores number of bytes read
NULL);
// release critical section
LeaveCriticalSection(&p->m_cs);
// display data.
if(bReadResult && dwNumBytesRead == 1)
{
//SendMessage(p->m_hWnd,WM_COMM_RXCHAR,(WPARAM)RXBuff,(LPARAM)p->m_nPortNr);
p->m_strReceived+=CString(RXBuff);
}
}while(bReadResult && dwNumBytesRead == 1);
}
}
return 1;
}
BOOL CGPSDevice::ClosePort()
{
// Close Port Handle.
if(m_hPort!=NULL)
CloseHandle(m_hPort);
if(m_hWnd!=NULL)
CloseHandle(m_hWnd);
// Set port handle to NULL.
m_hPort=NULL;
m_hWnd=NULL;
// delete CRITICAL_SECTION
DeleteCriticalSection(&m_cs);
return TRUE;
}
BOOL CGPSDevice::StartReadThread()
{
DWORD dwThreadID;
// Start Comm Thread.
if(!(m_hThread=(HANDLE)CreateThread(NULL,0,GPSReadThread,this,0,&dwThreadID)))
return FALSE;
return TRUE;
}
BOOL CGPSDevice::WriteChar(char *buf)
{
DWORD dwNumBytesWritten;
BOOL bResult;
// Clear Comm Error
PurgeComm(m_hPort, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
// write to port.
bResult = WriteFile(m_hPort, // Handle to COMM Port
buf, // Pointer to message buffer in calling finction
strlen(buf), // Length of message to send
&dwNumBytesWritten, // Where to store the number of bytes sent
NULL);
if(!bResult || dwNumBytesWritten == 0) return FALSE;
return TRUE;
}
void CGPSDevice::StopReadThread()
{
DWORD dwExitCode; // thread exit code
UINT nError; // return error code
GetExitCodeThread(m_hThread,&dwExitCode); // get Exit code
nError = TerminateThread(m_hThread,dwExitCode); // stop and delete readthread
if(nError = 0)
{
TRACE(L"TerminateThread Fail");
// AfxMessageBox(L"TerminateThread Fail");
}
}
BOOL CGPSDevice::GetGPSInfo()
{
//while((m_strReceived.Find(0x0d)!=-1)&&(m_strReceived.Find(0x0a)!=-1))
//{
if((m_strReceived.Find(0x0d)==-1)&&(m_strReceived.Find(0x0a)==-1))
{
//AfxMessageBox(_T("cann't get GPS info"));
return FALSE;
}
int len=m_strReceived.GetLength();
int startLF=m_strReceived.Find(0x0a);
int endCR=m_strReceived.Find(0x0d);
if(startLF>endCR)
endCR=m_strReceived.Find(0x0d,startLF);
CString msg= m_strReceived.Mid(startLF+1,endCR-startLF-1);//
m_strReceived.Delete(0,endCR+1);
if(msg.Left(6).Compare(L"$GPRMC")!=0)
return FALSE;
msg.Delete(0,msg.Find(',')+1);
LPTSTR pTime=msg.GetBuffer(msg.GetLength()+1);
int hour,min,sec;
char temp[9];
memset(temp,0,9);
memcpy(temp,pTime,1);
memcpy(temp+1,pTime+1,1);
memcpy(temp+3,pTime+2,1);
memcpy(temp+4,pTime+3,1);
memcpy(temp+6,pTime+4,1);
memcpy(temp+7,pTime+5,1);
hour=atoi(temp);
min=atoi(temp+3);
sec=atoi(temp+6);
msg.ReleaseBuffer();
msg.Delete(0,msg.Find(',')+1);
if(msg.GetAt(0)!='A')
return FALSE;
msg.Delete(0,msg.Find(',')+1);
CString longitude=msg.Left(2);
longitude+="度";
longitude+=msg.Mid(2,6);
longitude+="分";
msg.Delete(0,msg.Find(',')+1);
if(msg.GetAt(0)=='N')
longitude.Insert(0,L"北纬");
if(msg.GetAt(0)=='S')
longitude.Insert(0,L"南纬");
msg.Delete(0,msg.Find(',')+1);
CString latitude=msg.Left(3);
latitude+=L"度";
latitude+=msg.Mid(3,6);
latitude+=L"分";
msg.Delete(0,msg.Find(',')+1);
if(msg.GetAt(0)=='E')
latitude.Insert(0,L"东经");
if(msg.GetAt(0)=='W')
latitude.Insert(0,L"西经");
msg.Delete(0,msg.Find(',')+1);
msg.Delete(0,msg.Find(',')+1);
msg.Delete(0,msg.Find(',')+1);
LPTSTR pDate=msg.GetBuffer(msg.GetLength()+1);
int day,mon,year;
memset(temp,0,9);
memcpy(temp,pDate,1);
memcpy(temp+1,pDate+1,1);
memcpy(temp+3,pDate+2,1);
memcpy(temp+4,pDate+3,1);
memcpy(temp+6,pDate+4,1);
memcpy(temp+7,pDate+5,1);
day=atoi(temp);
mon=atoi(temp+3);
year=atoi(temp+6);
if(year>40)
year+=1900;
else
year+=2000;
CTime t(year,mon,day,hour,min,sec);
msg.Delete(0,msg.Find(',')+1);
msg.ReleaseBuffer();
m_latitude=latitude;
m_longitude=longitude;
m_CurrentTime=t;
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -