MFC串口操作(异步方式)源码

    技术2022-05-11  62

    这是我在一个后台系统摘抄出来的,在此基础上完成了一个独立的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);}

     

    最新回复(0)