?? cserial.cpp
字號:
// Serial.cpp: implementation of the CSerial class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"
#include "CSerial.h"
#include "Embest_SCOMMDlg.h"
const CM_THREADCOMMWRITE = WM_USER+110;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//*******************************************//
CSerial::CSerial()
{
m_hComm = INVALID_HANDLE_VALUE;
// m_bOpened = FALSE;
}
//******************************************//
CSerial::~CSerial()
{
ClosePort();
}
//*******************************************//
BOOL CSerial::WritetoPort(HANDLE hComm,const BYTE *buf,DWORD bufLen)
{
DWORD dwNumBytesWritten;
DWORD dwHaveNumWritten = 0;
ASSERT(hComm != INVALID_HANDLE_VALUE);
do
{
if(WriteFile(hComm,
buf+dwHaveNumWritten,
bufLen - dwHaveNumWritten,
&dwNumBytesWritten,
NULL))
{
dwHaveNumWritten = dwHaveNumWritten + dwNumBytesWritten;
if (dwHaveNumWritten == bufLen)
{
break;
}
Sleep(10);
}
else
{
return FALSE;
}
}while(TRUE);
return TRUE;
}
//***********************************************//
//串口讀線程函數
DWORD CSerial::ReadThreadFunc(LPVOID lparam)
{
CSerial *ceSeries = (CSerial *)lparam;
DWORD evtMask;
BYTE* readBuf = NULL;
DWORD actualReadLen = 0;
DWORD willReadLen;
DWORD dwReadErrors;
COMSTAT cmState;
//清空緩沖
ASSERT(ceSeries->m_hComm != INVALID_HANDLE_VALUE);
//清空串口
PurgeComm(ceSeries->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR);
SetCommMask(ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
while(TRUE)
{
if(WaitCommEvent(ceSeries->m_hComm,&evtMask,0))
{
SetCommMask(ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
if(evtMask & EV_RXCHAR)
{
ClearCommError(ceSeries->m_hComm, &dwReadErrors, &cmState);
willReadLen = cmState.cbInQue;
if(willReadLen <= 0)
{
continue;
}
readBuf = new BYTE[willReadLen];
ReadFile(ceSeries->m_hComm, readBuf, willReadLen, &actualReadLen ,0);
if(actualReadLen>0)
{
((CEmbest_SCOMMDlg *)(ceSeries->m_pPortOwner))->response(readBuf,actualReadLen);
}
delete[] readBuf;
}
}
if(WaitForSingleObject(ceSeries->m_hReadCloseEvent,500) == WAIT_OBJECT_0)
{
break;
}
}
return 0;
}
//************************************************//
//串口寫線程函數
DWORD CSerial::WriteThreadFunc(LPVOID lparam)
{
CSerial *ceSeries = (CSerial *)lparam;
MSG msg;
DWORD dwWriteLen = 0;
BYTE* buf = NULL;
while(TRUE)
{
if(PeekMessage(&msg,0,0,0,PM_REMOVE))
{
if(msg.hwnd != 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
continue;
}
if(msg.message == CM_THREADCOMMWRITE)
{
buf = (BYTE*)msg.lParam;
dwWriteLen = msg.wParam;
WritetoPort(ceSeries->m_hComm,buf,dwWriteLen);
delete[] buf;
}
}
if(WaitForSingleObject(ceSeries->m_hWriteCloseEvent ,500) == WAIT_OBJECT_0)
{
break;
}
ceSeries->m_hWriteThread = NULL;
}
return 0;
}
//***********************************************//
//關閉讀線程
void CSerial::CloseReadThread()
{
SetEvent(m_hReadCloseEvent);
SetCommMask(m_hComm,0);
PurgeComm(m_hComm,PURGE_RXCLEAR);
if(WaitForSingleObject(m_hReadThread,10000) == WAIT_TIMEOUT)
{
TerminateThread(m_hReadThread,0);
}
m_hReadThread = NULL;
}
//***********************************************//
//關閉寫線程
void CSerial::CloseWriteThread()
{
SetEvent(m_hWriteCloseEvent);
SetCommMask(m_hComm,0);
PurgeComm(m_hComm,PURGE_TXCLEAR);
if(WaitForSingleObject(m_hWriteThread,10000) == WAIT_TIMEOUT)
{
TerminateThread(m_hWriteThread,0);
}
m_hWriteThread = NULL;
}
//***********************************************//
//打開串口
BOOL CSerial::OpenPort(CWnd* pPortOwner,
UINT portNo,
DWORD baud,
BYTE parity,
BYTE databits,
BYTE stopbits)
{
DCB commParam;
TCHAR szPort[15];
if(m_hComm != INVALID_HANDLE_VALUE)
{
return TRUE;
}
ASSERT(pPortOwner != NULL);
ASSERT(portNo > 0 && portNo <5);
//設置串口名
wsprintf(szPort ,_T("COM%d:"), portNo);
m_hComm = CreateFile(
szPort,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);
if(m_hComm == INVALID_HANDLE_VALUE)
{
TRACE(_T("CreateFile return invalid handle"));
return FALSE;
}
if(!GetCommState(m_hComm,&commParam))
{
return FALSE;
}
commParam.BaudRate = baud;
commParam.ByteSize = databits;
commParam.Parity = parity; // 0-4=no,odd,even,mark,space
commParam.StopBits = stopbits;
if(!SetCommState(m_hComm, &commParam))
{
TRACE(_T("SetCommState error"));
return FALSE;
}
//設置串口讀寫時間
COMMTIMEOUTS CommTimeOuts;
GetCommTimeouts (m_hComm, &CommTimeOuts);
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 10;
CommTimeOuts.WriteTotalTimeoutConstant = 1000;
if(!SetCommTimeouts(m_hComm,&CommTimeOuts))
{
TRACE(_T("SetCommTimeouts wrong!"));
}
m_pPortOwner = pPortOwner;
SetCommMask(m_hComm,EV_RXCHAR);
SetupComm(m_hComm,512,512);
PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
m_hReadCloseEvent = CreateEvent(NULL ,TRUE ,FALSE ,NULL);
m_hWriteCloseEvent = CreateEvent(NULL ,TRUE ,FALSE ,NULL);
//創建讀串口線程
m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID);
//創建寫串口線程
m_hWriteThread = CreateThread(NULL,0,WriteThreadFunc, this,0,&m_dwWriteThreadID);
TRACE(_T("Serial Port Open Successful!"));
return TRUE;
}
//**************************************************//
//關閉串口
void CSerial::ClosePort()
{
if(m_hComm == INVALID_HANDLE_VALUE)
{
return;
}
CloseReadThread();
CloseWriteThread();
if(!CloseHandle(m_hComm))
{
m_hComm = INVALID_HANDLE_VALUE;
return;
}
}
//*****************************************************//
//公用寫串口
BOOL CSerial::WritePort(const BYTE *buf , DWORD bufLen)
{
if(PostThreadMessage(m_dwWriteThreadID,CM_THREADCOMMWRITE,WPARAM(bufLen),LPARAM(buf)))
{
return TRUE;
}
return FALSE;
}
//*******************************************************//
//設置串口超時
BOOL CSerial::SetSeriesTimeOuts(COMMTIMEOUTS CommTimeOuts)
{
ASSERT(m_hComm != INVALID_HANDLE_VALUE);
return SetCommTimeouts(m_hComm,&CommTimeOuts);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -