#include "stdafx.h"
#include "ComPort.h"
CComPort::CComPort()
:m_bOverlapped(FALSE),
m_hComm(INVALID_HANDLE_VALUE)
{
ZeroMemory(&m_ReadOverlapped, sizeof(OVERLAPPED));
ZeroMemory(&m_WriteOverlapped, sizeof(OVERLAPPED));
ZeroMemory(&m_WriteOverlapped, sizeof(OVERLAPPED));
m_pReadComThread = new CReadComThread(this);
}
CComPort::~CComPort()
{
Close();
delete m_pReadComThread;
}
/************************************************************************
打开串口
************************************************************************/
BOOL CComPort::Open(int nPort, BOOL bOverlapped /*=FALSE*/, DWORD dwBaud /*= 9600*/, BYTE DataBits /*= 8*/, CComPort::Parity parity /*= NoParity*/, CComPort::StopBits stopbits /*= OneStopBit*/, CComPort::FlowControl fc /*= NoFlowControl*/)
{
ASSERT(nPort>0 && nPort<=255);
CString strPort;
strPort.Format(_T("\\\\.\\COM%d"), nPort);
DWORD dwFlags;
if (bOverlapped)
{
dwFlags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED;
}
else
{
dwFlags = FILE_ATTRIBUTE_NORMAL;
}
m_hComm = CreateFile(strPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, dwFlags, NULL);
if (m_hComm == INVALID_HANDLE_VALUE)
{
return FALSE;
}
//Get the current state prior to changing it
DCB dcb;
dcb.DCBlength = sizeof(DCB);
GetCommState(m_hComm, &dcb);
//Setup the baud rate
dcb.BaudRate = dwBaud;
//Setup the Parity
switch (parity)
{
case EvenParity: dcb.Parity = EVENPARITY; break;
case MarkParity: dcb.Parity = MARKPARITY; break;
case NoParity: dcb.Parity = NOPARITY; break;
case OddParity: dcb.Parity = ODDPARITY; break;
case SpaceParity: dcb.Parity = SPACEPARITY; break;
default: ASSERT(FALSE); break;
}
//Setup the data bits
dcb.ByteSize = DataBits;
//Setup the stop bits
switch (stopbits)
{
case OneStopBit: dcb.StopBits = ONESTOPBIT; break;
case OnePointFiveStopBits: dcb.StopBits = ONE5STOPBITS; break;
case TwoStopBits: dcb.StopBits = TWOSTOPBITS; break;
default: ASSERT(FALSE); break;
}
//Setup the flow control
dcb.fDsrSensitivity = FALSE;
switch (fc)
{
case NoFlowControl:
{
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
break;
}
case CtsRtsFlowControl:
{
dcb.fOutxCtsFlow = TRUE;
dcb.fOutxDsrFlow = FALSE;
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
break;
}
case CtsDtrFlowControl:
{
dcb.fOutxCtsFlow = TRUE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
break;
}
case DsrRtsFlowControl:
{
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = TRUE;
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
break;
}
case DsrDtrFlowControl:
{
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = TRUE;
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
break;
}
case XonXoffFlowControl:
{
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fOutX = TRUE;
dcb.fInX = TRUE;
dcb.XonChar = 0x11;
dcb.XoffChar = 0x13;
dcb.XoffLim = 100;
dcb.XonLim = 100;
break;
}
default:
{
ASSERT(FALSE);
break;
}
}
//Now that we have all the settings in place, make the changes
SetCommState(m_hComm, &dcb);
SetBufferSize(1024, 1024);
PurgeComm(m_hComm, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
COMMTIMEOUTS timeouts;
GetTimeouts(timeouts);
timeouts.ReadIntervalTimeout = 100;
SetTimeouts(timeouts);
m_bOverlapped = bOverlapped;
if (m_bOverlapped)
{
m_ReadOverlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
m_WriteOverlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
m_WaitOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
}
m_pReadComThread->Create();
return TRUE;
}
/************************************************************************
关闭串口
************************************************************************/
void CComPort::Close()
{
if (IsOpen())
{
if (m_pReadComThread)
{
m_pReadComThread->Exit();
}
CloseHandle(m_hComm);
m_hComm = INVALID_HANDLE_VALUE;
m_bOverlapped = FALSE;
if (m_ReadOverlapped.hEvent)
{
CloseHandle(m_ReadOverlapped.hEvent);
}
if (m_WriteOverlapped.hEvent)
{
CloseHandle(m_WriteOverlapped.hEvent);
}
if (m_WaitOverlapped.hEvent)
{
CloseHandle(m_WaitOverlapped.hEvent);
}
}
}
void CComPort::SetTimeouts(COMMTIMEOUTS& timeouts)
{
ASSERT(IsOpen());
if (!SetCommTimeouts(m_hComm, &timeouts))
{
TRACE(_T("Failed in call to SetCommTimeouts\n"));
}
}
void CComPort::GetTimeouts(COMMTIMEOUTS& timeouts)
{
ASSERT(IsOpen());
if (!GetCommTimeouts(m_hComm, &timeouts))
{
TRACE(_T("Failed in call to GetCommTimeouts\n"));
}
}
/************************************************************************
串口是否打开
************************************************************************/
BOOL CComPort::IsOpen() const
{
return m_hComm != INVALID_HANDLE_VALUE;
}
/************************************************************************
设置串口输入和输出缓冲区大小
************************************************************************/
void CComPort::SetBufferSize(DWORD dwInputSize, DWORD dwOutputSize)
{
ASSERT(IsOpen());
SetupComm(m_hComm, dwInputSize, dwOutputSize);
}
/************************************************************************
获取串口输入缓冲区字节数量
************************************************************************/
DWORD CComPort::GetInputSize() const
{
COMSTAT Stat;
DWORD dwError;
return ClearCommError(m_hComm, &dwError, &Stat) == TRUE ? Stat.cbInQue : (DWORD)-1L;
}
/************************************************************************
设置事件信号掩码
************************************************************************/
void CComPort::SetEvent(DWORD dwMask)
{
ASSERT(IsOpen());
SetCommMask(m_hComm, dwMask);
}
/************************************************************************
支持同步,异步模式
************************************************************************/
BOOL CComPort::WaitEvent(DWORD &dwMask)
{
ASSERT(IsOpen());
LPOVERLAPPED pWait = NULL;
if (m_bOverlapped)
{
pWait = &m_WaitOverlapped;
}
if (!WaitCommEvent(m_hComm, &dwMask, pWait))
{
if (pWait)
{
if (GetLastError()== ERROR_IO_PENDING)
{
DWORD dwLength;
return GetOverlappedResult(m_hComm, &m_WaitOverlapped, &dwLength, TRUE);
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
}
return TRUE;
}
/************************************************************************
从串口读数据, 可设定超时
当为同步模式时,忽略超时;异步模式时,超时有效
************************************************************************/
DWORD CComPort::ReadComm(void* pData, DWORD dwDataSize, DWORD dwTimeouts /* = 0 */)
{
ASSERT(pData);
ASSERT(IsOpen());
COMSTAT Stat;
DWORD dwError;
if(::ClearCommError(m_hComm, &dwError, &Stat) && dwError > 0)
{
::PurgeComm(m_hComm, PURGE_RXABORT | PURGE_RXCLEAR);
return 0;
}
// 缓冲区无数据
if(!Stat.cbInQue)
return 0;
DWORD dwReadBytes = 0;
LPOVERLAPPED pOver = NULL;
//异步读取数据
if (m_bOverlapped)
{
pOver = &m_ReadOverlapped;
}
dwDataSize = min(Stat.cbInQue, dwDataSize);
if (!ReadFile(m_hComm, pData, dwDataSize, &dwReadBytes, pOver))
{
if (pOver)
{
if (ERROR_IO_PENDING == GetLastError())
{
WaitForSingleObject(m_ReadOverlapped.hEvent, dwTimeouts); /
一个支持同步异步的串口类
4星 · 超过85%的资源 需积分: 0 199 浏览量
2009-01-15
12:58:32
上传
评论 1
收藏 5KB RAR 举报
qinshubo1984
- 粉丝: 5
- 资源: 25
最新资源
- python-leetcode面试题解之第157题用Read4读取N个字符-题解.zip
- python-leetcode面试题解之第156题上下翻转二叉树-题解.zip
- python-leetcode面试题解之第155题最小栈-题解.zip
- python-leetcode面试题解之第153题寻找旋转排序数组中的最小值-题解.zip
- python-leetcode面试题解之第152题乘积最大子数组-题解.zip
- python-leetcode面试题解之第151题反转字符串中的单词-题解.zip
- python-leetcode面试题解之第150题逆波兰表达式求值-题解.zip
- python-leetcode面试题解之第149题直线上最多的点数-题解.zip
- python-leetcode面试题解之第148题排序链表-题解.zip
- python-leetcode面试题解之第147题对链表进行插入排序-题解.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈