沒有應該獲得的成功,只有不肯放棄的夢想
阿新 • • 發佈:2018-12-21
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、下面是我寫的一個串列埠下例子,可以參考一些
下面是完整程式碼,需要的可以下載