📄 serial.cpp
字号:
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSerial::SetRTS
// 功能描述 :
// 参数 : BOOL OnOrOff
// 返回值 : BOOL
//
///////////////////////////////////////////////////////////////////////
BOOL CSerial::SetRTS(BOOL OnOrOff)
{
return IsOpen() ? ::EscapeCommFunction(m_hCom, OnOrOff ? SETRTS:CLRRTS):FALSE;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSerial::SetBreak
// 功能描述 :
// 参数 : BOOL OnOrOff
// 返回值 : BOOL
//
///////////////////////////////////////////////////////////////////////
BOOL CSerial::SetBreak(BOOL OnOrOff)
{
return IsOpen() ? ::EscapeCommFunction(m_hCom, OnOrOff ? SETBREAK:CLRBREAK):FALSE;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSerial::SetMaskEvent
// 功能描述 :
// 参数 : DWORD dwMask
// 返回值 : void
//
///////////////////////////////////////////////////////////////////////
void CSerial::SetMaskEvent(DWORD dwMask)
{
m_dwMaskEvent = dwMask;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSerial::OnCTS
// 功能描述 :
// 返回值 : void
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnCTS()
{
if(::IsWindow(m_hNotifyWnd))
{
DWORD dwStatus;
if(GetCommModemStatus(m_hCom, &dwStatus))
::SendMessage(m_hNotifyWnd, WM_COM_CTS, 0, dwStatus&MS_CTS_ON ? 1:0);
}
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSerial::OnDSR
// 功能描述 :
// 返回值 : void
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnDSR()
{
if(::IsWindow(m_hNotifyWnd))
{
DWORD dwStatus;
if(::GetCommModemStatus(m_hCom, &dwStatus))
{
::SendMessage(m_hNotifyWnd, WM_COM_DSR, 0, dwStatus&MS_DSR_ON ? 1:0);
}
}
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSerial::OnRing
// 功能描述 :
// 返回值 : void
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnRing()
{
if(::IsWindow(m_hNotifyWnd))
::SendMessage(m_hNotifyWnd, WM_COM_RING, 0, 0);
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSerial::OnRLSD
// 功能描述 :
// 返回值 : void
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnRLSD()
{
if(::IsWindow(m_hNotifyWnd))
::SendMessage(m_hNotifyWnd, WM_COM_RLSD, 0, 0);
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSerial::OnBreak
// 功能描述 :
// 返回值 : void
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnBreak()
{
if(::IsWindow(m_hNotifyWnd))
::SendMessage(m_hNotifyWnd, WM_COM_BREAK, 0, 0);
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSerial::OnError
// 功能描述 :
// 返回值 : void
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnError()
{
DWORD dwError;
::ClearCommError(m_hCom, &dwError, NULL);
if(::IsWindow(m_hNotifyWnd))
::SendMessage(m_hNotifyWnd, WM_COM_ERROR, 0, dwError);
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSerial::OnReceive
// 功能描述 :
// 返回值 : void
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnReceive()
{
if(::IsWindow(m_hNotifyWnd))
::SendMessage(m_hNotifyWnd, WM_COM_RECEIVE, 0, 0);
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSerial::OnTXEmpty
// 功能描述 :
// 返回值 : void
//
///////////////////////////////////////////////////////////////////////
void CSerial::OnTXEmpty()
{
if(::IsWindow(m_hNotifyWnd))
::SendMessage(m_hNotifyWnd, WM_COM_TXEMPTY, 0, 0);
}
// ---------------------------CSCSerial类---------------------------------//
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSCSerial::CSCSerial
// 功能描述 :
// 参数 : CSerial *pSerial
// 返回值 :
//
///////////////////////////////////////////////////////////////////////
CSCSerial::CSCSerial(CSerial *pSerial)
{
pSerial->SetNotifyNum(sizeof(CSerialFrame));
pSerial->SetMaskEvent(EV_RXCHAR | EV_BREAK | EV_TXEMPTY);
m_pSerial = pSerial;
m_sequence = 0;
m_nStatus = STATUS_IDLE;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSCSerial::ReadFrame
// 功能描述 :
// 返回值 : CSerialFrame*
//
///////////////////////////////////////////////////////////////////////
CSerialFrame* CSCSerial::ReadFrame()
{
CSerialFrame *pFrame = (CSerialFrame *)m_DataBuff;
if(m_pSerial->ReadData(m_DataBuff, sizeof(CSerialFrame), 100))
return pFrame;
else
return NULL;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSCSerial::ReadData
// 功能描述 :
// 返回值 : CSerialFrame*
//
///////////////////////////////////////////////////////////////////////
CSerialFrame* CSCSerial::ReadData()
{
CSerialFrame *pFrame = (CSerialFrame *)m_DataBuff;
int nChecksum;
// 试图读取帧头
if(m_pSerial->ReadData(m_DataBuff, sizeof(CSerialFrame), 100))
{
// 检查贞大小
if(pFrame->uDataLen > FRAME_SIZE)
{
m_pSerial->Purge();
return NULL;
}
// 传输其他字节
if(pFrame->uDataLen > 0)
{
if(!m_pSerial->ReadData(pFrame + 1, pFrame->uDataLen, 600))
{
m_pSerial->Purge();
TRACE(" CSerialServer::ReadData 读取数据超时 \r\n");
return NULL;
}
}
// 检查效验位
nChecksum = pFrame->uChecksum;
pFrame->uChecksum = 0;
if(nChecksum != checksum((USHORT*)pFrame, sizeof(CSerialFrame) + pFrame->uDataLen))
{
TRACE(" CSerialServer::ReadData 数据效验出错 \r\n");
SendRetry();
return NULL;
}
return pFrame;
}
else
{
m_pSerial->Purge();
return NULL;
}
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSCSerial::SendCommand
// 功能描述 :
// 参数 : BYTE command
// 返回值 : BOOL
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendCommand(BYTE command)
{
CSerialFrame frame;
memset(&frame, 0, sizeof(frame));
frame.command = command;
frame.uDataLen = 0;
frame.uChecksum = checksum((USHORT*)&frame, sizeof(frame));
if(m_pSerial->Write(&frame, sizeof(frame)) != sizeof(frame))
return FALSE;
return TRUE;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSCSerial::SendRetry
// 功能描述 :
// 返回值 : BOOL
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendRetry()
{
CSerialFrame frame;
memset(&frame, 0, sizeof(frame));
frame.command = SERIAL_ERROR;
frame.uDataLen = 0;
frame.uChecksum = checksum((USHORT*)&frame, sizeof(frame));
if(m_pSerial->Write(&frame, sizeof(frame)) != sizeof(frame))
return FALSE;
return TRUE;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSCSerial::SendAck
// 功能描述 :
// 返回值 : BOOL
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendAck()
{
CSerialFrame frame;
memset(&frame, 0, sizeof(frame));
frame.command = SERIAL_ACK;
frame.uDataLen = 0;
frame.uChecksum = checksum((USHORT*)&frame, sizeof(frame));
if(m_pSerial->Write(&frame, sizeof(frame)) != sizeof(frame))
return FALSE;
return TRUE;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSCSerial::SendData
// 功能描述 :
// 参数 : LPVOID Buffer
// 参数 : int nBufferLen
// 返回值 : BOOL
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendData(LPVOID Buffer, int nBufferLen)
{
if(nBufferLen > FRAME_SIZE)
return FALSE;
CSerialFrame *pFrame = (CSerialFrame *)m_DataBuff;
memset(pFrame, 0, sizeof(CSerialFrame));
// 构建贞
pFrame->command = SERIAL_DATA;
pFrame->uDataLen = nBufferLen;
pFrame->sequence = m_sequence;
memcpy(pFrame + 1, Buffer, nBufferLen);
pFrame->uChecksum = checksum((USHORT*)pFrame, sizeof(CSerialFrame) + nBufferLen);
if(m_pSerial->Write(pFrame, sizeof(CSerialFrame) + nBufferLen)
!= sizeof(CSerialFrame) + nBufferLen)
return FALSE;
return TRUE;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSCSerial::SendFileSize
// 功能描述 :
// 参数 : DWORD dwSize
// 返回值 : BOOL
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendFileSize(DWORD dwSize)
{
char buff[sizeof(CSerialFrame) + sizeof(DWORD)];
memset(buff, 0, sizeof(CSerialFrame) + sizeof(DWORD));
CSerialFrame *pFrame = (CSerialFrame *)buff;
CSerialFrame recv;
// build frame
pFrame->command = SERIAL_SIZE;
pFrame->uDataLen = sizeof(DWORD);
*(DWORD*)(pFrame + 1) = dwSize;
pFrame->uChecksum = checksum((USHORT*)pFrame, sizeof(CSerialFrame) + sizeof(DWORD));
// send it
if(m_pSerial->Write(pFrame, sizeof(CSerialFrame) + sizeof(DWORD))
!= sizeof(CSerialFrame) + sizeof(DWORD))
return FALSE;
// wait for ack
if(m_pSerial->ReadData(&recv, sizeof(recv), 1500))
{
// 检查效验和
int nChecksum = recv.uChecksum;
recv.uChecksum = 0;
if(nChecksum != checksum((USHORT*)&recv, sizeof(recv)))
return FALSE;
if(recv.command == SERIAL_ACK)
return TRUE;
else
return FALSE;
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSCSerial::SendFileData
// 功能描述 :
// 参数 : LPVOID Buffer
// 参数 : int nBufferLen
// 返回值 : BOOL
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendFileData(LPVOID Buffer, int nBufferLen)
{
if(nBufferLen > FRAME_SIZE)
return FALSE;
CSerialFrame *pFrame = (CSerialFrame *)m_DataBuff;
memset(pFrame, 0, sizeof(CSerialFrame));
// 构建贞
pFrame->command = SERIAL_DATA;
pFrame->uDataLen = nBufferLen;
pFrame->sequence = m_sequence;
memcpy(pFrame + 1, Buffer, nBufferLen);
pFrame->uChecksum = checksum((USHORT*)pFrame, sizeof(CSerialFrame) + nBufferLen);
while(TRUE)
{
CSerialFrame ack;
if(m_pSerial->Write(pFrame, sizeof(CSerialFrame) + nBufferLen)
!= sizeof(CSerialFrame) + nBufferLen)
return FALSE;
if(m_pSerial->ReadData(&ack, sizeof(ack), 1500))
{
// 检查效验和
int nChecksum = ack.uChecksum;
ack.uChecksum = 0;
if(nChecksum != checksum((USHORT*)&ack, sizeof(ack)))
return FALSE;
if(ack.command == SERIAL_ACK)
{
m_sequence++;
return TRUE;
}
else if(ack.command == SERIAL_ERROR)
continue;
else
return FALSE;
}
else
return FALSE;
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSCSerial::SendEOF
// 功能描述 :
// 返回值 : BOOL
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendEOF()
{
// 构建数据帧
CSerialFrame frame, ack;
memset(&frame, 0, sizeof(frame));
frame.command = SERIAL_EOF;
frame.uDataLen = 0;
// 计算校验和
frame.uChecksum = checksum((USHORT*)&frame, sizeof(frame));
// 发送数据帧
if(m_pSerial->Write(&frame, sizeof(frame)) != sizeof(frame))
return FALSE;
// 接收对方的“确认”消息
if(m_pSerial->ReadData(&ack, sizeof(ack), 1500))
{
// 检查效验和
int nChecksum = ack.uChecksum;
ack.uChecksum = 0;
if(nChecksum != checksum((USHORT*)&ack, sizeof(ack)))
return FALSE;
if(ack.command == SERIAL_ACK)
{
return TRUE;
}
else
return FALSE;
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSCSerial::SendAbort
// 功能描述 :
// 返回值 : BOOL
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendAbort()
{
CSerialFrame frame, ack;
memset(&frame, 0, sizeof(frame));
frame.command = SERIAL_ABORT;
frame.uDataLen = 0;
frame.uChecksum = checksum((USHORT*)&frame, sizeof(frame));
if(m_pSerial->Write(&frame, sizeof(frame)) != sizeof(frame))
return FALSE;
if(m_pSerial->ReadData(&ack, sizeof(ack), 1500))
{
// 检查效验和
int nChecksum = ack.uChecksum;
ack.uChecksum = 0;
if(nChecksum != checksum((USHORT*)&ack, sizeof(ack)))
return FALSE;
if(ack.command == SERIAL_ACK)
{
return TRUE;
}
else
return FALSE;
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : CSCSerial::SendInit
// 功能描述 :
// 返回值 : BOOL
//
///////////////////////////////////////////////////////////////////////
BOOL CSCSerial::SendInit()
{
return SendCommand(SERIAL_INIT); m_nStatus = STATUS_IDLE;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : checksum
// 功能描述 : 计算校验和
// 参数 : USHORT* buff 要计算校验和的缓冲区
// 参数 : int size buff缓冲区的大小
// 返回值 : USHORT 数据的校验和
//
///////////////////////////////////////////////////////////////////////
USHORT checksum(USHORT* buff, int size)
{
unsigned long cksum = 0;
while(size>1)
{
cksum += *buff++;
size -= sizeof(USHORT);
}
// 是奇数
if(size)
{
cksum += *(UCHAR*)buff;
}
// 将32位的chsum高16位和低16位相加,然后取反
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
return (USHORT)(~cksum);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -