本来程序里面是有很详细注释得,但是不知道何故,粘贴过来之后中文全部是乱码,没的办法,只好将注释全部去掉了。
这个异步类只实现了一些简单功能。在使用时候需要注意下面几点:
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;
}
本文地址:http://com.8s8s.com/it/it26008.htm