软件介绍

  一个由印度人编写的VC串口类(也是一种VC串口控件),他还配合这个类写了VC 串口通信方面的一些基础知识,如怎么用VC打开串口,如何对串口进行配置,读串口、写串口等。

  这个类有点特别,它没有使用事件驱动原理,它是以查询方式工作的。

简介:  

  对没有接触过串口通信的VC程序员来说显得非常困难,很久以前我在 codeguru.com 上搜索过串口通信相关信息得到了非常大的帮助,从那时起能编写一个简单易用的VC 串口类是我的梦想。

  经过七个月在串口通信编程方面实践经验后,我编写了一个基于API实现的简单串口类,在介绍此串口类之前先介绍一下VC 串口通信方面的基础知识。

串口通信基础:

  串口通信每个字节的传输以串行的方式进行,传输时低位先被发送,一个“包”由“开始位”+“数据位”+“奇偶校验位”(不是必需)+“停止位” 组成。

  奇偶校验位是可选的,它用来进行错误检测,您可以在软件里设置是否启用奇偶校验,而且还可以选择启用哪种校验方式,如“奇”校验(ODD)或“偶”校验(EVEN)。

  PC机通过串口发送和接收数据的流程如下:

  1、

打开串口

  2、 配置串口通信参数,如:波特率、校验方式、数据位数等
  3、 设置通信超时时间
  4、 写数据
  5、 读数据
  6、 关闭串口

用VC打开串口:

  打开串口可以用API函数 CreateFile() 来实现,打开串口有两种方式,分别为重叠I/O(OVERLAPPED)和非重叠(NON-OVERLAPPED)方式(其实这两种方式分别对应串口的异步和同步通信方式-VC串口通信技术网注)。CSerialCom 类工作于非重叠(NON-OVERLAPPED)模式(即同步通信模式),有关更多 OVERLAPPED 和 NON-OVERLAPPED 方面的消息可查询MSDN。

串口配置:

  VC 串口通信程序编写最重要的课题就是如何利用 DCB 结构来配置串口,对 DCB 结构填充不正确是大多数人常反犯的毛病,通常串口通信程序编写好后出现这样那样的问题就是因为这个结构没有正确填充所致。在利用 CreateFile() 函数打开串口时就需要我们对串口的波特率、校验方式、数据位、停止位等进行配置。

设置超时时间:

  每次打开串口时都必须利用 COMMTIMEOUTS 结构设置超时时间,如果未设置此结构,通信将以默认或上次打开此串口时设置的超时时间为准。

写串口:

  WriteFile() 函数可实现这一功能,在执行这一动作之前必须先打开并配置好串口。

读串口:

  利用 ReadFile() 可实现这一功能,同样,在执行这一动作之前必须先打开并配置好串口。

关闭串口:

  不再使用已经打开的串口后必须关闭它以将此串口资源释放出来,这样其它程序才可能再使用此串口资源,外于非重叠I/O(NON-OVERLAPPED)模式下的串口在打开期间是不能被其它程序或同一程序内的其它线程访问的。使用 CloseHandle() 函数可以关闭串口, CloseHandle() 函数只有一个参数,它是由 CreateFile() 打开串口时返回的设置句柄。

CSerialCom 串口类

  CSerialCom 类使用六个函数来实现上面提到的功能,它们分别是:

BOOL CSerialCom::OpenPort(CString portname)
{
portname= "//./" + portname;  hComm = CreateFile(portname,  GENERIC_READ | GENERIC_WRITE,  0,  0,  OPEN_EXISTING,  0,  0);
if(hComm==INVALID_HANDLE_VALUE){  return false;}  else return true;  }  

  OpenPort()成员函数用来打开串口,它需要的参数只有一个,就是串口名,如“COM1”,“COM2” 。

BOOL CSerialCom::ConfigurePort(DWORD BaudRate, BYTE ByteSize,   DWORD fParity, BYTE Parity, BYTE StopBits)
{  if((m_bPortReady = GetCommState(hComm, &m_dcb))==0)  {  MessageBox("GetCommState Error","Error",MB_OK+MB_ICONERROR);  CloseHandle(hComm);  return false;  }  m_dcb.BaudRate =BaudRate;  m_dcb.ByteSize = ByteSize;  m_dcb.Parity =Parity ;  m_dcb.StopBits =StopBits;  m_dcb.fBinary=TRUE;  m_dcb.fDsrSensitivity=false;  m_dcb.fParity=fParity;  m_dcb.fOutX=false;  m_dcb.fInX=false;  m_dcb.fNull=false;  m_dcb.fAbortOnError=TRUE;  m_dcb.fOutxCtsFlow=FALSE;  m_dcb.fOutxDsrFlow=false;  m_dcb.fDtrControl=DTR_CONTROL_DISABLE;  m_dcb.fDsrSensitivity=false;  m_dcb.fRtsControl=RTS_CONTROL_DISABLE;  m_dcb.fOutxCtsFlow=false;  m_dcb.fOutxCtsFlow=false;  m_bPortReady = SetCommState(hComm, &m_dcb);  if(m_bPortReady ==0)  {  MessageBox("SetCommState Error","Error",MB_OK+MB_ICONERROR);  CloseHandle(hComm);  return false;  }  return true;
}  

  ConfigurePort() 函数对串口地配置,它所需参数如下所示:

  DWORD BaudRate

  DWORD BaudRate 用来描述串口通信使用的波特率,如此参数为 CBR_9600 时,波特率为9600bps,PC机支持的标准波特率有:CBR_110 ,CBR_300 ,CBR_600 ,CBR_1200,CBR_2400,CBR_4800,CBR_9600,CBR_14400, CBR_19200,CBR_38400,CBR_56000,CBR_57600,CBR_115200,CBR_128000,CBR_256000

  BYTE ByteSize

  此参数描述数据位位数,标准值为8或4。

  DWORD fParity

  奇偶校验开关,如果此参数为真(TRUE)则开启奇偶校验,为假(FALSE)则关闭奇偶校验。

  BYTE Parity

  校验方式,可选方式如下:

 

EVENPARITY

  MARKPARITY
  NOPARITY
  ODDPARITY
  SPACEPARITY

  BYTE StopBits

  停止位位数,可取值如下:

 

ONESTOPBIT

  ONE5STOPBITS
  TWOSTOPBITS

备注:ConfigurePort() 函数是假定串口的流控制是由硬件来完成的,软件在收发数据过程中不检测CTS/RTS 和 Xon/Xoff 状态,您可以修改DCB结构来启用软件流控制。

BOOL CSerialCom::SetCommunicationTimeouts(DWORD ReadIntervalTimeout,   DWORD ReadTotalTimeoutMultiplier,   DWORD ReadTotalTimeoutConstant,   DWORD WriteTotalTimeoutMultiplier,   DWORD WriteTotalTimeoutConstant)
{  if((m_bPortReady = GetCommTimeouts (hComm, &m_CommTimeouts))==0)  return false;  m_CommTimeouts.ReadIntervalTimeout =ReadIntervalTimeout;  m_CommTimeouts.ReadTotalTimeoutConstant =ReadTotalTimeoutConstant;  m_CommTimeouts.ReadTotalTimeoutMultiplier =ReadTotalTimeoutMultiplier;  m_CommTimeouts.WriteTotalTimeoutConstant = WriteTotalTimeoutConstant;  m_CommTimeouts.WriteTotalTimeoutMultiplier =WriteTotalTimeoutMultiplier;  m_bPortReady = SetCommTimeouts (hComm, &m_CommTimeouts);  if(m_bPortReady ==0)  {  MessageBox("StCommTimeouts function failed",  "Com Port Error",MB_OK+MB_ICONERROR);  CloseHandle(hComm);  return false;  }  return true;
}

  SetCommunicationTimeouts() 成员函数用来设置读/写超时时间,它所需参数如下:

  DWORD ReadIntervalTimeout

  设置读串口时,收到两个字符的最大时间间隔,单位为毫秒。在执行ReadFile() 期间,一但收到两个字符的时间间隔超过这一设定值,ReadFile()立即返回。如果这一参数设置为零,则表明这一特性未启用。

  ReadTotalTimeoutConstant

  常量,用来计算读操作总超时时间。每个读操作过程中,这个参数被加到ReadTotalTimeoutMultiplier。如果ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant两个参数都为零则表明总超时计算功能没有启用。

  ReadTotalTimeoutMultiplier

  用来保存读操作总超时时间的

  WriteTotalTimeoutConstant

  常量,用来计算写操作总超时时间。与ReadTotalTimeoutConstant差不多。

  WriteTotalTimeoutMultiplier

  用来保存写操作总超时时间的,如果WriteTotalTimeoutMultiplier 和 WriteTotalTimeoutConstant两参数均为零,表明写操作总超时时间特性不被启用。

  例如,您需要传送一块数据包,设定了写操作超时时间为500ms(每个字符间发送时间最大间隔),您可以用设置超时成员函数来设定,内容为:SetCommunicationTimeouts(0,500,0,0,0);如果设置成功,函数返回真,否则返回假。

BOOL CSerialCom::WriteByte(BYTE bybyte)
{  iBytesWritten=0;  if(WriteFile(hComm,&bybyte,1,&iBytesWritten,NULL)==0)  return false;  else   return true;
} 

  WriteByte() 成员函数用来向串口写数据。

BOOL CSerialCom::ReadByte(BYTE &resp)
{  BYTE rx;  resp=0;  DWORD dwBytesTransferred=0;  if (ReadFile (hComm, &rx, 1, &dwBytesTransferred, 0))  {  if (dwBytesTransferred == 1)  {  resp=rx;  return true;  }  }  return false;
} 

View Code

ReadByte() 成员函数实现读串口功能,如果您知道有数据发送来了,可能使用 ReadByte() 来读取数据,如果不知道何时有数据发送过来,可以周期性调用此函数,当没收到数据超过超时时间后, ReadByte() 自动返回。在实际应用中,通信双方可能会以某种协议进行的,此时一般有表明通信数据包结束的标志,如3964协议的结束符是‘ETX’,您可能通过它来判断是否传输结束。

void CSerialCom::ClosePort()
{
CloseHandle(hComm);
return;
}  

  ClosePort() 成员函数用来关闭一个已经打开的串口。

如何使用CSerialCom类

  使用CSerialCom类前的准备工作:

  1、

复制SerialCom.h 和 SerialCom.cpp两个文件到工程所在目录

  2、 在VC工程中导入这两个文件
  3、 加入#include "SerialCom.h"句代码到程序适当位置
  4、 创建CSerialCom类的一个实例

  现在就可以调用CSerialCom类成员函数来进行串口通信了,操作流程如下:

    1.  1 // 打开串口。 需要检查函数返回值来判断串口是否正确打开
       2 port.OpenPort( );
       3
       4 // 配置串口。需要检查函数返回值来判断否正确配置
       5 port.ConfigurePort( );
       6
       7 // 设置超时时间。需要检查函数返回值来判断否正确配置
       8 port.SetCommunicationTimeouts( );
       9
      10 // 写串口,由于一次只能写一个字节,一般需要多次调用此函数才能将需要发送的字符串发送完
      11 port.WriteByte();
      12
      13 // 读串口,由于一次只能读一个字节,一般需要多次调用此函数才能将需要读取的字符串读完
      14 port.ReadByte( );
      15
      16 // 关闭串口
      17 port.ClosePort();

      下载地址: http://pan.baidu.com/s/1mgzH428

  1. (一个由印度人编写的VC++串口类_serialport+CSerialCom_demo)

  2. 参考:    http://cs.nju.edu.cn/yangxc/dcc2003.files/jszc-sub/comif-35.htm
  3. http://www.codeguru.com/cpp/i-n/network/serialcommunications/article.php/c2483/A-communication-class-for-serial-port.htm
  4. http://www.vc-rs232.com/html/VC_SSCOM_Control/2011/0117/34.html

转载于:https://www.cnblogs.com/lwngreat/p/4098374.html

一个由印度人编写的VC串口类相关推荐

  1. 一个印度人写的VC串口类CSerialCom(有串口基础介绍)

    http://www.vc-rs232.com/html/VC_SSCOM_Control/2011/0117/34.html 一个印度人写的VC串口类CSerialCom(有串口基础介绍) 软件介绍 ...

  2. 深入浅出VC++串口编程--第三方类

    串口类 从本系列文章连载三.四可以看出,与通过WIN32 API进行串口访问相比,通过MScomm这个Activex控件进行串口访问要来的方便许多,它基本上可以向用户屏蔽多线程的细节,以事件(发出On ...

  3. IT 外包中的甲方乙方,德国人,美国人,印度人和日本人印象杂谈

    开篇介绍 最近经常和朋友聚会,三十而立的年龄自然讨论最多的就是各自的小家庭,如何赚钱,工作,未来的就业发展,职业转型等话题.还有各种跳槽,机会选择,甲方乙方以及外包中的各种趣事,外企与国内私企的发展机 ...

  4. 如何通过名字判断一个印度人的种姓

    在以前通过名字判断一个印度人的种姓是很难的.一般高种姓的人肤色都较浅,而低种姓的人肤色都相对较深.还有就是根据名字的含义,出生地.文化程度,是否精通梵文等宗教知识来判断. 因为很多种姓都是来自于职业, ...

  5. 继富士康之后,又一个8万人大厂转移印度,但仍在中国留有后路

    日前消息指和硕旗下的昌硕工厂正在搬迁,预计将全数搬迁至印度,这是苹果代工厂之中又一家跟随苹果的脚步转移至印度,那么印度制造真的靠谱么? 苹果推动代工厂向印度转移似乎已是坚定不移,它最先推动纬创远赴印度 ...

  6. VC++串口组件MSCOMM的使用

    文章来源:http://www.chinaitpower.com/A/2001-10-07/983.html 在众多网友的支持下,串口调试助手从2001年5月21日发布至今,短短一个月,在全国各地累计 ...

  7. [世界概览]那些被印度人毁掉或者差一点毁掉的公司(翻译)

    印度人办事拖沓和效率低下是出了名,看了下面这篇文章理解了.. 这是一个在美国的网站上经常看到的评论,被广泛转载,我也不知道哪个是原创,所以就不列出处了. []内的不是原文,是我的补充. ======= ...

  8. Web3 迟早也是印度人的?

    撰文:0xmin 最近,印度人成为了全球舞台上的明星. 继印度人占领硅谷之后,最近,他们又接管了英国.42 岁的苏纳克成为了英国首位印度裔首相,印裔精英不断出圈.当年英国人殖民印度人,现在印度人领导英 ...

  9. VC串口通信编程-2

    VC串口通信编程 (2009-07-08 13:48:40) 转载▼ Win32串口编程(转:韩耀旭) 在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信.串口通信 ...

最新文章

  1. 《Oracle系列》:oracle job详解
  2. linux insmod命令参数及用法详解--linux加载模块命令
  3. laravel判断HTTP请求是否ajax
  4. HDU 6143 Killer Names(排列+容斥,dp)
  5. boost::math::tools::sum_series用法的测试程序
  6. 利用js的闭包原理做对象封装及调用方法
  7. 《图解 HTTP》读书笔记(未完待续)
  8. cordic ip核 vivado_Xilinx Vivado CORDIC IP求解atan 反正切
  9. oracle的服務監聽器,Oracle监听器和服务名的配置
  10. ElementUI中使用地图实现地图位置选择_---SpringCloud Alibaba_若依微服务框架改造_ElementUI---工作笔记014
  11. 人口会一直增长下去吗_一直善良下去,你就会幸福
  12. Microsoft Dynamics CRM server 2013 中业务规则,有点像C#的正则表达式
  13. PhotoshopCS2相关教程网址
  14. 基于canny的边缘检测算法:
  15. CCS安装多版本编译器 Compiler version__更新手动下载、安装方法
  16. SAP系统登录以及注册开发人员
  17. 偏光太阳镜测试图片软件,[专题]真假偏光太阳镜简单、实用辨别方法!
  18. vue如何集成阿里云视频服务组件(aliplayer)视频功能是使用el-dialog 弹出aliplayer播放
  19. 添加打印机,错误为0x0000011b
  20. centos 安装 时间校准与定时同步

热门文章

  1. 鸿蒙智慧屏安卓内核,一切都是假象?荣耀智慧屏翻车,鸿蒙只是安卓的皮肤?...
  2. js获取html中img src属性值,javascript - js匹配img标签中的 src属性的值的正则怎么写?...
  3. java代码_Java:java五行代码实现Excel的快速导出
  4. ZStack源码剖析之核心库鉴赏——FlowChain
  5. ssl_error_rx_record_too_long
  6. 外文翻译 《How we decide》赛场上的四分卫 第三节
  7. iPhone 6 Screens Demystified
  8. 深入理解Redis主键失效原理及实现机制
  9. 三分频的Verilog实现
  10. 打开浏览器提示下载解决方法