📄 serialcomm.cpp
字号:
// SerialComm.cpp: implementation of the CSerialComm class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DTE.h"
#include "SerialComm.h"
#include <process.h>
#include <stdlib.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
void CSerialComm::InvalidateHandle(HANDLE &hHandle)
{
hHandle = INVALID_HANDLE_VALUE;
}
//--------------------------------------------------------------------
void CSerialComm::CloseAndCleanHandle(HANDLE &hHandle)
{
BOOL bRet;
bRet = CloseHandle(hHandle);
if(!bRet)
ASSERT(0);
InvalidateHandle(hHandle);
}
//---------------------------------------------------------------------
CSerialComm::CSerialComm()
{
InvalidateHandle(m_hCommPort);
InitLock();
//初始化
CanRead = false;
m_eState = SS_UnInit;
}
//-----------------------------------------------------------------------
CSerialComm::~CSerialComm()
{
m_eState = SS_Unknown;
DelLock();
}
//---------------------------------------------------------------------------
HRESULT CSerialComm::Init(std::string szPortName, std::string dwBaudRate,
std::string byParity, std::string byStopBit, std::string byByteSize)
{
HRESULT hr = S_OK;
try
{
//打开串口
m_hCommPort = ::CreateFile(szPortName.c_str(),
GENERIC_READ | GENERIC_WRITE,
0, //不共享COM口
NULL, //无安全策略
OPEN_EXISTING, //打开已有的文件
FILE_FLAG_OVERLAPPED, //I/O重叠模式
0);
if(m_hCommPort == INVALID_HANDLE_VALUE)
{
AfxMessageBox("这个串口没有装备或者已经被其他设备占用了!");
return E_FAIL;
}
//COM口设置掩码参数
if(!::SetCommMask(m_hCommPort, EV_RXCHAR))//|EV_TXEMPTY
{
AfxMessageBox("串口掩码设置错误!");
return E_FAIL;
}
//
/*DWORD DCBlength1=dcb.DCBlength; // sizeof(DCB)
DWORD BaudRate1=dcb.BaudRate; // current baud rate
DWORD fBinary1=dcb.fBinary; // binary mode, no EOF check
DWORD fParity1=dcb.fParity; // enable parity checking
DWORD fOutxCtsFlow1=dcb.fOutxCtsFlow; // CTS output flow control
DWORD fOutxDsrFlow1=dcb.fOutxDsrFlow; // DSR output flow control
DWORD fDtrControl1=dcb.fDtrControl; // DTR flow control type
DWORD fDsrSensitivity1=dcb.fDsrSensitivity; // DSR sensitivity
DWORD fTXContinueOnXoff1=dcb.fTXContinueOnXoff; // XOFF continues Tx
DWORD fOutX1=dcb.fOutX; // XON/XOFF out flow control
DWORD fInX1=dcb.fInX; // XON/XOFF in flow control
DWORD fErrorChar1=dcb.fErrorChar; // enable error replacement
DWORD fNull1=dcb.fNull; // enable null stripping
DWORD fRtsControl1=dcb.fRtsControl; // RTS flow control
DWORD fAbortOnError1=dcb.fAbortOnError; // abort reads/writes on error
DWORD fDummy21=dcb.fDummy2; // reserved
WORD wReserved1=dcb.wReserved; // not currently used
WORD XonLim1=dcb.XonLim; // transmit XON threshold
WORD XoffLim1=dcb.XoffLim; // transmit XOFF threshold
BYTE ByteSize1=dcb.ByteSize; // number of bits/byte, 4-8
BYTE Parity1=dcb.Parity; // 0-4=no,odd,even,mark,space
BYTE StopBits1=dcb.StopBits; // 0,1,2 = 1, 1.5, 2
char XonChar1=dcb.XonChar; // Tx and Rx XON character
char XoffChar1=dcb.XoffChar; // Tx and Rx XOFF character
char ErrorChar1=dcb.ErrorChar; // error replacement character
char EofChar1=dcb.EofChar; // end of input character
char EvtChar1=dcb.EvtChar; // received event character
WORD wReserved11=dcb.wReserved1; */ // reserved; do not use
//COM口的通信参数设置
DCB dcb = {0};
dcb.DCBlength = sizeof(DCB);
if (!::GetCommState (m_hCommPort,&dcb))
{
// ATLTRACE6 ( "CSerialCommHelper : Failed to Get Comm State Reason: %d",GetLastError());
return E_FAIL;
}
dcb.BaudRate = CBR_9600;//波特率
dcb.ByteSize = 8;//数据尺寸
dcb.Parity = NOPARITY; //校验选择
//终止位
dcb.StopBits = ONESTOPBIT;
dcb.fDsrSensitivity = 0;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fOutxDsrFlow = 0;
if (!::SetCommState (m_hCommPort,&dcb))
{
AfxMessageBox("串口通信参数设置错误");
//ATLTRACE6 ( "CSerialCommHelper : Failed to Set Comm State Reason: %d",GetLastError());
return E_FAIL;
}
//设置串口的缓冲区
SetupComm(m_hCommPort, 1024 ,1024);
//设置串口超时参数
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
if(!SetCommTimeouts(m_hCommPort, &timeouts))
{
AfxMessageBox("串口超时状态设置错误!");
return E_FAIL;
}
//清除缓冲区
PurgeComm(m_hCommPort, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
m_abIsConnected = true;
}
catch(...)
{
AfxMessageBox("串口设置异常!");
return E_FAIL;
}
if(SUCCEEDED(hr))
{
AfxMessageBox("串口设置成功!");
m_eState = SS_Init;
}
return hr;
}
//-------------------------------------------------------------------------------------
HRESULT CSerialComm::Start()
{
m_eState = SS_Started;
return S_OK;
}
//------------------------------------------------------------------------------------
HRESULT CSerialComm::Stop()
{
m_eState = SS_Stopped;
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CSerialComm::UnINit()
{
HRESULT hr = S_OK;
try
{
m_abIsConnected = false;
CanRead = false;
// SignalObjectAndWait(m_hThreadTerm, m_hThread, INFINITE, FALSE);
// CloseAndCleanHandle(m_hThreadTerm);
// CloseAndCleanHandle(m_hThread);
CloseAndCleanHandle(m_hCommPort);
}
catch(...)
{
ASSERT(0);
hr = E_FAIL;
}
if(SUCCEEDED(hr))
m_eState = SS_UnInit;
return hr;
}
//-------------------------------------------------------------------------------------------------
HRESULT CSerialComm::CanProcess()
{
switch(m_eState)
{
case SS_Unknown:ASSERT(0);return E_FAIL;
case SS_UnInit :return E_FAIL;
case SS_Started:return S_OK;
case SS_Init:
case SS_Stopped: return E_FAIL;
default :ASSERT(0);
}
return E_FAIL;
}
//-------------------------------------------------------------------------------------------------
HRESULT CSerialComm::WRITEProtocol(const BYTE *data, DWORD dwSize)
{
HRESULT hr = CanProcess();
if(FAILED(hr)) return hr;
int iRet = 0;
OVERLAPPED ov;
memset(&ov, 0, sizeof(ov));
ov.hEvent = CreateEvent(0, true, 0, 0);
DWORD dwBytesWritten = 0;
iRet = ::WriteFile(m_hCommPort, data, dwSize, &dwBytesWritten, &ov);
if(iRet == 0)
WaitForSingleObject(ov.hEvent, INFINITE);
CloseHandle(ov.hEvent);
return S_OK;
}
//-------------------------------------------------------------------------------------------------
HRESULT CSerialComm::SerialWriteData(const BYTE *msg, DWORD size)
{
UINT16 i;
UINT16 j;
UINT16 sendindex;
sendindex = 0;
sendbuffer[sendindex] = C0CHAR;
sendindex = (sendindex+1);
for (i=0; i<size; i++)
{
j=msg[i];
if (j==C0CHAR)
{
sendbuffer[sendindex] = DBCHAR;
sendindex++;
sendbuffer[sendindex] = DCCHAR;
sendindex++;
}
else if (j==DBCHAR)
{
sendbuffer[sendindex] = DBCHAR;
sendindex++;
sendbuffer[sendindex] = DDCHAR;
sendindex++;
}
else
{
sendbuffer[sendindex] = msg[i];
sendindex++;
}
}
sendbuffer[sendindex] = C0CHAR;
//发送数据
WRITEProtocol(sendbuffer, sendindex+1);
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -