📄 nmeamsgdlg.cpp
字号:
// NMEAMsgDlg.cpp : implementation file
//
#include "stdafx.h"
#include "NMEAMsg.h"
#include "NMEAMsgDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define BUFFERSIZE 256
#define METHOD_BUFFERED 0x0
#define FILE_ANY_ACCESS 0x0
#define FILE_DEVICE_SERIAL_PORT 0x0000001b
#define CTL_CODE(DeviceType, Function, Method, Access) (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
#define IOCTL_SERIAL_AGPS_UPDATE_ON CTL_CODE(FILE_DEVICE_SERIAL_PORT,100,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_AGPS_UPDATE_OFF CTL_CODE(FILE_DEVICE_SERIAL_PORT,101,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_AGPS_RESET_ON CTL_CODE(FILE_DEVICE_SERIAL_PORT,102,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_AGPS_RESET_OFF CTL_CODE(FILE_DEVICE_SERIAL_PORT,103,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_GPS_POWER_ON CTL_CODE(FILE_DEVICE_SERIAL_PORT,104,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_GPS_POWER_OFF CTL_CODE(FILE_DEVICE_SERIAL_PORT,105,METHOD_BUFFERED,FILE_ANY_ACCESS)
typedef enum {
// We're reading something other than a sentence (can't parse until we hit $)
PARSE_STATE_UNKNOWN,
// We're currently reading contents of a sentence
PARSE_STATE_IN_SENTENCE,
// We've hit a '\r' in string. '\n' must be next for this sentence to be legit
PARSE_STATE_FOUND_CR
} PARSE_STATE;
// Character delimeters in NMEA string
const CHAR cSentenceStart = '$';
const CHAR cCR = '\r';
const CHAR cLF = '\n';
HANDLE hCPort;
BOOL OKToRun=TRUE;
DWORD WINAPI ReadNMEAThread(LPVOID lpParameter);
/////////////////////////////////////////////////////////////////////////////
// CNMEAMsgDlg dialog
CNMEAMsgDlg::CNMEAMsgDlg(CWnd* pParent /*=NULL*/)
: CDialog(CNMEAMsgDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CNMEAMsgDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CNMEAMsgDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CNMEAMsgDlg)
DDX_Control(pDX, IDC_LIST1, m_nmeaList);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CNMEAMsgDlg, CDialog)
//{{AFX_MSG_MAP(CNMEAMsgDlg)
ON_BN_CLICKED(IDC_BUTTON2, OnStart)
ON_BN_CLICKED(IDC_BUTTON3, OnExit)
ON_BN_CLICKED(IDC_BUTTON1, OnSetting)
ON_BN_CLICKED(IDC_BUTTON5, OnPowerOn)
ON_BN_CLICKED(IDC_BUTTON4, OnPowerOff)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CNMEAMsgDlg message handlers
BOOL CNMEAMsgDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
CenterWindow(GetDesktopWindow()); // center to the hpc screen
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CNMEAMsgDlg::OnStart()
{
// TODO: Add your control notification handler code here
HANDLE hReadNMEAThread;
logfile.Open(_T("\\Temp\\NMEAMessage.txt"),CFile::modeCreate | CFile::modeWrite, NULL);
hReadNMEAThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReadNMEAThread, (LPVOID)this, 0, NULL );
}
void CNMEAMsgDlg::OnExit()
{
// TODO: Add your control notification handler code here
OKToRun = FALSE;
HANDLE hEvent = CreateEvent(0,FALSE,FALSE,L"ReadNMEAMessage");
SetEvent(hEvent);
Sleep(100);
logfile.Close();
EndDialog(1);
}
void CNMEAMsgDlg::OnSetting()
{
// TODO: Add your control notification handler code here
}
void CNMEAMsgDlg::OnPowerOn()
{
// TODO: Add your control notification handler code here
DWORD dwRet;
DeviceIoControl (hCPort, IOCTL_SERIAL_GPS_POWER_ON, 0, 0, NULL, 0, &dwRet, NULL);
}
void CNMEAMsgDlg::OnPowerOff()
{
// TODO: Add your control notification handler code here
DWORD dwRet;
DeviceIoControl (hCPort, IOCTL_SERIAL_GPS_POWER_OFF, 0, 0, NULL, 0, &dwRet, NULL);
}
DWORD WINAPI ReadNMEAThread(LPVOID lpParameter)
{
//Open COM4
CNMEAMsgDlg* p = (CNMEAMsgDlg *)lpParameter;
TCHAR buf[256];
DCB dcb;
p->m_nmeaList.AddString(L"Open GPS COM port, please wait.");
hCPort = CreateFile(_T("COM2:"), // 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
Sleep(500);
memset (&dcb, 0, sizeof (dcb));
dcb.DCBlength = sizeof (dcb);
if (GetCommState(hCPort, &dcb) == 0)
{
DWORD err = GetLastError ();
wsprintf(buf, _T("Serial GetCommState: Failed for port %x err:%d"), hCPort, err);
::MessageBox(NULL,buf,_T("Error"),MB_OK);
}
dcb.BaudRate = 57600;
// dcb.BaudRate = 4800;
dcb.ByteSize = 8; // 8 data bits
dcb.StopBits = ONESTOPBIT;
dcb.Parity = NOPARITY;
dcb.fBinary = 1; // no EOF check
dcb.fOutX = 0; // no xon/xoff flow control on output
dcb.fInX = 0; // no xon/xoff flow control on input
dcb.fNull = 0; // no null stripping
dcb.fDtrControl = 0; // no DTR flow control
if (SetCommState(hCPort, &dcb) == 0)
{
DWORD err = GetLastError ();
wsprintf (buf, _T("SetCommState: Failed for port %x err:%d"), hCPort, err);
::MessageBox(NULL,buf,_T("Error"),MB_OK);
}
// check portID
if (hCPort == INVALID_HANDLE_VALUE )
{
wsprintf (buf, _T("Serial connect: Failed for port %x"), hCPort);
::MessageBox(NULL,buf,_T("Error"),MB_OK);
return FALSE;
}
Sleep(500);
BYTE pBuffer[BUFFERSIZE];
DWORD cbBuffer=BUFFERSIZE;
DWORD cbRead,dwMsgStart;
unsigned int i;
PARSE_STATE parseState;
HANDLE hEvent = CreateEvent(0,FALSE,FALSE,L"ReadNMEAMessage");
p->m_nmeaList.AddString(L"Waiting for NMEA message...");
while (OKToRun) {
WaitForSingleObject(hEvent, 1000);
BOOL fSuccess = ReadFile(hCPort,pBuffer,cbBuffer,&cbRead,NULL);
parseState = PARSE_STATE_UNKNOWN; // current state
for (i = 0; i < cbRead; i++) {
switch (parseState) {
case PARSE_STATE_UNKNOWN:
{
// Look for the '$' at beginning of sentence
if (pBuffer[i] == cSentenceStart) {
dwMsgStart = i;
parseState = PARSE_STATE_IN_SENTENCE;
}
}
break;
case PARSE_STATE_IN_SENTENCE:
{
// Keep reading in data until we get to \r to indicate sentence end.
if (pBuffer[i] == cCR) {
parseState = PARSE_STATE_FOUND_CR;
}
}
break;
case PARSE_STATE_FOUND_CR:
{
// Looking for \n at end of sentence.
if (pBuffer[i] == cLF) {
p->LogNMEAMsg(pBuffer+dwMsgStart,i-dwMsgStart+1);
}
else {
// This is not a valid NMEA string.
//DEBUGMSG(ZONE_PARSE,(L"GPS: NMEA string did not properly close string with \\r\\n tag\r\n"));
}
parseState = PARSE_STATE_UNKNOWN;
}
break;
default:
{
; // Should never be outside of one of 3 known states.
}
break;
}
}
}
CloseHandle(hCPort);
return TRUE;
}
BOOL CNMEAMsgDlg::LogNMEAMsg(BYTE* pBuffer,DWORD dwSize)
{
char pbNMEABuffer[BUFFERSIZE];
TCHAR pListBuf[BUFFERSIZE];
if(pBuffer[0] == '$' &&
pBuffer[1] == 'G' &&
pBuffer[2] == 'P')
{
memcpy(pbNMEABuffer,pBuffer,dwSize);
pbNMEABuffer[dwSize] = '\0';
mbstowcs(pListBuf, pbNMEABuffer, strlen(pbNMEABuffer)+1);
m_nmeaList.AddString(pListBuf);
m_nmeaList.SetCurSel(m_nmeaList.GetCount()-1);
//write to file
logfile.Write(pbNMEABuffer,strlen(pbNMEABuffer)+1);
logfile.Flush();
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -