这是我在一个后台系统摘抄出来的,在此基础上完成了一个独立的PPI读写程序(非DLL或控件方式)
//*************************************************************************//**模 块 名:YFCOM.cpp//**说 明:YFSoft 版权所有2005 - 2006(C)//**创 建 人:叶帆//**日 期:2006年4月4日//**修 改 人://**日 期://**描 述:串口操作//**版 本:V1.0//*************************************************************************#include "stdafx.h"#include "yfcom.h"
//串口句柄HANDLE m_COM_Handle;//两个信号全局变量(串口操作用)OVERLAPPED m_OverlappedRead, m_OverlappedWrite;
//*************************************************************************//函 数 名:OpenCom//输 入:long lngPort, 串口号// char *cfgMessage, 配置信息,形如"9600,e,8,1"// long lngInSize, 接收缓冲区大小// long lngOutSize 发送缓冲区大小//输 出:long//功能描述:打开串口//全局变量://调用模块://作 者:叶帆//日 期:2006年4月4日//修 改 人://日 期://版 本://*************************************************************************long OpenCom(long lngPort,char *cfgMessage,long lngInSize,long lngOutSize){ try { char szMsg[255]; DCB dcb; //打开端口 if (lngPort>9) sprintf( szMsg, ".//COM%d", lngPort ); else sprintf( szMsg, "COM%d", lngPort );
//用异步方式读写串口 m_COM_Handle = CreateFile(szMsg, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED , NULL ); if( m_COM_Handle == NULL ) return( 2 );
//清空异步读写参数 memset(&(m_OverlappedRead), 0, sizeof (OVERLAPPED)); memset(&(m_OverlappedWrite), 0, sizeof (OVERLAPPED)); //设置dcb块 dcb.DCBlength = sizeof( DCB ); //长度 GetCommState(m_COM_Handle , &dcb ); //波特率,奇偶校验,数据位,停止位 如:9600,n,8,1 sprintf(szMsg,"COM%d:%s", lngPort,cfgMessage); BuildCommDCB(szMsg,&dcb); //------------------------------ dcb.fBinary=TRUE; //二进制方式 dcb.fOutxCtsFlow=FALSE; //不用CTS检测发送流控制 dcb.fOutxDsrFlow=FALSE; //不用DSR检测发送流控制 dcb.fDtrControl=DTR_CONTROL_DISABLE; //禁止DTR流量控制 dcb.fDsrSensitivity=FALSE; //对DTR信号线不敏感 dcb.fTXContinueOnXoff=TRUE; //检测接收缓冲区 dcb.fOutX=FALSE; //不做发送字符控制 dcb.fInX =FALSE; //不做接收控制 dcb.fErrorChar=FALSE; //是否用指定字符替换校验错的字符 dcb.fNull=FALSE; //保留NULL字符 dcb.fRtsControl=RTS_CONTROL_ENABLE; //允许RTS流量控制 dcb.fAbortOnError=FALSE; //发送错误后,继续进行下面的读写操作 dcb.fDummy2=0; //保留 dcb.wReserved=0; //没有使用,必须为0 dcb.XonLim=0; //指定在XOFF字符发送之前接收到缓冲区中可允许的最小字节数 dcb.XoffLim=0; //指定在XOFF字符发送之前缓冲区中可允许的最小可用字节数 dcb.XonChar=0; //发送和接收的XON字符 dcb.XoffChar=0; //发送和接收的XOFF字符 dcb.ErrorChar=0; //代替接收到奇偶校验错误的字符 dcb.EofChar=0; //用来表示数据的结束 dcb.EvtChar=0; //事件字符,接收到此字符时,会产生一个事件 dcb.wReserved1=0; //没有使用 //dcb.BaudRate =9600; //波特率 //dcb.Parity=0; //奇偶校验 //dcb.ByteSize=8; //数据位 //dcb.StopBits=0; //停止位 //------------------------------ if(dcb.Parity==0 ) // 0-4=None,Odd,Even,Mark,Space { dcb.fParity=FALSE; //奇偶校验无效 } else { dcb.fParity=TRUE; //奇偶校验有效 } sprintf(szMsg,"COM%d:%d,%d,%d,%d (InSize:%ld,OutSize:%ld)", lngPort,dcb.BaudRate,dcb.Parity,dcb.ByteSize,dcb.StopBits,lngInSize,lngOutSize); //读写超时设置 COMMTIMEOUTS CommTimeOuts; //西门子参数 CommTimeOuts.ReadIntervalTimeout =0; //字符允许间隔ms 该参数如果为最大值,会使readfile命令立即返回 CommTimeOuts.ReadTotalTimeoutMultiplier =0; //总的超时时间(对单个字节) CommTimeOuts.ReadTotalTimeoutConstant = 2500; //多余的超时时间ms CommTimeOuts.WriteTotalTimeoutMultiplier =0; //总的超时时间(对单个字节) CommTimeOuts.WriteTotalTimeoutConstant = 2500; //多余的超时时间 SetCommTimeouts( m_COM_Handle, &CommTimeOuts ); //获取信号句柄 m_OverlappedRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); m_OverlappedWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if( !SetCommState( m_COM_Handle, &dcb ) || //判断设置参数是否成功 !SetupComm( m_COM_Handle, lngInSize, lngOutSize ) || //设置输入和输出缓冲区是否成功 m_OverlappedRead.hEvent==NULL || m_OverlappedWrite.hEvent==NULL) { DWORD dwError = GetLastError(); //获取最后的错误信息 if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent ); if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent ); CloseHandle( m_COM_Handle ); m_COM_Handle=NULL; return dwError; } return( 0 ); } catch(...) { return -1; } }
//*************************************************************************//函 数 名:CloseCom//输 入://输 出:long//功能描述:关闭串口//全局变量://调用模块://作 者:叶帆//日 期:2006年4月4日//修 改 人://日 期://版 本://*************************************************************************long CloseCom(){ try { if(m_COM_Handle == NULL ) return( 1 ); SetCommMask(m_COM_Handle ,NULL); SetEvent(m_OverlappedRead.hEvent); SetEvent(m_OverlappedWrite.hEvent);
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent ); if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent ); if (CloseHandle( m_COM_Handle )==FALSE)return (2);
m_COM_Handle = NULL; } catch(...) { return (3); } return( 0 );}
//*************************************************************************//函 数 名:SendData//输 入:BYTE *bytBuffer, 数据// long lngSize 个数//输 出:long//功能描述:发送数据//全局变量://调用模块://作 者:叶帆//日 期:2006年4月4日//修 改 人://日 期://版 本://*************************************************************************long SendData(BYTE *bytBuffer, long lngSize ){ try { if( m_COM_Handle == NULL ) return( -1 ); DWORD dwBytesWritten=lngSize; BOOL bWriteStat; COMSTAT ComStat; DWORD dwErrorFlags; ClearCommError(m_COM_Handle,&dwErrorFlags,&ComStat); bWriteStat=WriteFile(m_COM_Handle, bytBuffer, lngSize, &dwBytesWritten, &(m_OverlappedWrite));
if(!bWriteStat) { if(GetLastError()==ERROR_IO_PENDING) { GetOverlappedResult(m_COM_Handle,&(m_OverlappedWrite),&dwBytesWritten,TRUE); //等待直到发送完毕 } else { dwBytesWritten=0; } } return (long)dwBytesWritten; } catch(...) { return -1; }}
//*************************************************************************//函 数 名:AcceptData//输 入:BYTE *bytBuffer, 数据// long lngSize 个数//输 出:long//功能描述:读取数据//全局变量://调用模块://作 者:叶帆//日 期:2006年4月4日//修 改 人://日 期://版 本://*************************************************************************long AcceptData(BYTE *bytBuffer, long lngSize ){ try { if( m_COM_Handle == NULL ) return( -1 ); DWORD lngBytesRead=lngSize; BOOL fReadStat; DWORD dwRes=0;
//读数据 fReadStat=ReadFile(m_COM_Handle,bytBuffer,lngSize,&lngBytesRead,&(m_OverlappedRead)); //Sleep(1); if( !fReadStat ) { if( GetLastError() == ERROR_IO_PENDING ) //重叠 I/O 操作在进行中 { dwRes=WaitForSingleObject(m_OverlappedRead.hEvent,1000); //等待,直到超时 switch(dwRes) { case WAIT_OBJECT_0: //读完成 if(GetOverlappedResult(m_COM_Handle,&(m_OverlappedRead),&lngBytesRead,FALSE)==0) { //错误 return -2; } break; case WAIT_TIMEOUT: //超时 return -1; break; default: //WaitForSingleObject 错误 break; } } }
return lngBytesRead; } catch(...) { return -1; }}
//*************************************************************************//函 数 名:ClearAcceptBuffer//输 入://输 出:long//功能描述:清除接收缓冲区//全局变量://调用模块://作 者:叶帆//日 期:2006年4月4日//修 改 人://日 期://版 本://*************************************************************************long ClearAcceptBuffer(){ try { if(m_COM_Handle == NULL ) return( -1 ); PurgeComm(m_COM_Handle,PURGE_RXABORT | PURGE_RXCLEAR); // } catch(...) { return(1); } return(0);}
//*************************************************************************//函 数 名:ClearSendBuffer//输 入://输 出:long//功能描述:清除发送缓冲区//全局变量://调用模块://作 者:叶帆//日 期:2006年4月4日//修 改 人://日 期://版 本://*************************************************************************long ClearSendBuffer(){ try { if(m_COM_Handle == NULL ) return( -1 ); PurgeComm(m_COM_Handle,PURGE_TXABORT | PURGE_TXCLEAR); // } catch(...) { return (1); } return(0);}
