登录
首页 嵌入式系统 嵌入式系统
回帖 发帖
正文

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

点击:2259 回复:1

MFC串口操作(异步方式)源码
这是在一个后台系统摘抄出来的,在此基础上完成了一个独立的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);
}
最后修改:2007-4-4 15:31:38
06-07-05 14:22
MFC,微软基础类(Microsoft Foundation Classes),实际上是微软提供的,用于在C++环境下编写应用程序的一个框架和引擎,VC++是WinOS下开发人员使用的专业C++ SDK(SDK,Standard SoftWare Develop Kit,专业软件开发平台),MFC就是挂在它之上的一个输助软件开发包,MFC作为与VC++血肉相连的部分(注意C++和VC++的区别:C++是一种程序设计语言,是一种大家都承认的软件编制的通用规范,而VC++只是一个编译器,或者说是一种编译器+源程序编辑器的IDE,WS,PlatForm,这跟Pascal和Dephi的关系一个道理,Pascal是Dephi的语言基础,Dephi使用Pascal规范来进行Win下应用程序的开发和编译,却不同于Basic语言和VB的关系,Basic语言在VB开发出来被应用的年代已经成了Basic语言的新规范,VB新加的Basic语言要素,如面对对象程序设计的要素,是一种性质上的飞跃,使VB既是一个IDE,又成长成一个新的程序设计语言),MFC同BC++集成的VCL一样是一个非外挂式的软件包,类库,只不过MFC类是微软为VC++专配的..

  MFC是Win API与C++的结合,API,即微软提供的WinOS下应用程序的编程语言接口,是一种软件编程的规范,但不是一种程序开发语言本身,可以允许用户使用各种各样的第三方(如我是一方,微软是一方,Borland就是第三方)的编程语言来进行对Win OS下应用程序的开发,使这些被开发出来的应用程序能在WinOS下运行,比如VB,VC++,Java,Dehpi编程语言函数本质上全部源于API,因此用它们开发出来的应用程序都能工作在WinOS的消息机制和绘图里,遵守WinOS作为一个操作系统的内部实现,这其实也是一种必要,微软如果不提供API,这个世上对Win编程的工作就不会存在,微软的产品就会迅速从时尚变成垃圾,上面说到MFC是微软对API函数的专用C++封装,这种结合一方面让用户使用微软的专业C++ SDK来进行Win下应用程序的开发变得容易,因为MFC是对API的封装,微软做了大量的工作,隐藏了好多内节程序开发人员在Win下用C++ & MFC编制软件时的大量内节,如应用程序实现消息的处理,设备环境绘图,这种结合是以方便为目的的,必定要付出一定代价(这是微软的一向作风),因此就造成了MFC对类封装中的一定程度的的冗余和迂回,但这是可以接受的..
 
  最后要明白MFC不只是一个功能单纯的界面开发系统,它提供的类绝大部分用来进行界面开发,关联一个窗口的动作,但它提供的类中有好多类不与一个窗口关联,即类的作用不是一个界面类,不实现对一个窗口对象的控制(如创建,销毁),而是一些在WinOS(用MFC编写的程序绝大部分都在WinOS中运行)中实现内部处理的类,如数据库的管理类等,学习中最应花费时间的是消息和设备环境,对C++和MFC的学习中最难的部分是指针,C++面向对像程序设计的其它部分,如数据类型,流程控制都不难,建议学习数据结构C++版..
07-04-04 15:34

工控新闻

更多新闻资讯