gpsviewerdlg.cpp
来自「GPS信号强度」· C++ 代码 · 共 342 行
CPP
342 行
/* GPSViewerDlg.cpp
* ----------------
* This file is the heart of the GPSViewer Application and demonstrates how to
* use the Centrality GPS NMEA interface located on COM7. Careful study of this
* code will allow the user to understand the methods needed to fully utilize
* the COM7 GPS port. This code is intended to be used as a fully functional
* sample for complete integration with the Centrality GPS platform and this
* purpose only. Debug statements have been commented out but left embedded in
* the code for development purposes.
*
* Here are the key steps that you should take note of as you walk through
* this code:
*
* 1. Using Createfile to open the COM7 port
* 2. Setting up the COM7 port
* 3. Creating a thread to wait on COM7 and read its contents
* 4. Parsing NMEA commands that come out of the COM7 port
* 5. Safely closing the port
*
* Author: Howard Shen, Centrality Communications MTS
* Date: 8/29/03
*/
#include "stdafx.h"
#include "GPSViewer.h"
#include "GPSViewerDlg.h"
#include "GPSExport.h"
#include "windows.h"
#include "math.h"
#include "stdlib.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/* Global Defines */
/* -------------- */
#define g_UpdateInterval 1000 // This is the update interval for the screen (in milliseconds)
/* Global variables */
/* ---------------- */
CString time, lat, latdir, lon, londir, numused, alt;
UINT g_allinit;
char buff[1000]; // Read buffer
UINT m_nTimer; // Timer for refreshing the screen
HANDLE comm_hand; // Global handle to the COM7 port
HANDLE nmeathread_hand; // Global handle to the NMEA reading thread
/* Function Prototypes */
/* ------------------- */
DWORD WINAPI ReadNMEAThread(LPVOID lpParameter);
// This is the function which contorls the NMEA reading thread
/* START of Microsoft Machine Generated Message Handler Code - DO NOT MODIFY */
/////////////////////////////////////////////////////////////////////////////
// CGPSViewerDlg dialog
CGPSViewerDlg::CGPSViewerDlg(CWnd* pParent /*=NULL*/)
: CDialog(CGPSViewerDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CGPSViewerDlg)
m_staticlong = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CGPSViewerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CGPSViewerDlg)
DDX_Text(pDX, IDC_STATIC_LONG, m_staticlong);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CGPSViewerDlg, CDialog)
//{{AFX_MSG_MAP(CGPSViewerDlg)
ON_WM_CANCELMODE()
ON_WM_TIMER()
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_CLOSE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// End of Microsoft machine generated code
/* Function: OnInitDialog()
* ------------------------
* This fucntion gets called at startup and initalizes the whole program.
* Initializing the COM port takes place here. Key steps (1), (2) ,and (3)
* take place in this function.
*/
BOOL CGPSViewerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
DCB commDCB;
COMMTIMEOUTS timeouts;
DWORD dwError;
ULONG bytesWritten;
// 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
// Key Step #1 - Using CreateFile to open COM7
// -------------------------------------------
comm_hand = CreateFile(L"COM7:", GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
if(comm_hand == NULL)
{
MessageBox (TEXT("Unable to open COM7."), TEXT("Error"), MB_OK);
dwError = GetLastError ();
DEBUGMSG(1, (L"Opening COM7 failed: %d!\r\n", (int)GetLastError()));
return TRUE;
}
commDCB.DCBlength = sizeof (DCB);
// Key Step #2 - Setting the COM7 port settings
// --------------------------------------------
// Get the default port setting information.
if(!GetCommState (comm_hand, &commDCB))
{
CloseHandle(comm_hand);
DEBUGMSG(1, (L"Failed in getting COM7 DCB settings: %d!\r\n", (int)GetLastError()));
return FALSE;
}
commDCB.DCBlength = sizeof(DCB);
commDCB.BaudRate = 38400; // Current baud
commDCB.ByteSize = 8; // Number of bits/bytes, 4-8
commDCB.Parity = NOPARITY; // 0-4=no,odd,even,mark,space
commDCB.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2
// Setting COM7 to Centrality speicifcations
if (!SetCommState(comm_hand, &commDCB))
{
CloseHandle(comm_hand);
MessageBox (TEXT("Unable to configure COM7 DCB settings"), TEXT("Error"), MB_OK);
DEBUGMSG(1, (L"Error in trying to set COM7 DCB settings: %d!\r\n", (int)GetLastError()));
dwError = GetLastError ();
return FALSE;
}
// Get the default timeout settings for port
if(!GetCommTimeouts(comm_hand, &timeouts))
{
CloseHandle(comm_hand);
DEBUGMSG(1, (L"Failed in getting COM7 timeout settings: %d!\r\n", (int)GetLastError()));
return FALSE;
}
DEBUGMSG(1, (L"DCB set successfully.\r\n"));
// Change the timeouts structure settings to Centrality settings
timeouts.ReadIntervalTimeout = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
// Set the time-out parameters for all read and write operations on the port.
if (!SetCommTimeouts(comm_hand, &timeouts))
{
CloseHandle(comm_hand);
MessageBox (TEXT("Unable to configure COM7 timeout settings"), TEXT("Error"), MB_OK);
DEBUGMSG(1, (L"Error in trying to set COM7 timeout settings: %d!\r\n", (int)GetLastError()));
dwError = GetLastError ();
return FALSE;
}
DEBUGMSG(1, (L"Comm timeouts set successfully.\r\n"));
// Key Step #3 - Creating a thread to wait on COM7 and read its contents
// ----------------------------------------------------------------------
// * See definition of ReadNMEAThread() for details on thread operations
nmeathread_hand = CreateThread(NULL, 0, ReadNMEAThread, NULL, 0, NULL);
if(!nmeathread_hand)
{
DEBUGMSG(1, (L"Could not create NMEA read thread.\r\n"));
return 0;
}
m_nTimer = SetTimer(1, g_UpdateInterval, 0);
g_allinit = 1;
// Writing something to the COM7 port to start GPS processing (Added March 2004)
// -----------------------------------------------------------------------------
if(!WriteFile(comm_hand, (L"StartGPS!\r\n"), 20, &bytesWritten, NULL))
{
DEBUGMSG(1, (L"Could not write message to COM7 to start GPS.\r\n"));
}
DEBUGMSG(1, (L"GPS started! Bytes written: %d.\r\n", bytesWritten));
return TRUE;
}
/* Function: OnCancelMode()
* ------------------------
* This fucntion gets called to deinitialize the GPSViewer. Notice that you
* should wait for the NMEA reading thread to exit cleanly before continuing.
* Key step (5) is covered by this function.
*/
void CGPSViewerDlg::OnCancelMode()
{
CDialog::OnCancelMode();
if(g_allinit == 1) {
DEBUGMSG(1, (L"Cancel application. Shutting down.\r\n"));
SetCommMask(comm_hand, 0);
// Wait for NMEA reading thread to cleanly exit (max 5 sec)
WaitForSingleObject(nmeathread_hand, 5000);
KillTimer(m_nTimer);
// This call officially closes the COM7 and shuts down GPS.
CloseHandle(comm_hand);
g_allinit = 0;
} else {
DEBUGMSG(1, (L"Trying to cancel, but nothing was started. Exiting.\r\n"));
}
}
/* Function: OnNotify()
* ------------------------
* This fucntion is not vital to the opertaions of GPS but needs to exist
* for Microsoft EVC programs. There is no need to modify/study this function.
*/
BOOL CGPSViewerDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// TODO: Add your specialized code here and/or call the base class
return CDialog::OnNotify(wParam, lParam, pResult);
}
/* Function: OnNotify()
* --------------------
* This fucntion's only purpose is to force the application to redraw the
* output at the interval specified by g_UpdateInterval. It's not that
* important.
*/
void CGPSViewerDlg::OnTimer(UINT nIDEvent)
{
//MessageBeep(0xFFFFFFFF); // Beep
DEBUGMSG(1, (L"Timer Signled."));
Invalidate();
UpdateWindow();
CDialog::OnTimer(nIDEvent);
}
/* Function: ReadNMEAThread()
* --------------------------
* This is the function responsible for reading the GPS NMEA port (COM7)
* and parsing the output - key step (4). Basically, this function sets
* up to read the COM port whenever an event is passed down by the GPS
* NMEA driver. This event is the simple EV_RXCHAR. You must first set up
* the function to wait on this even (4a) and then read from the port when
* the event is signified (4b). After reading information out of the port,
* you must then parse it to extract the needed location/satellite
* information (4c). You will notice that all the information needed
* by GPSViewer is contained in the $GPGGA NMEA message. You are obviously
* free to do use whatever information you need that is supported by the
* NMEA standard. If you need other mesages to be supported by Centrality
* Communications, please contact your local representative.
*/
DWORD WINAPI ReadNMEAThread(LPVOID lpParameter)
{
int start, endline, onestart, oneend, length, linelen, degdig;
ULONG bytesRead;
DWORD EventMask = EV_RXCHAR;
// Setting the CommMask to listen for this event (4a)
SetCommMask(comm_hand, EV_RXCHAR);
// Wait on the event
while(WaitCommEvent(comm_hand, &EventMask, NULL))
{
// Clear the buffer before you start reading
memset(buff, 0, 1000);
// Read from COM7 (4b)
while(ReadFile(comm_hand, buff, 1000, &bytesRead, NULL))
{
if(bytesRead == 0)
break;
CString dacstr(buff);
DEBUGMSG(1, (L"bytesRead = %d", bytesRead));
DEBUGMSG(1, (L"CString = %s", dacstr));
start = 0;
endline = 0;
// Parse/Process the output (4c)
while(1)
{
start = dacstr.Find(L"$G", start);
if(start < 0)
break;
endline = dacstr.Find(L"\r\n", start);
if(endline < 0)
break;
linelen = endline - start;
//DEBUGMSG(1, (L"start = %d endline = %d length = %d", start, endline, linelen));
// Extract one line
CString oneline;
oneline = dacstr.Mid(start, linelen);
DEBUGMSG(1, (L"Oneline = %s", oneline));
// Process one line
onestart = 0;
oneend = 0;
if(oneline.Left(6) == L"$GPGGA")
{
onestart += oneline.Find(L",", onestart);
oneend = oneline.Find(L",", onestart+1);
length = oneend - onestart - 1;
time = oneline.Mid(onestart + 1, length);
time = time.Left(2) + L":" + time.Mid(2,2) + L":" + time.Right(5);
//DEBUGMSG(1, (L"onestart = %d oneend = %d length = %d", onestart, oneend, length));
onestart = oneend+1;
oneend = oneline.Find(L",", onestart+1);
length = oneend - onestart;
lat = oneline.Mid(onestart, length);
degdig = lat.GetLength() - 2;
lat = lat.Left(2) + L"
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?