⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nmeamsgdlg.cpp

📁 这是一个对SIRF STAR III 卫星信号的解析代码.
💻 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 + -