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

来源:互联网 发布:女程序员 编辑:程序博客网 时间:2024/06/05 19:37

这是我在一个后台系统摘抄出来的,在此基础上完成了一个独立的PPI读写程序(非DLL或控件方式)

 

  1. //*************************************************************************
  2. //**模 块 名:YFCOM.cpp
  3. //**说 明:YFSoft 版权所有2005 - 2006(C)
  4. //**创 建 人:叶帆
  5. //**日 期:2006年4月4日
  6. //**修 改 人:
  7. //**日 期:
  8. //**描 述:串口操作
  9. //**版 本:V1.0
  10. //*************************************************************************
  11. #include "stdafx.h"
  12. #include "yfcom.h"

  13. //串口句柄
  14. HANDLE m_COM_Handle;
  15. //两个信号全局变量(串口操作用)
  16. OVERLAPPED m_OverlappedRead, m_OverlappedWrite;

  17. //*************************************************************************
  18. //函 数 名:OpenCom
  19. //输 入:long lngPort, 串口号
  20. // char *cfgMessage, 配置信息,形如"9600,e,8,1"
  21. // long lngInSize, 接收缓冲区大小
  22. // long lngOutSize 发送缓冲区大小
  23. //输 出:long
  24. //功能描述:打开串口
  25. //全局变量:
  26. //调用模块:
  27. //作 者:叶帆
  28. //日 期:2006年4月4日
  29. //修 改 人:
  30. //日 期:
  31. //版 本:
  32. //*************************************************************************
  33. long OpenCom(long lngPort,char *cfgMessage,long lngInSize,long lngOutSize)
  34. {
  35.  try
  36.  {
  37.      char szMsg[255];
  38.   DCB dcb;
  39.         
  40.   //打开端口
  41.   if (lngPort>9)
  42.            sprintf( szMsg, "////.//COM%d", lngPort );
  43.   else
  44.      sprintf( szMsg, "COM%d", lngPort );

  45.   //用异步方式读写串口
  46.   m_COM_Handle = CreateFile(szMsg, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED , NULL ); 
  47.   if( m_COM_Handle == NULL ) return( 2 );

  48.   //清空异步读写参数
  49.   memset(&(m_OverlappedRead), 0, sizeof (OVERLAPPED));
  50.         memset(&(m_OverlappedWrite), 0, sizeof (OVERLAPPED));
  51.       
  52.   //设置dcb块
  53.   dcb.DCBlength = sizeof( DCB ); //长度
  54.   GetCommState(m_COM_Handle , &dcb );
  55.         
  56.   //波特率,奇偶校验,数据位,停止位 如:9600,n,8,1
  57.         sprintf(szMsg,"COM%d:%s", lngPort,cfgMessage);
  58.   BuildCommDCB(szMsg,&dcb);
  59.      //------------------------------ 
  60.   dcb.fBinary=TRUE; //二进制方式 
  61.   dcb.fOutxCtsFlow=FALSE; //不用CTS检测发送流控制
  62.   dcb.fOutxDsrFlow=FALSE; //不用DSR检测发送流控制
  63.         dcb.fDtrControl=DTR_CONTROL_DISABLE; //禁止DTR流量控制
  64.   dcb.fDsrSensitivity=FALSE; //对DTR信号线不敏感
  65.   dcb.fTXContinueOnXoff=TRUE; //检测接收缓冲区
  66.   dcb.fOutX=FALSE; //不做发送字符控制
  67.   dcb.fInX =FALSE; //不做接收控制
  68.   dcb.fErrorChar=FALSE; //是否用指定字符替换校验错的字符
  69.   dcb.fNull=FALSE; //保留NULL字符
  70.      dcb.fRtsControl=RTS_CONTROL_ENABLE; //允许RTS流量控制
  71.   dcb.fAbortOnError=FALSE; //发送错误后,继续进行下面的读写操作
  72.   dcb.fDummy2=0; //保留
  73.   dcb.wReserved=0; //没有使用,必须为0
  74.   dcb.XonLim=0; //指定在XOFF字符发送之前接收到缓冲区中可允许的最小字节数
  75.   dcb.XoffLim=0; //指定在XOFF字符发送之前缓冲区中可允许的最小可用字节数
  76.      dcb.XonChar=0; //发送和接收的XON字符 
  77.         dcb.XoffChar=0; //发送和接收的XOFF字符
  78.   dcb.ErrorChar=0; //代替接收到奇偶校验错误的字符 
  79.   dcb.EofChar=0; //用来表示数据的结束
  80.   dcb.EvtChar=0; //事件字符,接收到此字符时,会产生一个事件
  81.   dcb.wReserved1=0; //没有使用
  82.      //dcb.BaudRate =9600; //波特率
  83.   //dcb.Parity=0; //奇偶校验 
  84.   //dcb.ByteSize=8; //数据位
  85.   //dcb.StopBits=0; //停止位
  86.         //------------------------------
  87.        
  88.   if(dcb.Parity==) // 0-4=None,Odd,Even,Mark,Space
  89.   {
  90.    dcb.fParity=FALSE; //奇偶校验无效
  91.   }
  92.   else
  93.   {
  94.    dcb.fParity=TRUE; //奇偶校验有效
  95.   }
  96.         
  97.         sprintf(szMsg,"COM%d:%d,%d,%d,%d (InSize:%ld,OutSize:%ld)", lngPort,dcb.BaudRate,dcb.Parity,dcb.ByteSize,dcb.StopBits,lngInSize,lngOutSize); 

  98.   //读写超时设置
  99.   COMMTIMEOUTS CommTimeOuts;
  100.   //西门子参数
  101.   CommTimeOuts.ReadIntervalTimeout =0; //字符允许间隔ms 该参数如果为最大值,会使readfile命令立即返回 
  102.   CommTimeOuts.ReadTotalTimeoutMultiplier =0; //总的超时时间(对单个字节) 
  103.   CommTimeOuts.ReadTotalTimeoutConstant = 2500; //多余的超时时间ms 
  104.   CommTimeOuts.WriteTotalTimeoutMultiplier =0; //总的超时时间(对单个字节) 
  105.   CommTimeOuts.WriteTotalTimeoutConstant = 2500; //多余的超时时间
  106.   
  107.   SetCommTimeouts( m_COM_Handle, &CommTimeOuts );
  108.       
  109.   //获取信号句柄
  110.   m_OverlappedRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  111.         m_OverlappedWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  112.        
  113.   if( !SetCommState( m_COM_Handle, &dcb ) || //判断设置参数是否成功
  114.    !SetupComm( m_COM_Handle, lngInSize, lngOutSize ) || //设置输入和输出缓冲区是否成功
  115.          m_OverlappedRead.hEvent==NULL ||
  116.        m_OverlappedWrite.hEvent==NULL)
  117.   
  118.   { 
  119.        DWORD dwError = GetLastError(); //获取最后的错误信息
  120.         if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
  121.           if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
  122.     CloseHandle( m_COM_Handle );
  123.             m_COM_Handle=NULL;
  124.     return dwError;
  125.   }
  126.       
  127.   return( 0 );
  128.     }
  129.  catch(...)
  130.  {
  131.   return -1;
  132.  }
  133.    
  134. }

  135. //*************************************************************************
  136. //函 数 名:CloseCom
  137. //输 入:
  138. //输 出:long
  139. //功能描述:关闭串口
  140. //全局变量:
  141. //调用模块:
  142. //作 者:叶帆
  143. //日 期:2006年4月4日
  144. //修 改 人:
  145. //日 期:
  146. //版 本:
  147. //*************************************************************************
  148. long CloseCom()
  149. {
  150.    try
  151.    {
  152.  if(m_COM_Handle == NULL ) return( 1 );
  153.  SetCommMask(m_COM_Handle ,NULL);
  154.     SetEvent(m_OverlappedRead.hEvent);
  155.  SetEvent(m_OverlappedWrite.hEvent);

  156.  if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
  157.  if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
  158.     if (CloseHandle( m_COM_Handle )==FALSE)return (2);

  159.  m_COM_Handle = NULL;
  160.    }
  161.    catch(...)
  162.    {
  163.     return (3);
  164.    }
  165.  return( 0 );
  166. }

  167. //*************************************************************************
  168. //函 数 名:SendData
  169. //输 入:BYTE *bytBuffer, 数据
  170. // long lngSize 个数
  171. //输 出:long
  172. //功能描述:发送数据
  173. //全局变量:
  174. //调用模块:
  175. //作 者:叶帆
  176. //日 期:2006年4月4日
  177. //修 改 人:
  178. //日 期:
  179. //版 本:
  180. //*************************************************************************
  181. long SendData(BYTE *bytBuffer, long lngSize )
  182. {
  183.  try
  184.  {
  185.      if( m_COM_Handle == NULL ) return( -);
  186.      
  187.   DWORD dwBytesWritten=lngSize;
  188.   BOOL bWriteStat;
  189.   COMSTAT ComStat;
  190.   DWORD dwErrorFlags;
  191.         
  192.   ClearCommError(m_COM_Handle,&dwErrorFlags,&ComStat);
  193.   bWriteStat=WriteFile(m_COM_Handle, bytBuffer, lngSize, &dwBytesWritten, &(m_OverlappedWrite));

  194.   if(!bWriteStat)
  195.   {
  196.      if(GetLastError()==ERROR_IO_PENDING)
  197.      {
  198.       GetOverlappedResult(m_COM_Handle,&(m_OverlappedWrite),&dwBytesWritten,TRUE); //等待直到发送完毕
  199.      }
  200.      else
  201.      {
  202.              dwBytesWritten=0;
  203.      }
  204.   }
  205.   return (long)dwBytesWritten;
  206.     }
  207.  catch(...)
  208.  {
  209.   return -1;
  210.  }
  211. }

  212. //*************************************************************************
  213. //函 数 名:AcceptData
  214. //输 入:BYTE *bytBuffer, 数据
  215. // long lngSize 个数
  216. //输 出:long
  217. //功能描述:读取数据
  218. //全局变量:
  219. //调用模块:
  220. //作 者:叶帆
  221. //日 期:2006年4月4日
  222. //修 改 人:
  223. //日 期:
  224. //版 本:
  225. //*************************************************************************
  226. long AcceptData(BYTE *bytBuffer, long lngSize )
  227. {
  228.   
  229.     try
  230.  { 
  231.      if( m_COM_Handle == NULL ) return( -);
  232.       
  233.   DWORD lngBytesRead=lngSize;
  234.   BOOL fReadStat;
  235.   DWORD dwRes=0;

  236.   //读数据
  237.   fReadStat=ReadFile(m_COM_Handle,bytBuffer,lngSize,&lngBytesRead,&(m_OverlappedRead)); 
  238.   //Sleep(1);
  239.   if( !fReadStat )
  240.   {
  241.    if( GetLastError() == ERROR_IO_PENDING ) //重叠 I/O 操作在进行中 
  242.    {
  243.     dwRes=WaitForSingleObject(m_OverlappedRead.hEvent,1000); //等待,直到超时
  244.     switch(dwRes)
  245.     {
  246.     case WAIT_OBJECT_0: //读完成 
  247.      
  248.      if(GetOverlappedResult(m_COM_Handle,&(m_OverlappedRead),&lngBytesRead,FALSE)==0)
  249.      {
  250.       //错误
  251.       return -2;
  252.      }
  253.     
  254.      break;
  255.     case WAIT_TIMEOUT: //超时
  256.      return -1;
  257.      break;
  258.     default: //WaitForSingleObject 错误
  259.      break;
  260.     }
  261.    }
  262.   }

  263.      return lngBytesRead; 

  264.  }
  265.  catch(...)
  266.  {
  267.   return -1;
  268.  }
  269. }

  270. //*************************************************************************
  271. //函 数 名:ClearAcceptBuffer
  272. //输 入:
  273. //输 出:long
  274. //功能描述:清除接收缓冲区
  275. //全局变量:
  276. //调用模块:
  277. //作 者:叶帆
  278. //日 期:2006年4月4日
  279. //修 改 人:
  280. //日 期:
  281. //版 本:
  282. //*************************************************************************
  283. long ClearAcceptBuffer()
  284. {
  285.    try
  286.    {
  287.        if(m_COM_Handle == NULL ) return( -);
  288.        PurgeComm(m_COM_Handle,PURGE_RXABORT | PURGE_RXCLEAR); //
  289.    }
  290.    catch(...)
  291.    {
  292.     return(1);
  293.    }
  294.  return(0);
  295. }

  296. //*************************************************************************
  297. //函 数 名:ClearSendBuffer
  298. //输 入:
  299. //输 出:long
  300. //功能描述:清除发送缓冲区
  301. //全局变量:
  302. //调用模块:
  303. //作 者:叶帆
  304. //日 期:2006年4月4日
  305. //修 改 人:
  306. //日 期:
  307. //版 本:
  308. //*************************************************************************
  309. long ClearSendBuffer()
  310. {
  311.  try
  312.  {
  313.        if(m_COM_Handle == NULL ) return( -);
  314.        PurgeComm(m_COM_Handle,PURGE_TXABORT | PURGE_TXCLEAR); //
  315.     }
  316.  catch(...)
  317.  {
  318.   return (1);
  319.  }
  320.  return(0);
  321. }
0 0