您的位置:首页 > 其它

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

2016-06-23 13:44 519 查看
这是我在一个后台系统摘抄出来的,在此基础上完成了一个独立的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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: