本来程序里面是有很详细注释得,但是不知道何故,粘贴过来之后中文全部是乱码,没的办法,只好将注释全部去掉了。
这个异步类只实现了一些简单功能。在使用时候需要注意下面几点: 1。串口得相关参数需要在open之前设置好,打开之后,就不能设置了 2。读取串口数据采取查询方式 3。向串口发送数据函数得执行需要一定得时间,知道成功它才返回。 4。默认是没有硬件握手得,如果要握手,需要调用函数setflowctrl 5。串口波特率直接传递数值就可以,比如9600。
头文件如下: //AsynComm.h //moonight //2004-10-31
#include <windows.h>
/* MODEM CONTROL setting */ #define C_DTR 0x01 #define C_RTS 0x02
/* MODEM LINE STATUS */ #define S_CTS 0x01 #define S_DSR 0x02 #define S_RI 0x04 #define S_CD 0x08
#define SIO_OK 0 #define SIO_ERROR -1
class CAsynComm { public: CAsynComm(); virtual ~CAsynComm(); protected: volatile int nPort; volatile HANDLE ComHandle; DCB MyDcb; int InbufSize, OutbufSize; COMMTIMEOUTS coTimeOut; OVERLAPPED ro,wo; void Init(); bool IsOpen(); public: int getch(); int putch(char ch); int read(char *buf, int len); int write(char *buf, int len); int close(); virtual int open(int port); int setsetting(int BaudRate, int ByteSize = 8, int Parity = NOPARITY, int StopBits = ONESTOPBIT); int setflowctrl(); int getlstatus(); int setdtr(bool enable); int setrts(bool enable); int settimeout(unsigned long ulTimeOut); int setiosize(int isize,int osize); };
CPP文件如下: // AsynComm.cpp: implementation of the CAsynComm class. // //////////////////////////////////////////////////////////////////////
#include "AsynComm.h"
////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CAsynComm::CAsynComm() { Init(); }
CAsynComm::~CAsynComm() { close(); if(ro.hEvent != INVALID_HANDLE_VALUE) CloseHandle(ro.hEvent);
if(wo.hEvent != INVALID_HANDLE_VALUE) CloseHandle(wo.hEvent); }
void CAsynComm::Init() { memset(&MyDcb, 0, sizeof(MyDcb)); MyDcb.DCBlength = sizeof(MyDcb); MyDcb.BaudRate = 9600; MyDcb.ByteSize = 8; MyDcb.Parity = NOPARITY; MyDcb.StopBits = ONESTOPBIT; ComHandle = INVALID_HANDLE_VALUE; InbufSize = 8192; OutbufSize = 8192; memset(&coTimeOut, 0, sizeof(coTimeOut)); coTimeOut.ReadIntervalTimeout = 0xFFFFFFFF; coTimeOut.ReadTotalTimeoutMultiplier = 0; coTimeOut.ReadTotalTimeoutConstant = 0; coTimeOut.WriteTotalTimeoutMultiplier = 0; coTimeOut.WriteTotalTimeoutConstant = 5000; memset(&ro, 0, sizeof(ro)); memset(&wo, 0, sizeof(wo)); ro.hEvent = CreateEvent(NULL, true, false, NULL); wo.hEvent = CreateEvent(NULL, true, false, NULL); }
bool CAsynComm::IsOpen() { return (ComHandle!=INVALID_HANDLE_VALUE); }
int CAsynComm::close() { if(IsOpen()) CloseHandle(ComHandle); ComHandle = INVALID_HANDLE_VALUE; return SIO_OK; }
int CAsynComm::read(char *buf, int len) { if(!IsOpen()) return SIO_ERROR; memset(buf,0,len);
COMSTAT stat; DWORD error;
if(ClearCommError(ComHandle, &error, &stat) && error > 0) { PurgeComm(ComHandle, PURGE_RXABORT | PURGE_RXCLEAR); return SIO_ERROR; } if(!stat.cbInQue) return SIO_ERROR;
unsigned long count = 0; len = min((int)(len - 1), (int)stat.cbInQue);
if(!ReadFile(ComHandle, buf, len, &count, &ro)) { if(GetLastError() == ERROR_IO_PENDING) { if(!GetOverlappedResult(ComHandle, &ro, &count, false)) { if(GetLastError() != ERROR_IO_INCOMPLETE) count = 0; } } else count = 0; } if(count>0) { buf[count] = '\0'; return count; } return SIO_ERROR; }
int CAsynComm::getch() { if(!IsOpen()) return SIO_ERROR; COMSTAT stat; DWORD error; char buf[2];
if(ClearCommError(ComHandle, &error, &stat) && error > 0) { PurgeComm(ComHandle, PURGE_RXABORT | PURGE_RXCLEAR); return SIO_ERROR; } if(!stat.cbInQue) return SIO_ERROR; unsigned long count = 0;
if(!ReadFile(ComHandle, buf, 1, &count, &ro)) { if(GetLastError() == ERROR_IO_PENDING) { if(!GetOverlappedResult(ComHandle, &ro, &count, false)) { if(GetLastError() != ERROR_IO_INCOMPLETE) count = 0; } } else count = 0; } if(count>0) { return ((int)(buf[0])); } return SIO_ERROR; }
int CAsynComm::write(char *buf, int len) { if(!IsOpen()) return SIO_ERROR;
if(buf==NULL) return SIO_ERROR; DWORD error; if(ClearCommError(ComHandle, &error, NULL) && error > 0) { PurgeComm(ComHandle, PURGE_TXABORT | PURGE_TXCLEAR); } unsigned long count = 0; unsigned long value=0; if(!WriteFile(ComHandle, buf, len, &count, &wo)) { value=GetLastError(); if(value != ERROR_IO_PENDING) count = 0; else { if(!GetOverlappedResult(ComHandle, &wo, &count, TRUE)) { if(GetLastError() != ERROR_IO_INCOMPLETE) count = 0; } } } if(count>0) return count; return SIO_ERROR; }
int CAsynComm::putch(char ch) { if(!IsOpen()) return SIO_ERROR; DWORD error; char buf[2]; if(ClearCommError(ComHandle, &error, NULL) && error > 0) { PurgeComm(ComHandle, PURGE_TXABORT | PURGE_TXCLEAR); } buf[0]=ch; buf[1]=0; unsigned long count = 0; if(!WriteFile(ComHandle, buf, 1, &count, &wo)) { if(GetLastError() != ERROR_IO_PENDING) count = 0; } if(count>0) return SIO_OK; return SIO_ERROR; }
int CAsynComm::open(int port) { if(port>1024 || port<1) return SIO_ERROR; if(IsOpen()) close(); nPort = port; char str[10]; if(ro.hEvent==INVALID_HANDLE_VALUE || wo.hEvent==INVALID_HANDLE_VALUE) return SIO_ERROR; strcpy(str, "COM"); ltoa(port, str + 3, 10); ComHandle = CreateFile( str, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL ); if(!IsOpen()) return SIO_ERROR; SetupComm(ComHandle, InbufSize, OutbufSize); SetCommState(ComHandle, &MyDcb); SetCommTimeouts(ComHandle, &coTimeOut); PurgeComm(ComHandle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); return SIO_OK; }
int CAsynComm::setsetting(int BaudRate, int ByteSize, int Parity, int StopBits) { if(IsOpen()) return SIO_ERROR; MyDcb.BaudRate = BaudRate; MyDcb.ByteSize = ByteSize; MyDcb.Parity = Parity; MyDcb.StopBits = StopBits; return SIO_OK; }
int CAsynComm::settimeout(unsigned long ulTimeOut) { if(IsOpen()) return SIO_ERROR; coTimeOut.WriteTotalTimeoutConstant = ulTimeOut; return SIO_OK; }
int CAsynComm::setflowctrl() { if(IsOpen()) return SIO_ERROR; MyDcb.fOutxCtsFlow=TRUE; MyDcb.fRtsControl=TRUE; return SIO_OK; }
int CAsynComm::getlstatus() { COMSTAT stat; DWORD error; int ret=0; if(!IsOpen()) return SIO_ERROR; if(ClearCommError(ComHandle, &error, &stat) && error > 0) { PurgeComm(ComHandle, PURGE_RXABORT | PURGE_RXCLEAR); return SIO_ERROR; } if(stat.fCtsHold) ret|=S_CTS; if(stat.fDsrHold) ret|=S_DSR; if(stat.fRlsdHold) ret|=S_RI; return ret; }
int CAsynComm::setdtr(bool enable) { if(!IsOpen()) return SIO_ERROR; DWORD data=CLRDTR; if(enable)data=SETDTR; if(EscapeCommFunction(ComHandle,data))return SIO_OK; return SIO_ERROR; }
int CAsynComm::setrts(bool enable) { if(!IsOpen()) return SIO_ERROR; DWORD data=CLRRTS; if(enable)data=SETRTS; if(EscapeCommFunction(ComHandle,data))return SIO_OK; return SIO_ERROR; }
int CAsynComm::setiosize(int isize,int osize) { if(IsOpen()) return SIO_ERROR; if(isize<=0) return SIO_ERROR; if(osize<=0) return SIO_ERROR; InbufSize = isize; OutbufSize = osize; return SIO_OK; } 
|