您的位置:首页 > 编程语言

vc 串口通信代码

2015-09-14 16:07 274 查看
#include "StdAfx.h"
#include "comm.h"
#include "publib.h"
#include <process.h>

CommModule::CommModule()
{
m_hCOM = NULL;
m_bLog = FALSE;
m_hThread = NULL;
m_hStopEvt = NULL;
m_data_cb = NULL;
}

CommModule::~CommModule()
{

}

HANDLE CommModule::Init_Port(const char *port)
{
COMSTAT	comstat;
DWORD	errors;

CString s = CString(port);

m_flowCtrl = COMM_FC_HW;
m_baud = 115200;

//	20120131 by foil - open com port fail
int count = 1;
while (count <= 50)	//	try 50 times
{
m_hCOM = CreateFile(s,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);

if(m_hCOM == INVALID_HANDLE_VALUE )
{
DebugOut(_T("try %d: Failed to open %s, err = %d\n"), count, (LPCTSTR)s, GetLastError());
Sleep(100);
count ++;
}
else
break;
}

if(m_hCOM == INVALID_HANDLE_VALUE )
{
//	if(m_bLog)
DebugOut(_T("eventually Failed to open %s, err = %d\n"), (LPCTSTR)s, GetLastError());
m_hCOM = NULL;
return NULL;
}
else
DebugOut(_T("Open %s succeeded!!!\n"), (LPCTSTR)s);

::ClearCommError(m_hCOM, &errors, &comstat);

//turn off fAbort first
DCB dcb;

if( GetCommState(m_hCOM, &dcb)==FALSE )
{
CloseHandle(m_hCOM);
m_hCOM = NULL;
return NULL;
}

dcb.DCBlength = sizeof(DCB);
dcb.Parity = NOPARITY;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
dcb.BaudRate = m_baud;
dcb.fBinary = TRUE;
dcb.fParity = FALSE;

if(m_flowCtrl == COMM_FC_HW)
dcb.fOutxCtsFlow = TRUE;
else
dcb.fOutxCtsFlow = FALSE;

dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = FALSE;
dcb.fTXContinueOnXoff = FALSE;
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE;
dcb.fAbortOnError = FALSE;

if(m_flowCtrl == COMM_FC_SW)
{
dcb.fOutX = TRUE;
dcb.fInX = TRUE;
}
else
{
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
}

if(m_flowCtrl == COMM_FC_SW
|| m_flowCtrl == COMM_FC_NONE)
dcb.fRtsControl = RTS_CONTROL_ENABLE;
else if(m_flowCtrl == COMM_FC_HW)
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;

if(m_flowCtrl == COMM_FC_SW)
{
dcb.XonChar = 0x11;
dcb.XoffChar = 0x13;
}
else
{
dcb.XonChar = 0;
dcb.XoffChar = 0;
}

dcb.ErrorChar = 0;
dcb.EofChar = 0;
dcb.EvtChar = 0;

::ClearCommError(m_hCOM, &errors, &comstat);

if( SetCommState(m_hCOM, &dcb)==FALSE )
{
CloseHandle(m_hCOM);
m_hCOM = NULL;
return NULL;
}

if( ::SetupComm(m_hCOM, 8192, 8192)==FALSE )
{
CloseHandle(m_hCOM);
m_hCOM = NULL;
return NULL;
}

if( ::PurgeComm(m_hCOM, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR)==FALSE )
{
CloseHandle(m_hCOM);
m_hCOM = NULL;
return NULL;
}

// Communications Properties
COMMPROP cp;
if(GetCommProperties(m_hCOM, &cp) == FALSE)
{
CloseHandle(m_hCOM);
m_hCOM = NULL;
return NULL;
}

COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 0xFFFFFFFF;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 2000;
if( ::SetCommTimeouts(m_hCOM, &timeouts) == FALSE )
{
CloseHandle(m_hCOM);
m_hCOM = NULL;
return NULL;
}

m_hStopEvt = ::CreateEvent(NULL, TRUE, FALSE, NULL);
if(m_hStopEvt == NULL)
{
CloseHandle(m_hCOM);
m_hCOM = NULL;
return false;
}

if(StartThread() == false)
{
return NULL;
}

return m_hCOM;
}

// Wait for thread
void CommModule::WaitForExit()
{
if(m_hThread == NULL)
return;

WaitForSingleObject(m_hThread, INFINITE);
CloseHandle(m_hThread);
m_hThread = NULL;
}

void CommModule::StopThread()
{
if(m_hThread == NULL)
return ;

::SetEvent(m_hStopEvt);
WaitForExit();
}

bool CommModule::StartThread()
{
m_hThread = (HANDLE)_beginthreadex(
NULL, 0, (PBEGINTHREADEX_THREADFUNC)CommModule::HelpThreadFunc, (LPVOID)this, 0, NULL);

if( m_hThread )
return true;

return false;
}

DWORD CommModule::ThreadFunc()
{
COMSTAT	comstat;
DWORD	errors;

while(1)
{
//If dwMilliseconds is zero, the function tests the object's state and returns immediately
if( ::WaitForSingleObject(m_hStopEvt, 0)==WAIT_OBJECT_0 )
{
::ClearCommError(m_hCOM, &errors, &comstat);
break;
}

::ClearCommError(m_hCOM, &errors, &comstat);

if( !comstat.cbInQue )
{
Sleep(1); //dwMilliseconds
continue;
}

int dwBytesRead = (DWORD) comstat.cbInQue;
if( 512 <= (int) dwBytesRead )
dwBytesRead = 512;

if( ::ReadFile(m_hCOM, rawchars, dwBytesRead, &m_dwRead, NULL) )
{
if( m_dwRead==0 || m_data_cb==NULL)
continue;

m_iRead = m_dwRead;
rawchars[m_dwRead] = 0;

if(m_bLog)
DebugOutA("\r\n[rxd] %s\r\n", rawchars);
m_data_cb(0, (const char*)rawchars, m_iRead, m_pData);

}
}

return 0;
}

DWORD CommModule::HelpThreadFunc(LPVOID param)
{
CommModule *pto = (CommModule *)param;

return pto->ThreadFunc();

}

bool CommModule::WriteData(const char *Buf, const int size)
{
CString strDebug, strTemp;

int nRetryCount = 0;
int nSentBytes = 0;

while( nSentBytes < size )
{
int wbytes = 0;
int nPerSend = 0;

// reset write bytes
wbytes = 0;

// set send bytes
nPerSend = size - nSentBytes;

//	if (nPerSend%8 == 0)
//		nPerSend--;

// write to com
BOOL bWriteResult = WriteFile(m_hCOM, ((char*)Buf)+nSentBytes,
nPerSend, (unsigned long*)&wbytes, NULL);

// check result
if(!bWriteResult)
{
if(m_bLog)
DebugOutA("\r\n[error] WriteFile failed: %d\r\n", GetLastError());
// clear com error
::ClearCommError(m_hCOM, NULL, NULL);
}
else if( wbytes < nPerSend )
{
nSentBytes += wbytes;

if(m_bLog)
DebugOutA("\r\n[error] not write done. To write =%d, written = %d\r\n", nPerSend, wbytes);
}
else
{
// update the counts of sent bytes
nSentBytes += wbytes;
// reset retry count and continue to skip retry
nRetryCount = 0;
continue;
}

// check retry count
if( 3 <= nRetryCount )
{
if(m_bLog)
DebugOutA("\r\n[error] write failed: <%s>\r\n", Buf);
return false;
}

// increase retry count
nRetryCount++;

// receiver might be in busy status, sleep awhile
Sleep(100);
}
if(m_bLog)
DebugOutA("\r\n[txd] %s\r\n", Buf);
return true;
}

int CommModule::SetCallBack(DataNotify reply, void *pExt)
{
m_data_cb = reply;
m_pData = pExt;

return 1;
}

void CommModule::Deinit_Port()
{
StopThread();

if(m_hCOM!=NULL)
{
CloseHandle(m_hCOM);
m_hCOM = NULL;
}

if(m_hStopEvt!=NULL)
{
CloseHandle(m_hStopEvt);
m_hStopEvt = NULL;
}
}

void CommModule::EnableLog(BOOL bEnable)
{
m_bLog = bEnable;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: