📄 mutithreadserial.cpp
字号:
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MutithreadSerial.h"
//#include "O231BatteryDevDef.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
MutithreadSerial::MutithreadSerial()
{
bCommConnected = false;//端口连接标志
iBaud = 9600; //初始化波特率
m_iWhichCommand = 0; //初始化命令标志
memset(this->m_bReData,0x00,sizeof(this->m_bReData));
m_iRevLen = 0; //初始化接收长度
Com1IsOpen = false;
Com2IsOpen = false;
bCommRxSign = false;
m_bShakeHandFlag = false;
}
MutithreadSerial::~MutithreadSerial()
{
}
UINT jThreadFunction(LPVOID lpParam)
{
//线程函数主体,监视串口
MutithreadSerial *pComm = ( MutithreadSerial*)lpParam;
OVERLAPPED os;
DWORD dwEventMask, dwTransfer;
DWORD dwErrorFlags;
COMSTAT ComStat;
memset(&os, 0, sizeof(OVERLAPPED));
os.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); //FALSE: nonsignaled
if (os.hEvent == NULL)
{
return FALSE;
}
if (!SetCommMask(pComm->hCom, EV_RXCHAR))
return FALSE;
//Loop until user requests disconnect
while (pComm->bCommConnected)
{
ClearCommError(pComm->hCom, &dwErrorFlags, &ComStat);
if(ComStat.cbInQue)
{
pComm->bCommRxSign = true;
ResetEvent(pComm->hPostMsgEvent);
pComm->OnCommRecvNotify(0,0);
WaitForSingleObject(pComm->hPostMsgEvent, 0xFFFFFFFF);
continue;
}
dwEventMask = 0;
if (!WaitCommEvent(pComm->hCom, &dwEventMask, &os))// dwEventMask: receive event
{
//WaitCommEvent()没有等到结果,如果ERROR_IO_PENDING == GetLastError()
//就用GetOverlappedResult()来等待。
if (ERROR_IO_PENDING == GetLastError())
{
GetOverlappedResult(pComm->hCom, &os, &dwTransfer, TRUE); //dwTransfer:actual bytes count
//TRUE:If TRUE, the function does not return until the operation has been completed.
}
}
if ((dwEventMask & EV_RXCHAR) == EV_RXCHAR)
{
//Sets the state of the event to nonsignaled until explicitly set to signaled by the SetEvent member function.
pComm->bCommRxSign = true;
ResetEvent(pComm->hPostMsgEvent);
pComm->OnCommRecvNotify(0, 0);
WaitForSingleObject(pComm->hPostMsgEvent, 0xFFFFFFFF);
}
}
CloseHandle(os.hEvent);
return TRUE;
}
bool MutithreadSerial::InitComm(bool bDefault, int p_iCom , HWND p_hwnd)
{
this->m_hwnd231 = p_hwnd; //是主程序的窗口句柄,此参数必须传入,否则数据不能
//响应到主程序中去
CString l_sCommPort;
l_sCommPort.Format( "COM%d", p_iCom );
HANDLE l_hCom = CreateFile(l_sCommPort, GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
NULL); //以重叠I/O的形式打开串口
this->hCom = l_hCom;
if(hCom == INVALID_HANDLE_VALUE)
{
bCommOpenOk=false;
return false;
}
SetupComm(hCom, 4096, 4096);
COMMTIMEOUTS CommTimeOuts;
GetCommTimeouts(hCom, &CommTimeOuts);
if(!SetCommMask(hCom, EV_RXCHAR))
{
return false;
}
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;//20;
CommTimeOuts.ReadTotalTimeoutConstant = 0;//1000;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;//20;
CommTimeOuts.WriteTotalTimeoutConstant = 5000;//1000
SetCommTimeouts(hCom, &CommTimeOuts);
DCB Dcb;
Dcb.DCBlength = sizeof(DCB);
GetCommState(hCom, &Dcb);
if(bDefault)
{
Dcb.BaudRate = iBaud;
Dcb.ByteSize = 8;
//注意:260是无校验,230是MARKPARITY
Dcb.Parity = MARKPARITY;//NOPARITY;
Dcb.StopBits = ONESTOPBIT;
Dcb.fOutxDsrFlow = false;
Dcb.fOutxCtsFlow = false;
Dcb.fDtrControl = RTS_CONTROL_DISABLE;
Dcb.fRtsControl = RTS_CONTROL_DISABLE;
Dcb.fInX = false;
Dcb.fOutX = false;
}
else
{
Dcb.BaudRate = CommDcb.BaudRate;
Dcb.ByteSize = CommDcb.ByteSize;
Dcb.Parity = CommDcb.Parity;
Dcb.StopBits = CommDcb.StopBits;
}
Dcb.fBinary = TRUE;
Dcb.fParity = TRUE;
Dcb.wReserved = 0;
if(!SetCommState(hCom,&Dcb))
return false;
if((hPostMsgEvent = CreateEvent(NULL, TRUE, TRUE, NULL))==NULL) //有信号状态
return FALSE;
PurgeComm( hCom, PURGE_RXCLEAR | PURGE_TXABORT |PURGE_TXCLEAR| PURGE_RXABORT);
bCommOpenOk = true;
if(p_iCom == 1)
{
Com1IsOpen = true;
}
if(p_iCom == 2)
{
Com2IsOpen = true;
}
return true;
}
DWORD MutithreadSerial::WriteComm(unsigned char *buf, DWORD dwLength)
{
BOOL fState;
DWORD l_dwRes;
DWORD length = dwLength;
COMSTAT ComStat;
DWORD dwErrorFlags = 0;
OVERLAPPED osWrite = {0} ;
if((osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))==NULL)
{
length = 0;
return length;
}
ClearCommError(hCom, &dwErrorFlags, &ComStat);
fState = WriteFile(hCom, buf, length, &length, &osWrite);
if(!fState)
{
if(GetLastError() == ERROR_IO_PENDING)
{
l_dwRes = WaitForSingleObject(osWrite.hEvent, INFINITE);
switch(l_dwRes)
{
case WAIT_OBJECT_0:
if (!GetOverlappedResult(hCom, &osWrite, &length, FALSE))
{
length = 0;
}
else
{
return length;
}
break;
default:
length = 0;
break;
}
}
else
length = 0;
}
return length;
}
DWORD MutithreadSerial::ReadComm(unsigned char *buf, DWORD dwLength)
{
DWORD length = 0;
COMSTAT ComStat;
DWORD dwErrorFlags;
Sleep(250);
ClearCommError(hCom, &dwErrorFlags, &ComStat);
length = min(dwLength, ComStat.cbInQue);
ReadFile(hCom, buf, length, &length, &osRead);
return length;
}
/////////////////////////////////////////////////////////////
void MutithreadSerial::CloseComm()
{
bCommConnected = FALSE;
bCommOpenOk = false;
SetCommMask(hCom, 0);
EscapeCommFunction(hCom, CLRDTR);
PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR);
CloseHandle(hCom);
pThread = NULL;
}
bool MutithreadSerial::BeginComm()
{
bool fRetVal;
if (!bCommOpenOk) return false;
bCommConnected = true;
if((pThread = AfxBeginThread(jThreadFunction, this)) == NULL)
{
bCommConnected = false;
CloseHandle(hCom);
fRetVal = FALSE;
return fRetVal;
}
else
{
//函数会建立一个辅助线程并暂时将其挂起。
//调用CWinThread:: ResumeThread使线程开始运行
pThread->SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
pThread->ResumeThread();
EscapeCommFunction(hCom, SETDTR);
}
return TRUE;
}
bool MutithreadSerial::ChangeBaud()
{
//此函数现在没有用到。
if(hCom==NULL)
return false;
COMMTIMEOUTS CommTimeOuts;
GetCommTimeouts(hCom, &CommTimeOuts);
if(!SetCommMask(hCom, EV_RXCHAR))
{
return false;
}
SetupComm(hCom, 4096, 4096);
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 5000;
SetCommTimeouts(hCom, &CommTimeOuts);
DCB Dcb;
Dcb.DCBlength = sizeof(DCB);
GetCommState(hCom,&Dcb);
Dcb.BaudRate=iBaud;
Dcb.ByteSize=8;
Dcb.Parity=NOPARITY;
Dcb.StopBits=ONESTOPBIT;
Dcb.fOutxDsrFlow = false;
Dcb.fOutxCtsFlow = false;
Dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
Dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
Dcb.fInX = Dcb.fOutX = false;
//Dcb.XonChar = ASCII_XON;
//Dcb.XoffChar = ASCII_XOFF;
Dcb.XonLim = 100;
Dcb.XoffLim = 100;
Dcb.fBinary = TRUE;
Dcb.fParity = TRUE;
if(!SetCommState(hCom,&Dcb))
return false;
return true;
}
void MutithreadSerial::OnCommRecvNotify(WPARAM wParam, LPARAM lParam)
{
//取得数据缓冲
this->iCommGetCounter = ReadComm((unsigned char *)sCommGetBuffer,COMM232GETDATAMAX);
if(this->iCommGetCounter == 0)
{
SetEvent(hPostMsgEvent); //根本就没有取到数据,所以返回
return;
}
MutithreadSerial *p_Comm = this;
memset(m_bReData, 0x00, sizeof(m_bReData)); //每一次都必须初始化
memcpy(this->m_bReData, sCommGetBuffer, this->iCommGetCounter*sizeof(BYTE));
memset(sCommGetBuffer, 0x00, COMM232GETDATAMAX * sizeof(BYTE)); //清空接收缓冲
if(this->m_bReData[2] == 0x88)//通信协议制定的。
{
//是主动上传的数据
::SendMessage(p_Comm->m_hwnd231, WM_ACTIVE_TRANS, 0, 0);
Sleep(3);
}
else//查询方式的返回
{
::SendMessage(p_Comm->m_hwnd231, WM_SEND_AND_RETURN, 0, 0);
Sleep(3);
}
//允许发送下一个WM_COMMNOTIFY消息
SetEvent(hPostMsgEvent);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -