📄 serialcomm.cpp
字号:
if (FALSE == ::GetCommConfig(m_hCOM, NULL, &dwCCSize))
return BOOL(FALSE);
LPCOMMCONFIG pCC = LPCOMMCONFIG(new BYTE[dwCCSize]);
if (NULL == pCC)
return BOOL(FALSE);
pCC->dwSize = dwCCSize;
pCC->wVersion = 0x200;
pCC->dcb.DCBlength = sizeof(DCB);
if (FALSE == ::GetCommConfig(m_hCOM, pCC, &dwCCSize))
{
delete[] LPBYTE(pCC);
return BOOL(FALSE);
}
//检查CommConfigDialog显示标志,防止重复启动CommConfigDialog
if (FALSE == m_bShowCommConfigDialog)
{
BOOL bRet = FALSE;
m_bShowCommConfigDialog = TRUE;
if (FALSE != ::CommConfigDialog(m_atcCurCOM, NULL, pCC))
{
if (NULL != IsOpened())
{
::PurgeComm(m_hCOM, PURGE_RXABORT | PURGE_TXABORT);
bRet=::SetCommConfig(m_hCOM, pCC, dwCCSize);
bRet = SetCommState(&pCC->dcb);
delete[] LPBYTE(pCC);
::PurgeComm(m_hCOM, PURGE_TXCLEAR | PURGE_RXCLEAR);
}
}
m_bShowCommConfigDialog = FALSE;
return BOOL(bRet);
}
}
return BOOL(FALSE);
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
//设置当前的异步写属性
//<参数>
// bAsyncOutput: 异步写属性设置值
//<返回值> 无
void CSerialComm::SetAsyncOutput(BOOL bAsyncOutput)
{
#if !defined(SC_MSCOMOBJECT)
m_bAsyncOutput = bAsyncOutput;
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
//获取当前的异步写属性
//<参数> 无
//<返回值>
// 返回当前的异步写属性。
BOOL CSerialComm::GetAsyncOutput()
{
#if !defined(SC_MSCOMOBJECT)
return BOOL(m_bAsyncOutput);
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
//以单片机多机通讯模式向指定地址发送数据
//<参数>
// ucAddr: 指定地址
// pData: 指定待发数据
// lWriteSize: 指定待发数据长度
//<返回值>
// 返回正确写出的字节数。出错时返回值小于0。
long CSerialComm::WriteTo(BYTE ucAddr, LPVOID pData, long lWriteSize)
{
#if !defined(SC_MSCOMOBJECT)
if (INVALID_HANDLE_VALUE == m_hCOM || NULL == m_hCOM)
return long(-6);
COMSTAT stCOMStat;
DWORD dwErr = 0;
//如果入口参数无效则试图返回输入缓冲区中的数据长度
if (NULL == pData || 0 > lWriteSize)
{
if (FALSE == ::ClearCommError(m_hCOM, &dwErr, &stCOMStat))
return long(-7);
return long(stCOMStat.cbOutQue);
}
m_stDCB.Parity = MARKPARITY;
m_stDCB.fParity = TRUE;
::SetCommState(m_hCOM, &m_stDCB);
BOOL bAsyncOutput = m_bAsyncOutput;
m_bAsyncOutput = FALSE;
long lWrited = Write(&ucAddr, sizeof(BYTE));
if (sizeof(BYTE) != lWrited)
{
m_bAsyncOutput = bAsyncOutput;
m_stDCB.Parity = SPACEPARITY;
::SetCommState(m_hCOM, &m_stDCB);
if (lWrited < 0)
return long(lWrited);
return long(-8);
}
m_bAsyncOutput = bAsyncOutput;
m_stDCB.Parity = SPACEPARITY;
::SetCommState(m_hCOM, &m_stDCB);
return long(Write(pData, lWriteSize));
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
//在当前串行通讯端口等待接收第九位为'1'的地址数据
//<参数>
// pucAddr: 指定用于接收地址数据的缓冲区
//<返回值>
// 如果成功返回TRUE,否则返回FALSE。
// 注: 该方法一般用于与单片机进行通讯,数据第九位为'0',地址第九位为'1'。通讯
//时,校验方式设置为空校验方式以保证发送的数据数据第九位为'0'。
BOOL CSerialComm::ScanAddr(LPBYTE pucAddr)
{
#if !defined(SC_MSCOMOBJECT)
if (INVALID_HANDLE_VALUE == m_hCOM || NULL == m_hCOM || NULL == pucAddr)
return BOOL(FALSE);
if (sizeof(BYTE) != Read(pucAddr, sizeof(BYTE)))
return BOOL(FALSE);
DWORD dwError = 0;
COMSTAT stCOMStat;
if (FALSE == ::ClearCommError(m_hCOM, &dwError, &stCOMStat))
return BOOL(FALSE);
//由于处于空校验方式,如果出现接收校验错误即表示收到了第九位为'1'的数据。
if (FALSE == BOOL(dwError & CE_RXPARITY))
{
if (0 < stCOMStat.cbInQue)
{
LPBYTE pBuff = new BYTE[stCOMStat.cbInQue];
Read(pBuff, stCOMStat.cbInQue);
delete[] pBuff;
}
return BOOL(FALSE);
}
return BOOL(TRUE);
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
//设置当前串行通讯端口的DCB参数
//<参数>
// pDCB: 指定DCB数据
//<返回值>
// 如果成功则返回TRUE,否则返回FALSE。
BOOL CSerialComm::SetCommState(DCB *pDCB)
{
#if !defined(SC_MSCOMOBJECT)
if (INVALID_HANDLE_VALUE == m_hCOM || NULL == m_hCOM || NULL == pDCB)
return BOOL(FALSE);
::PurgeComm(m_hCOM, PURGE_RXABORT | PURGE_TXABORT);
if (FALSE == ::SetCommState(m_hCOM, pDCB))
return BOOL(FALSE);
::memcpy(&m_stDCB, pDCB, sizeof(DCB));
::PurgeComm(m_hCOM, PURGE_TXCLEAR | PURGE_RXCLEAR);
if (FALSE != ::GetCommTimeouts(m_hCOM, &m_stCTO))
{
int iBits = 1 + m_stDCB.ByteSize + ((m_stDCB.StopBits == ONESTOPBIT) ? 1 : 2);
m_stCTO.ReadIntervalTimeout = 10; //10ms的区间超时
m_stCTO.ReadTotalTimeoutMultiplier = (iBits * 1000) / m_stDCB.BaudRate; //传输一个字节所需的时间
if (0 == m_stCTO.ReadTotalTimeoutMultiplier)
m_stCTO.ReadTotalTimeoutMultiplier = 1;
m_stCTO.ReadTotalTimeoutConstant = m_stCTO.ReadTotalTimeoutMultiplier * 10;
m_stCTO.WriteTotalTimeoutMultiplier = ((iBits + 2) * 1000) / m_stDCB.BaudRate; //传输一个字节所需的时间
if (0 == m_stCTO.WriteTotalTimeoutMultiplier)
m_stCTO.WriteTotalTimeoutMultiplier = 1;
m_stCTO.WriteTotalTimeoutConstant = m_stCTO.WriteTotalTimeoutMultiplier * 10;
::SetCommTimeouts(m_hCOM, &m_stCTO);
}
return BOOL(TRUE);
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
//获取当前的DCB镜像
//<参数>
// pDCB: 指向一个用于接收DCB数据的缓冲区
//<返回值>
// 如果成功返回TRUE,否则返回FALSE。
BOOL CSerialComm::GetCommState(DCB *pDCB)
{
#if !defined(SC_MSCOMOBJECT)
if (INVALID_HANDLE_VALUE == m_hCOM || NULL == m_hCOM || NULL == pDCB)
return BOOL(FALSE);
if (FALSE == ::GetCommState(m_hCOM, pDCB))
return BOOL(FALSE);
::memcpy(&m_stDCB, pDCB, sizeof(DCB));
return BOOL(TRUE);
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
//设置当前的波特率属性
//<参数>
// dwBaudrate: 波特率属性设置值
//<返回值> 无
void CSerialComm::SetBaudrate(DWORD dwBaudrate)
{
#if !defined(SC_MSCOMOBJECT)
m_stDCB.BaudRate = FormatBaudrate(dwBaudrate);
SetCommState(&m_stDCB);
if (FALSE != ::GetCommTimeouts(m_hCOM, &m_stCTO))
{
int iBits = 1 + m_stDCB.ByteSize + ((m_stDCB.StopBits == ONESTOPBIT) ? 1 : 2);
m_stCTO.ReadIntervalTimeout = 10; //10ms的区间超时
m_stCTO.ReadTotalTimeoutMultiplier = (iBits * 1000) / m_stDCB.BaudRate; //传输一个字节所需的时间
if (0 == m_stCTO.ReadTotalTimeoutMultiplier)
m_stCTO.ReadTotalTimeoutMultiplier = 1;
m_stCTO.ReadTotalTimeoutConstant = m_stCTO.ReadTotalTimeoutMultiplier * 10;
m_stCTO.WriteTotalTimeoutMultiplier = ((iBits + 2) * 1000) / m_stDCB.BaudRate; //传输一个字节所需的时间
if (0 == m_stCTO.WriteTotalTimeoutMultiplier)
m_stCTO.WriteTotalTimeoutMultiplier = 1;
m_stCTO.WriteTotalTimeoutConstant = m_stCTO.WriteTotalTimeoutMultiplier * 10;
::SetCommTimeouts(m_hCOM, &m_stCTO);
}
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
//获取当前的波特率属性
//<参数> 无
//<返回值>
// 返回当前的波特率属性。
DWORD CSerialComm::GetBaudrate()
{
#if !defined(SC_MSCOMOBJECT)
return DWORD(m_stDCB.BaudRate);
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
//设置当前的数据位数属性
//<参数>
// ucSize: 数据位数属性设置值
//<返回值> 无
void CSerialComm::SetByteSize(BYTE ucSize)
{
#if !defined(SC_MSCOMOBJECT)
BYTE ucOldSet = m_stDCB.ByteSize;
m_stDCB.ByteSize = ucSize;
if (FALSE == SetCommState(&m_stDCB))
{
m_stDCB.ByteSize = ucOldSet;
}
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
//获取当前的数据位数属性
//<参数> 无
//<返回值>
// 返回当前的数据位数属性。
BYTE CSerialComm::GetByteSize()
{
#if !defined(SC_MSCOMOBJECT)
return BYTE(m_stDCB.ByteSize);
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
//设置当前的校验方式属性
//<参数>
// ucParity: 校验方式属性设置值
//<返回值> 无
void CSerialComm::SetParity(BYTE ucParity)
{
#if !defined(SC_MSCOMOBJECT)
m_stDCB.Parity = FormatParity(ucParity);
SetCommState(&m_stDCB);
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
//获取当前的校验方式属性
//<参数> 无
//<返回值>
// 返回当前的校验方式属性。
BYTE CSerialComm::GetParity()
{
#if !defined(SC_MSCOMOBJECT)
return BYTE(m_stDCB.Parity);
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
//设置当前的停止位数属性
//<参数>
// ucStopBits: 停止位数属性设置值
//<返回值> 无
void CSerialComm::SetStopBits(BYTE ucStopBits)
{
#if !defined(SC_MSCOMOBJECT)
BYTE ucOldSet = m_stDCB.StopBits;
m_stDCB.StopBits = ucStopBits;
if (FALSE == SetCommState(&m_stDCB))
{
m_stDCB.StopBits = ucOldSet;
}
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
//获取当前的停止位数属性
//<参数> 无
//<返回值>
// 返回当前的停止位数属性。
BYTE CSerialComm::GetStopBits()
{
#if !defined(SC_MSCOMOBJECT)
return BYTE(m_stDCB.StopBits);
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
void CSerialComm::ClearReadBuffer()
{
#if !defined(SC_MSCOMOBJECT)
if (INVALID_HANDLE_VALUE != m_hCOM || NULL != m_hCOM)
{
::PurgeComm(m_hCOM, PURGE_RXCLEAR);
}
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
void CSerialComm::ClearWriteBuffer()
{
#if !defined(SC_MSCOMOBJECT)
if (INVALID_HANDLE_VALUE != m_hCOM || NULL != m_hCOM)
{
::PurgeComm(m_hCOM, PURGE_TXCLEAR);
}
#else //if !defined(SC_MSCOMOBJECT)
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -