首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 网页设计 | 平面设计 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
中国IT实验室Dotnet频道
中国IT教育
Google
首页 ASP.NET  C#  XML/WebService ADO.NET VC.NET VB.NET .NET 资讯动态 专题 RSS订阅 讨论 下载
您现在的位置: 中国IT实验室 >> Dotnet >> VC.NET >> 正文

用VC 6.0实现串行通信的三种方法

  方法二:在单线程中实现自定义的串口通信类

  控件简单易用,但由于必须拿到对话框中使用,在一些需要在线程中实现通信的应用场合,控件的使用显得捉襟见肘。此时,若能够按不同需要定制灵活的串口通信类将弥补控件的不足,以下将介绍如何在单线程中建立自定义的通信类。

  该通信类CSimpleComm需手动加入头文件与源文件,其基类为CObject,大致建立步骤如下:

  (1) 打开串口,获取串口资源句柄

  通信程序从CreateFile处指定串口设备及相关的操作属性。再返回一个句柄,该句柄将被用于后续的通信操作,并贯穿整个通信过程。CreateFile()函数中有几个值得注意的参数设置:串口共享方式应设为0,串口为不可共享设备;创建方式必须为OPEN_EXISTING,即打开已有的串口。对于dwFlagAndAttribute参数,对串口有意义的值是FILE_FLAG_OVERLAPPED,该标志表明串口采用异步通信模式,可进行重叠操作;若值为NULL,则为同步通信方式,在同步方式下,应用程序将始终控制程序流,直到程序结束,若遭遇通信故障等因素,将导致应用程序的永久等待,所以一般多采用异步通信。

  (2)串口设置

  串口打开后,其属性被设置为默认值,根据具体需要,通过调用GetCommState(hComm,&dcb)读取当前串口设备控制块DCB(Device Control Block)设置,修改后通过SetCommState(hComm,&dcb)将其写入。再需注意异步读写的超时控制设置, 通过COMMTIMEOUTS结构设置超时,调用SetCommTimeouts(hComm,&timeouts)将结果写入。以下是温度监控程序中串口初始化成员函数:

BOOL CSimpleComm::Open( )
{
 DCB dcb;
 m_hIDComDev=CreateFile( "COM2", GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVE RLAPPED, NULL );
// 打开串口,异步操作

 if( m_hIDComDev == NULL )
 return( FALSE );
 dcb.DCBlength = sizeof( DCB );
 GetCommState( m_hIDComDev, &dcb ); // 获得端口默认设置
 dcb.BaudRate=CBR_4800;
 dcb.ByteSize=8;dcb.Parity= NOPARITY;
 dcb.StopBits=(BYTE) ONESTOPBIT;
 ......
 

   (3)串口读写操作

  主要运用ReadFile()与WriteFile()API函数,若为异步通信方式,两函数中最后一个参数为指向OVERLAPPED结构的非空指针,在读写函数返回值为FALSE的情况下,调用GetLastError()函数,返回值为ERROR_IO_PENDING,表明I/O操作悬挂,即操作转入后台继续执行。此时,可以用WaitForSingleObject()来等待结束信号并设置最长等待时间,举例如下:

BOOL bReadStatus;
bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );

if(!bReadStatus)
{
 if(GetLastError()==ERROR_IO_PENDING)
  {
  WaitForSingleObject(m_OverlappedRead.hEvent,1000);
  return ((int)dwBytesRead);
  }
 return(0);
}
return ((int)dwBytesRead);  

  定义全局变量m_Serial作为新建通信类CSimpleComm的对象,通过调用类的成员函数即可实现所需串行通信功能。与方法一相比,方法二赋予串行通信程序设计较大的灵活性,端口的读写可选择较简单的查询式,或通过设置与外设数据发送时间间隔TimeCycle相同的定时器:SetTimer(1,TimeCycle,NULL),进行定时读取或发送。

CSampleView:: OnTimer(UINT nIDEvent)
{
 char InputData[30];
 m_Serial.ReadData(InputData,30); // 数据处理
}  

  若对端口数据的响应时间要求较严格,可采用事件驱动I/O读写,Windows定义了9种串口通信事件,较常用的有:

  EV_RXCHAR: 接收到一个字节,并放入输入缓冲区。

  EV_TXEMPTY: 输出缓冲区中的最后一个字符发送出去。

  EV_RXFLAG: 接收到事件字符(DCB结构中EvtChar成员),放入输入缓冲区。

  在用SetCommMask()指定了有用的事件后,应用程序可调用WaitCommEvent()来等待事件的发生。SetCommMask(hComm,0)可使WaitCommEvent()中止。

 

上一页  [1] [2] [3] 下一页

【责编:Peng】

中国IT教育

相关产品和培训
文章评论
 友情推荐链接
 认证培训
 专题推荐

 ·WEB程序开发--ASP.NET和PHP、JSP究竟学哪个?
 ·五步带你入门XML
 ·关于Java框架技术专题
 ·XML全攻略技术专题
 ·JAVA开源技术介绍专题
 ·Java嵌入式开发之J2ME技术专题
 ·超前体验 Oracle 11g的5个新特性…
 ·揭密使用VB.NET的五个实用技巧
 ·Oracle和SQL Server常用函数对比专题…
 ·展现C#世界 C#程序设计专题…
 今日更新
 社区讨论
 博客论点
 频道精选
 Dotnet频道相关导航