1. 程式人生 > >沒有應該獲得的成功,只有不肯放棄的夢想

沒有應該獲得的成功,只有不肯放棄的夢想

1、SerialComm.h成員變數,成員函式宣告

#pragma once

#define    WM_COMM_RX    0x0400 + 500     //串列埠訊息接收訊號巨集定義
#define    REV_LEN       1000             //接收的位元組數
class CSerialComm
{
public:
	CSerialComm();
	~CSerialComm();
public:
	BOOL OpenComm(LPCTSTR lpFileName);
	void SetCommStat(DCB mDcbComm);
	BOOL GetCommStat(DCB* mDcbComm);
	BOOL ReadFileStat();
	BOOL WriteFileStat(char *p, UINT len);
	BOOL CloseHandleStat();
	//讀取執行緒,讀取串列埠資料
	static unsigned int __stdcall OnRecv(void*);
	void CreateRecvThread();     //建立讀取資料執行緒
private:
	BOOL m_nWorkIng;
	

public:
	CWinThread* m_pThread;  //執行緒指標
	COMMTIMEOUTS  m_nTimeout;
	DCB m_nDcb;
	HANDLE m_hComm;
	CString m_nOutputContext;
	char m_nInputContext[1000];
	CString m_revData;
	DWORD m_nReceiveNum;
	HWND m_hWnd;
};

2、開啟串列埠


BOOL CSerialComm::OpenComm(LPCTSTR lpFileName)
{
	m_hComm = CreateFile(lpFileName, GENERIC_READ | GENERIC_WRITE,0, NULL, OPEN_EXISTING, 0, NULL);
	
    	if (m_hComm == INVALID_HANDLE_VALUE)
		{
			AfxMessageBox("開啟串列埠失敗!");
			return FALSE;
		}	
			return TRUE;		
}

3、設定串列埠引數


void CSerialComm::SetCommStat(DCB mDcbComm)
{
	
	COMMTIMEOUTS TimeOuts;   //設定超時時間
	TimeOuts.ReadIntervalTimeout = 1000;
	TimeOuts.ReadTotalTimeoutMultiplier = 500;
	TimeOuts.ReadTotalTimeoutConstant = 5000; //設定寫超時
	TimeOuts.WriteTotalTimeoutMultiplier = 100;
	TimeOuts.WriteTotalTimeoutConstant = 500;
	SetCommTimeouts(m_hComm, &TimeOuts);
	SetupComm(m_hComm, 1024, 1024);
	

	if (!SetCommState(m_hComm, &mDcbComm))
	{
		AfxMessageBox("串列埠設定失敗!");
		return;
	}
	PurgeComm(m_hComm, PURGE_TXCLEAR | PURGE_RXCLEAR);
	
}

4、讀取串列埠資料


//非同步讀取串列埠資料
BOOL CSerialComm::ReadFileStat()
{
	DWORD dwBytesWrite = 1000;
	DWORD wCount;
	BOOL bReadStatus;
	DWORD dwErrorFlags;
	COMSTAT ComStat;
	OVERLAPPED m_osRead;
	ClearCommError(m_hComm, &dwErrorFlags, &ComStat);
	bReadStatus = ReadFile(m_hComm, m_nInputContext, 1000, &wCount, NULL);
	if (!bReadStatus)
	{
			AfxMessageBox("讀串列埠失敗!");
			return FALSE;
	}
	PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
	m_nReceiveNum = wCount;
	return TRUE;
}

5、建立執行緒,迴圈等待接收串列埠資料


//迴圈等待串列埠資料
unsigned int __stdcall CSerialComm::OnRecv(void* LPParam)//接收資料
{
	CSerialComm *obj = static_cast<CSerialComm*>(LPParam);
	CString revData;
	UINT len = REV_LEN;
	while (true)
	{
		obj->ReadFileStat();
		revData = obj->m_nInputContext;
		obj->m_revData = revData;
		::PostMessage(obj->m_hWnd, WM_COMM_RX, (WPARAM)(CString *)&obj->m_revData, (LPARAM)(UINT)len);
	}
	return 0;
}

//建立訊息接收執行緒
void CSerialComm::CreateRecvThread()
{
	(HANDLE)_beginthreadex(NULL, 0, &CSerialComm::OnRecv, this, 0, NULL);
}

6、串列埠初始化操作

如果在其他類中使用該串列埠類,需要建立一個串列埠物件,具體的串列埠初始化如下:

CSerialComm *serialComm = new CSerialComm();
initSerial()
{
	CString serialnum, sbaudrate;
	UINT nbaudrate;
	serialnum = "COM5";
	sbaudrate = "9600";
	nbaudrate = _tstoi(sbaudrate);
	DCB dcb;
	serialComm->OpenComm(serialnum);
	serialComm->GetCommStat(&dcb);
	//設定串列埠引數
	dcb.BaudRate = nbaudrate;
	dcb.ByteSize = 8;
	dcb.Parity = NOPARITY;
	dcb.StopBits = ONESTOPBIT;
	serialComm->SetCommStat(dcb);
	serialComm->CreateRecvThread();
	serialComm->m_hWnd = m_hWnd;
}

7、下面是我寫的一個串列埠下例子,可以參考一些

下面是完整程式碼,需要的可以下載