|
/**//* CommUtils.h */ #ifndef _CommUtils_H__ #define _CommUtils_H__
class CommUtils { public: bool ReadCom(unsigned char * ReceiveData, DWORD& ReceiveLength); void CloseCom(); bool WriteCom(unsigned char * sendchar,int sendsize); bool OpenCom(int Port);
CommUtils(); virtual ~CommUtils(); int m_Port; char szCurPath[256];
private: OVERLAPPED ReadovReady, WriteovReady; HANDLE hComm; bool bOpenCom; };
#endif
/**//* CommUtils.cpp 串口通讯类 Author: edog 2007-11-21 EMail: comwell@126.com */ #include "stdafx.h" #include "CommUtils.h" #include "stdio.h" const int READ_TIMEOUT = 500;
CommUtils::CommUtils() { bOpenCom = false; }
CommUtils::~CommUtils() { this->CloseCom(); }
bool CommUtils::OpenCom(int Port) { if (bOpenCom) { this->CloseCom(); bOpenCom = false; } char szport[10]; sprintf(szport,"COM%d",Port); hComm = CreateFile( szport, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, //FILE_ATTRIBUTE_NORMAL| NULL); if (hComm == INVALID_HANDLE_VALUE) return false; if (!SetupComm(hComm, 1024, 512)) return false; COMMTIMEOUTS commtimeouts; commtimeouts.ReadIntervalTimeout = MAXDWORD; commtimeouts.ReadTotalTimeoutConstant =0; commtimeouts.ReadTotalTimeoutMultiplier =0; commtimeouts.WriteTotalTimeoutConstant =0; commtimeouts.WriteTotalTimeoutMultiplier=0; if (!SetCommTimeouts(hComm, &commtimeouts)) return false;
memset(&ReadovReady,0,sizeof(OVERLAPPED)); memset(&WriteovReady,0,sizeof(OVERLAPPED)); ReadovReady.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); WriteovReady.hEvent =CreateEvent(NULL,TRUE,FALSE,NULL); SECURITY_ATTRIBUTES sa; sa.nLength=sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor=NULL; sa.bInheritHandle=TRUE; DCB dcb; GetCommState(hComm, &dcb); dcb.fBinary = TRUE; dcb.fParity = TRUE; dcb.BaudRate = CBR_9600; // 波特率 9600 dcb.ByteSize = 8; // 8 位数据位 dcb.Parity = NOPARITY; // 无奇偶校验 dcb.StopBits = ONESTOPBIT; // 1 个停止位 if (!SetCommState(hComm, &dcb )) return false;
bOpenCom = true; return bOpenCom; }
bool CommUtils::WriteCom(unsigned char *sendchar, int sendsize) { if (!bOpenCom) return false; DWORD BytesSent; DWORD resD; PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT); BytesSent=0; BOOL hr = WriteFile(hComm, // Handle to COMM Port sendchar, // Pointer to message buffer in calling finction sendsize, // Length of message to send &BytesSent, // Where to store the number of bytes sent &WriteovReady); // Overlapped structure if(!hr) { if(GetLastError() != ERROR_IO_PENDING) { return false; } else { resD=WaitForSingleObject(WriteovReady.hEvent,INFINITE); } switch(resD) { case WAIT_OBJECT_0: { if(!GetOverlappedResult(hComm,&WriteovReady,&BytesSent,false)) return false; else return true; } default: return false; break; } } return true; }
void CommUtils::CloseCom() { if (!bOpenCom) return;
CloseHandle(hComm); hComm=NULL; CloseHandle(ReadovReady.hEvent); CloseHandle(WriteovReady.hEvent ); ReadovReady.hEvent =NULL; WriteovReady.hEvent =NULL; }
bool CommUtils::ReadCom(unsigned char * ReceiveData, DWORD& ReceiveLength) { if (!bOpenCom) return false; if (ReadovReady.hEvent == NULL) return false; ReceiveLength = 0; if (ReadFile(hComm, ReceiveData, 128, &ReceiveLength, &ReadovReady) == FALSE) { if (GetLastError() != ERROR_IO_PENDING) return false; }
if(ReceiveLength == 0) return false; ReceiveData[ReceiveLength] = 0;
DWORD dwRead; DWORD dwRes = WaitForSingleObject(ReadovReady.hEvent, READ_TIMEOUT); switch(dwRes) { case WAIT_OBJECT_0: if (!GetOverlappedResult(hComm, &ReadovReady, &dwRead, FALSE)) return false; break;
case WAIT_TIMEOUT: break; default: break; } return true; }
以下为使用方法:
// 1. 包含头文件,定义变量 #include "CommUtils.h" CommUtils theComm; unsigned char data[1024]; unsigned long len = 0;
// 2. 打开串口,设置接收定时器 theComm.OpenCom(1); // 打开COM1口 SetTimer(1, 50, 0);
// 3. 发送数据 theComm.WriteCom(data, len);
// 4. 接收数据处理 void CUARTDlg::OnTimer(UINT nIDEvent) { if (nIDEvent == 1) { if (theComm.ReadCom(data, len)) { if (len > 0) { // 接收数据处理。。。 } } } CDialog::OnTimer(nIDEvent); }
|