一个简单得异步串口类

类别:编程语言 点击:0 评论:0 推荐:

本来程序里面是有很详细注释得,但是不知道何故,粘贴过来之后中文全部是乱码,没的办法,只好将注释全部去掉了。

这个异步类只实现了一些简单功能。在使用时候需要注意下面几点:
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