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

简介:

这是我在一个后台系统摘抄出来的,在此基础上完成了一个独立的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. //串口句柄  
  15. HANDLE m_COM_Handle;  
  16. //两个信号全局变量(串口操作用)  
  17. OVERLAPPED m_OverlappedRead, m_OverlappedWrite;  
  18.  
  19. //*************************************************************************  
  20. //函 数 名:OpenCom  
  21. //输    入:long lngPort,        串口号  
  22. //   char *cfgMessage,    配置信息,形如"9600,e,8,1"  
  23. //   long lngInSize,      接收缓冲区大小  
  24. //   long lngOutSize      发送缓冲区大小  
  25. //输    出:long  
  26. //功能描述:打开串口  
  27. //全局变量:  
  28. //调用模块:  
  29. //作    者:叶帆  
  30. //日    期:2006年4月4日  
  31. //修 改 人:  
  32. //日    期:  
  33. //版    本:  
  34. //*************************************************************************  
  35. long OpenCom(long lngPort,char *cfgMessage,long lngInSize,long lngOutSize)  
  36. {  
  37.  try 
  38.  {  
  39.      char szMsg[255];  
  40.   DCB dcb;  
  41.           
  42.   //打开端口  
  43.   if (lngPort>9)  
  44.            sprintf( szMsg, "\\\\.\\COM%d", lngPort );  
  45.   else 
  46.      sprintf( szMsg, "COM%d", lngPort );  
  47.  
  48.   //用异步方式读写串口  
  49.   m_COM_Handle  = CreateFile(szMsg, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED , NULL );     
  50.   if( m_COM_Handle == NULL ) return( 2 );  
  51.  
  52.   //清空异步读写参数  
  53.   memset(&(m_OverlappedRead), 0, sizeof (OVERLAPPED));  
  54.         memset(&(m_OverlappedWrite), 0, sizeof (OVERLAPPED));  
  55.         
  56.   //设置dcb块  
  57.   dcb.DCBlength = sizeof( DCB );         //长度  
  58.   GetCommState(m_COM_Handle , &dcb );  
  59.           
  60.   //波特率,奇偶校验,数据位,停止位  如:9600,n,8,1  
  61.         sprintf(szMsg,"COM%d:%s", lngPort,cfgMessage);  
  62.   BuildCommDCB(szMsg,&dcb);  
  63.      //------------------------------   
  64.   dcb.fBinary=TRUE;                      //二进制方式    
  65.   dcb.fOutxCtsFlow=FALSE;                //不用CTS检测发送流控制  
  66.   dcb.fOutxDsrFlow=FALSE;                //不用DSR检测发送流控制  
  67.         dcb.fDtrControl=DTR_CONTROL_DISABLE;   //禁止DTR流量控制  
  68.   dcb.fDsrSensitivity=FALSE;             //对DTR信号线不敏感  
  69.   dcb.fTXContinueOnXoff=TRUE;            //检测接收缓冲区  
  70.   dcb.fOutX=FALSE;                       //不做发送字符控制  
  71.   dcb.fInX =FALSE;                       //不做接收控制  
  72.   dcb.fErrorChar=FALSE;                  //是否用指定字符替换校验错的字符  
  73.   dcb.fNull=FALSE;                       //保留NULL字符  
  74.      dcb.fRtsControl=RTS_CONTROL_ENABLE;    //允许RTS流量控制  
  75.   dcb.fAbortOnError=FALSE;               //发送错误后,继续进行下面的读写操作  
  76.   dcb.fDummy2=0;                         //保留  
  77.   dcb.wReserved=0;                       //没有使用,必须为0  
  78.   dcb.XonLim=0;                          //指定在XOFF字符发送之前接收到缓冲区中可允许的最小字节数  
  79.   dcb.XoffLim=0;                         //指定在XOFF字符发送之前缓冲区中可允许的最小可用字节数  
  80.      dcb.XonChar=0;                         //发送和接收的XON字符   
  81.         dcb.XoffChar=0;                        //发送和接收的XOFF字符  
  82.   dcb.ErrorChar=0;                       //代替接收到奇偶校验错误的字符   
  83.   dcb.EofChar=0;                         //用来表示数据的结束  
  84.   dcb.EvtChar=0;                         //事件字符,接收到此字符时,会产生一个事件  
  85.   dcb.wReserved1=0;                      //没有使用  
  86.      //dcb.BaudRate =9600;                  //波特率  
  87.   //dcb.Parity=0;                        //奇偶校验   
  88.   //dcb.ByteSize=8;                      //数据位  
  89.   //dcb.StopBits=0;                      //停止位  
  90.         //------------------------------  
  91.          
  92.   if(dcb.Parity==0 )        // 0-4=None,Odd,Even,Mark,Space  
  93.   {  
  94.    dcb.fParity=FALSE;    //奇偶校验无效  
  95.   }  
  96.   else 
  97.   {  
  98.    dcb.fParity=TRUE;     //奇偶校验有效  
  99.   }  
  100.           
  101.         sprintf(szMsg,"COM%d:%d,%d,%d,%d (InSize:%ld,OutSize:%ld)", lngPort,dcb.BaudRate,dcb.Parity,dcb.ByteSize,dcb.StopBits,lngInSize,lngOutSize);   
  102.    
  103.   //读写超时设置  
  104.   COMMTIMEOUTS CommTimeOuts;  
  105.   //西门子参数  
  106.   CommTimeOuts.ReadIntervalTimeout =0;                                   //字符允许间隔ms   该参数如果为最大值,会使readfile命令立即返回     
  107.   CommTimeOuts.ReadTotalTimeoutMultiplier =0;                             //总的超时时间(对单个字节)    
  108.   CommTimeOuts.ReadTotalTimeoutConstant = 2500;                           //多余的超时时间ms   
  109.   CommTimeOuts.WriteTotalTimeoutMultiplier =0;                            //总的超时时间(对单个字节)   
  110.   CommTimeOuts.WriteTotalTimeoutConstant = 2500;                          //多余的超时时间  
  111.     
  112.   SetCommTimeouts( m_COM_Handle, &CommTimeOuts );  
  113.         
  114.   //获取信号句柄  
  115.   m_OverlappedRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);  
  116.         m_OverlappedWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);  
  117.          
  118.   if( !SetCommState( m_COM_Handle, &dcb ) ||                   //判断设置参数是否成功  
  119.    !SetupComm( m_COM_Handle, lngInSize, lngOutSize ) ||     //设置输入和输出缓冲区是否成功  
  120.          m_OverlappedRead.hEvent==NULL ||  
  121.        m_OverlappedWrite.hEvent==NULL)  
  122.     
  123.   {    
  124.        DWORD dwError = GetLastError();                     //获取最后的错误信息  
  125.         if( m_OverlappedRead.hEvent != NULL )  CloseHandle( m_OverlappedRead.hEvent );  
  126.           if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );  
  127.     CloseHandle( m_COM_Handle );  
  128.             m_COM_Handle=NULL;  
  129.     return dwError;  
  130.   }  
  131.         
  132.   return( 0 );  
  133.     }  
  134.  catch(...)  
  135.  {  
  136.   return -1;  
  137.  }  
  138.      
  139. }  
  140.  
  141. //*************************************************************************  
  142. //函 数 名:CloseCom  
  143. //输    入:  
  144. //输    出:long  
  145. //功能描述:关闭串口  
  146. //全局变量:  
  147. //调用模块:  
  148. //作    者:叶帆  
  149. //日    期:2006年4月4日  
  150. //修 改 人:  
  151. //日    期:  
  152. //版    本:  
  153. //*************************************************************************  
  154. long CloseCom()  
  155. {  
  156.    try 
  157.    {  
  158.  if(m_COM_Handle  == NULL ) return( 1 );  
  159.  SetCommMask(m_COM_Handle ,NULL);  
  160.     SetEvent(m_OverlappedRead.hEvent);  
  161.  SetEvent(m_OverlappedWrite.hEvent);  
  162.  
  163.  if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );  
  164.  if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );  
  165.     if (CloseHandle( m_COM_Handle )==FALSE)return (2);  
  166.  
  167.  m_COM_Handle  = NULL;  
  168.    }  
  169.    catch(...)  
  170.    {  
  171.     return (3);  
  172.    }  
  173.  return( 0 );  
  174. }  
  175.  
  176. //*************************************************************************  
  177. //函 数 名:SendData  
  178. //输    入:BYTE *bytBuffer,   数据  
  179. //      long lngSize       个数  
  180. //输    出:long  
  181. //功能描述:发送数据  
  182. //全局变量:  
  183. //调用模块:  
  184. //作    者:叶帆  
  185. //日    期:2006年4月4日  
  186. //修 改 人:  
  187. //日    期:  
  188. //版    本:  
  189. //*************************************************************************  
  190. long SendData(BYTE *bytBuffer, long lngSize )  
  191. {  
  192.  try 
  193.  {  
  194.      if( m_COM_Handle  == NULL ) return( -1 );  
  195.        
  196.   DWORD dwBytesWritten=lngSize;  
  197.   BOOL bWriteStat;  
  198.   COMSTAT ComStat;  
  199.   DWORD   dwErrorFlags;  
  200.           
  201.   ClearCommError(m_COM_Handle,&dwErrorFlags,&ComStat);  
  202.   bWriteStat=WriteFile(m_COM_Handle, bytBuffer, lngSize, &dwBytesWritten, &(m_OverlappedWrite));  
  203.  
  204.   if(!bWriteStat)  
  205.   {  
  206.      if(GetLastError()==ERROR_IO_PENDING)  
  207.      {  
  208.       GetOverlappedResult(m_COM_Handle,&(m_OverlappedWrite),&dwBytesWritten,TRUE); //等待直到发送完毕  
  209.      }  
  210.      else 
  211.      {  
  212.              dwBytesWritten=0;  
  213.      }  
  214.   }  
  215.   return (long)dwBytesWritten;  
  216.     }  
  217.  catch(...)  
  218.  {  
  219.   return -1;  
  220.  }  
  221. }  
  222.  
  223. //*************************************************************************  
  224. //函 数 名:AcceptData  
  225. //输    入:BYTE *bytBuffer,   数据  
  226. //      long lngSize       个数  
  227. //输    出:long  
  228. //功能描述:读取数据  
  229. //全局变量:  
  230. //调用模块:  
  231. //作    者:叶帆  
  232. //日    期:2006年4月4日  
  233. //修 改 人:  
  234. //日    期:  
  235. //版    本:  
  236. //*************************************************************************  
  237. long AcceptData(BYTE *bytBuffer, long lngSize )  
  238. {  
  239.     
  240.     try 
  241.  {   
  242.      if( m_COM_Handle == NULL ) return( -1 );  
  243.         
  244.   DWORD   lngBytesRead=lngSize;  
  245.   BOOL    fReadStat;  
  246.   DWORD   dwRes=0;  
  247.  
  248.   //读数据  
  249.   fReadStat=ReadFile(m_COM_Handle,bytBuffer,lngSize,&lngBytesRead,&(m_OverlappedRead));    
  250.   //Sleep(1);  
  251.   if( !fReadStat )  
  252.   {  
  253.    if( GetLastError() == ERROR_IO_PENDING )                                   //重叠 I/O 操作在进行中   
  254.    {  
  255.     dwRes=WaitForSingleObject(m_OverlappedRead.hEvent,1000);   //等待,直到超时  
  256.     switch(dwRes)  
  257.     {  
  258.     case WAIT_OBJECT_0:   //读完成     
  259.        
  260.      if(GetOverlappedResult(m_COM_Handle,&(m_OverlappedRead),&lngBytesRead,FALSE)==0)  
  261.      {  
  262.       //错误  
  263.       return -2;  
  264.      }  
  265.       
  266.      break;  
  267.     case WAIT_TIMEOUT:    //超时  
  268.      return -1;  
  269.      break;  
  270.     default:              //WaitForSingleObject 错误  
  271.      break;  
  272.     }  
  273.    }  
  274.   }  
  275.  
  276.      return lngBytesRead;                
  277.    
  278.  }  
  279.  catch(...)  
  280.  {  
  281.   return -1;  
  282.  }  
  283. }  
  284.  
  285. //*************************************************************************  
  286. //函 数 名:ClearAcceptBuffer  
  287. //输    入:  
  288. //输    出:long  
  289. //功能描述:清除接收缓冲区  
  290. //全局变量:  
  291. //调用模块:  
  292. //作    者:叶帆  
  293. //日    期:2006年4月4日  
  294. //修 改 人:  
  295. //日    期:  
  296. //版    本:  
  297. //*************************************************************************  
  298. long ClearAcceptBuffer()  
  299. {  
  300.    try 
  301.    {  
  302.        if(m_COM_Handle  == NULL ) return( -1 );  
  303.        PurgeComm(m_COM_Handle,PURGE_RXABORT | PURGE_RXCLEAR);   //  
  304.    }  
  305.    catch(...)  
  306.    {  
  307.     return(1);  
  308.    }  
  309.  return(0);  
  310. }  
  311.  
  312. //*************************************************************************  
  313. //函 数 名:ClearSendBuffer  
  314. //输    入:  
  315. //输    出:long  
  316. //功能描述:清除发送缓冲区  
  317. //全局变量:  
  318. //调用模块:  
  319. //作    者:叶帆  
  320. //日    期:2006年4月4日  
  321. //修 改 人:  
  322. //日    期:  
  323. //版    本:  
  324. //*************************************************************************  
  325. long ClearSendBuffer()  
  326. {  
  327.  try 
  328.  {  
  329.        if(m_COM_Handle  == NULL ) return( -1 );  
  330.        PurgeComm(m_COM_Handle,PURGE_TXABORT |  PURGE_TXCLEAR);  //  
  331.     }  
  332.  catch(...)  
  333.  {  
  334.   return (1);  
  335.  }  
  336.  return(0);  
  337. }  
  338.  

 


















本文转自yefanqiu51CTO博客,原文链接:http://blog.51cto.com/yfsoft/323491,如需转载请自行联系原作者

相关文章
|
3月前
|
传感器 Linux API
如何实现 MCU软件中多个模块初始化函数的优雅调用
如何实现 MCU软件中多个模块初始化函数的优雅调用
|
5月前
《QT从基础到进阶·二》信号发送后槽函数执行多次
《QT从基础到进阶·二》信号发送后槽函数执行多次
31 0
|
10月前
|
存储 程序员 编译器
windows下的串口编程,串口操作类封装
windows下的串口编程,串口操作类封装
|
11月前
|
芯片
查询方式的按键驱动程序
查询方式的按键驱动程序
100 0
|
存储 文件存储
【课堂笔记】VB 自定义过程sub,消息窗体的输入输出,断点调试方法
【课堂笔记】VB 自定义过程sub,消息窗体的输入输出,断点调试方法
378 0
|
C语言
【C 语言】文件操作 ( 配置文件读写 | 框架搭建 | 主函数逻辑结构 | 启动无限循环 | 接收用户操作值 | 宏定义 | 显示操作菜单 )
【C 语言】文件操作 ( 配置文件读写 | 框架搭建 | 主函数逻辑结构 | 启动无限循环 | 接收用户操作值 | 宏定义 | 显示操作菜单 )
120 0
win10 uwp 异步转同步
原文:win10 uwp 异步转同步 有很多方法都是异步,那么如何从异步转到同步? 可以使用的方法需要获得是否有返回值,返回值是否需要。
845 0