基于VC++开发串口通信的方法 点击:6398 | 回复:8



飞哥0

    
  • 精华:4帖
  • 求助:0帖
  • 帖子:33帖 | 215回
  • 年度积分:0
  • 历史总积分:365
  • 注册:2003年8月04日
发表于:2005-09-30 09:38:00
楼主
串行通信中的关键是串行通信设备的初始化、数据的发送和接收及其实现方式。   在Dos环境下,用户可以直接对通信设备编程,可以通过查询中断的方式使用通信设备。但是Windows不提倡应用程序直接控制硬件,而是通过Windows所提供的设备驱动程序来进行数据传递。在Windows环境中,通信支持中断功能,当通信设备接收到一个输入字符的时候就产生一个硬件中断,该中断暂停应用程序的执行,并把接收到的字符存入到一个叫接收数据队列的内存缓冲区中。而待发数据也先存入到一个叫发送数据队列的内存缓冲区中,再由Windows系统负责在后台进行发送。因此,在Windows下接收和发送数据的关键就是如何从接收队列取数据和如何向发送数据队列发数据。Windows提供了相应的API函数来实现这些功能。   串行口在Win 32中是作为文件来进行处理的,而不是直接对端口进行操作。在Win32环境下,可以把串口看作由文件系统访问的设备。使用标准的CreateFile()函数打开端口,再使用ReadFile()和WriteFile()函数读写数据,就如同端口只是一个文件对象一样。对于串行通信,Win 32提供了相应的文件I/O函数与通信函数,使用这些函数,可以编制出符合不同需要的通信程序。   通常实现串行通信的步骤如下:   1 ) 按协议的设置初始化并打开串行口,这样做就是通知Windows本应用程序需要这个串口,并封锁其他应用程序使它们不能使用此串口。   2) 配置这个串行口。   3) 在串口上往返地传输数据,并在传输过程中进行校验。   4) 不需要此串口时,关闭串口,即释放串口以供其它应用程序使用。   在这四个步骤中,主要的程序代码集中在第3步。   本文就Win32环境下基于VC++开发串口通信三种方式的编程问题展开讨论。   1采用MFC串口通信编程   Win32系统把文件的概念进行了扩展,无论是文件、通信设备、命名管道、邮件槽、磁盘还是控制台都被看作是文件。因此,可以用MFC中的CFile类来实现对串口的操作,并且Win32中的文件I/O函数支持重叠式输入输出,这使得线程从费时的I/O操作中解放出来。Win32 API包含了一系列访问通信资源的通信函数。   通常采用MFC的串口通信编程主要步骤如下:   1)在MainFrmcpp中定义全局变量   HANDLE hCom;//准备打开的串口的句柄   2)打开串口   Windows通信会话以调用CreateFile()函数打开串行口开始。通信程序从CreateFile处指定串口设备及相关的操作属性,并返回一个句柄,该句柄将被用于后续的通信操作。   3)串口初始化(设置串口参数及进行串口超时设置)   在打开通信设备句柄后,通常要对串口进行初始化工作(即配置参数如波特率、数据位数、停止位数、奇偶校验以及握手和流控协议等),配置串口通过改变数据结构——设备控制块DCB(Device Control Block)来实现。结构DCB有近30个数据成员,对于采用3线方式的串行通信来说,只要设置好波特率、数据位、停止位、校验位等几个关键参数就可以。   调用GetCommState函数可以获得串口的配置,该函数把当前配置填充到一个DCB结构中。要修改串口配置,应该先修改串口的DCB结构,然后调用SetCommState函数用指定的DCB结构来设置串口。   除了在结构DCB中的设置外,程序一般还需要设置I/O缓冲区的大小和超时。超时设置是为了避免当通信过程中由于数据传输突然中断时而造成对串口的读写操作进入无限期的等待状态。超时设置过程分为两步,首先设置超时结构COMMTIMEOUTS中的五个成员,然后调用SetCommTimeouts()函数设置超时值。   这里介绍一种简捷的方法可以做到不了解DCB的详细内容也可以设置好串行通信参数:即利用BuildCommDCB函数来设置DCB,然后用函数SetCommState()配置串行通信口。   DCB dcb;//定义数据控制块结构   GetCommState(hCom,&dcb);//读串口原来的参数设置   BuildCommDCB(“COM2:9600,N,8,1”,& dcb);//创建数据控制块DCB结构   SetCommState(hCom,&dcb);//将结构DCB的主要参数设置到串口COM2   其中的BuildCommDCB(“COM2:9600,N,8,1”,&dcb)语句可以代替前面4条串口通信参数赋值语句的效果。   4)读写串口API函数   串行口打开后,可以对它进行读写操作。   5)关闭串口API函数   串行口是非共享资源,所以打开串口后,一定要关闭串口。关闭串口函数的原型:BOOL CloseHandle(HANDLE hObject);其中hObject参数为CreateFile()返回的端口句柄。返回值非0,则调用成功。   2采用ActiveX控件 (MScomm控件)编程   虽然在Windows下Win32API提供了使用CreateFile/WriteFile等文件I/O函数进行串行口操作的方法,但是在编程实现上比较复杂。Windows平台先进的ActiveX技术使得对串行口编程时不再需要处理烦琐的细节。利用已有的ActiveX控件,只需要编写少量的代码,就可以轻松高效地完成任务。   Microsoft Communications Control(以下简称MSComm)是Microsoft公司提供的简化Windows下串行通信编程的ActiveX控件,它为应用程序提供了通过串行接口收发数据的简便方法。具体地说,它提供了两种处理通信问题的方法:一是事件驱动(Event-driven)方法:主要是在comEvReceive(接收到数据)事件发生时响应并获取缓冲区的数据。一是查询法:在这种情况下,每当应用程序执行完某一串行口操作后,将不断检查MSComm控件的CommEvent属性以检查执行结果或者检查某一事件是否发生(Microsoft提供的用于串口操作的控件Mscomm共有27个属性)。   以下介绍在VC集成开发环境下对该控件编程的步骤。   (1)在当前的Workspace中插入MSComm控件   在VC环境下,创建基于对话框的MFC应用程序,在设置项目选项时必须选上ActiveX Controls,其他的按照缺省设置。然后进行以下步骤:Project菜单→Add to Project→Components and Controls→Registered ActiveX Controls→选择Components: Microsoft Communications Control,version 6.0插入到当前的Workspace中。   结果添加了类CMSComm(另有相应文件:mscomm.h和mscommcpp)。   (2)在MainFrm.h中加入MSComm控件   protected:   CMSComm m_ComPort;   在Mainfrm.cpp::OnCreate()中加入:   DWORD style=WS_VISIBLE|WS_CHILD;   if(!m_ComPort.Create(NULL,style,CRect(0,0,0,0),this,ID_COMMCTRL)){   TRACE0(“Failed to create OLE Communications Control\n”);   return-1;//创建失败}   (3)初始化串口   以下是通过设置控件属性对串口进行初始化的实例:   m_ComPort.SetCommPort(1);//指定串口号   m_ComPort.SetInBufferSize(1024);//设置输入缓冲区的   大小,Bytes   m_ComPort.SetOutBufferSize(512);//设置输出缓冲区的   Bytes,   if(!m_ComPort.GetPortOpen());//打开串口   m_ComPort.SetPortOpen(TRUE);//打开通信口   m_ComPort.SetInputMode(1);//设置输入方式为二进制   方式   m_ComPort.SetSettings(“9600,n,8,1”);//设置波特率等   参数   m_ComPort.SetRThreshold(1);//为1表示有一个字符引   发一个事件   m_ComPort.SetInputLen(0);   (4)捕捉串口事件   MSComm控件可以采用轮询或事件驱动的两种方法从端口获取数据。比较常用的是事件驱动方法:有事件(如接收到数据)时通知程序。在程序中需要捕获并处理这些通讯事件。   (5)串口读写   完成读写的两个函数的原型是VARIANT GetInput();及void SetOutput(const VARIANT& newValue);都要使用VARIANT类型。首先由函数



周公

  • 精华:10帖
  • 求助:0帖
  • 帖子:119帖 | 5549回
  • 年度积分:0
  • 历史总积分:6446
  • 注册:2002年11月26日
发表于:2005-09-30 09:53:00
1楼
虽然不是本版‘传感器与仪表’方向,文章不错,加精华

CHEN_CHN

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 5回
  • 年度积分:0
  • 历史总积分:5
  • 注册:2005年7月21日
发表于:2005-10-10 16:29:00
2楼
ARE THE GOOD

digi

  • 精华:19帖
  • 求助:0帖
  • 帖子:52帖 | 797回
  • 年度积分:0
  • 历史总积分:1171
  • 注册:2001年9月19日
发表于:2005-10-10 16:39:00
3楼
不错,的确有加精的必要 谢谢

autoyx.com

  • 精华:0帖
  • 求助:0帖
  • 帖子:32帖 | 634回
  • 年度积分:0
  • 历史总积分:882
  • 注册:2005年9月27日
发表于:2005-10-11 08:23:00
4楼
我也长期从事VC++的串口开发,对串口开发的心得体会如下 485通信编程的难点在于完整正确的数据包的提取,一般有二种方法:   1: 数据包前加同步帧,包长度信息,校验码.   2: 通过接收数据的时间判断,如>50ms未有新数据,判断一个包接收结束. 欢迎到我网站下载 http://www.tiasky.com/   串口调试工具:SPCfgTest.zip 大小为 252 KB    调整字节串接收时间(10mS~200mS),可将一般串口调试工具收不全的数据全收全;或不应断开收的数据收全、收完整。 http://www.tiasky.com/

oo9

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 1回
  • 年度积分:0
  • 历史总积分:1
  • 注册:2005年10月04日
发表于:2005-10-13 17:17:00
5楼
我采用了 ActiveX控件 (MScomm控件)编程,代码与上面一样,在具有VC的机器上,可以运行。但是拿到没有VC环境的机器上就会报错“错误创建空文档”,请问原因。 说明:采用release版本,mscomm控件已经注册。

autoyx.com

  • 精华:0帖
  • 求助:0帖
  • 帖子:32帖 | 634回
  • 年度积分:0
  • 历史总积分:882
  • 注册:2005年9月27日
发表于:2005-11-25 23:24:00
6楼
在VC环境下,建议不采用 ActiveX控件 编串口程序,  VC编串口程序的例程很多,可用baidu.com搜一下 http://www.tiasky.com/

段艳兵

  • 精华:0帖
  • 求助:1帖
  • 帖子:1帖 | 8回
  • 年度积分:0
  • 历史总积分:80
  • 注册:2005年8月12日
发表于:2005-11-27 09:08:00
7楼
我对串口通信很感兴趣,能给我一个具体的事例吗?

autoyx.com

  • 精华:0帖
  • 求助:0帖
  • 帖子:32帖 | 634回
  • 年度积分:0
  • 历史总积分:882
  • 注册:2005年9月27日
发表于:2005-11-27 17:00:00
8楼
用baidu.com搜  VC 串口

热门招聘
相关主题

官方公众号

智造工程师