基于多线程技术的异步串行通信应用

 1  引言
在工业控制领域,由于串行接口简单、使用方便,从而使得异步串行通信成为计算机之间极为常用的通信手段。C++ Builder 6是Borland公司推出的快速应用程序开发平台,它采用面向对象的C++作为开发语言,同时提供了良好的可视化开发环境,是目前开发Windows应用程序的强大、高效的开发平台之一。在基于Windows 2000的多任务操作平台下的控制系统中,利用C++ Builder的多线程技术实现串行通信可以增强控制程序的运行效率,保证控制的准确性和健壮性。

2  C++ Builder下的多线程开发
多线程应用程序是包含数个同时执行的线程的应用程序,C++ Builder中的TThread提供了用于简化编写多线程应用程序的对象,大大简化了编写多线程程序的难度。这些对象通过避免瓶颈、组织程序和多道处理等方式来增强程序的功能。
2.1  定义线程对象
要在应用程序中使用线程对象,必须创建TThread的一个新的派生类。可从主菜单中选择File|New来创建TThread的一个派生类,在新对话框中,选择Thread Object,系统会提示为新线程对象提供类名。在提供名字之后,C++ Builder创建一个新的.cpp和头文件以实现线程。自动生成的.cpp文件中包含关于新线程的代码框架,若将线程命名为TmyThread,则. cpp文件如下所示:
//--------------------------------
#include <vcl/vcl.h>
#include pragma hdrstop
#include “Unit2.h”
__fastcall TMyThread::TMyThread(bool CreateSuspended):Tthread(CreateSuspended)
{
}
//--------------------------------
void __fastcall TmyThread::Execute()
{
  //---- Place thread code here ----
}
//--------------------------------
在此段代码中,首先需要使用构造函数来初始化新线程类,一般是为线程分配缺省的优先级,并可指定线程是否在执行完成后自动释放。之后在Execute方法中编写线程函数实现任务。
多线程程序的编写和独立的程序不同,必须确认没有覆盖应用程序其他线程所使用的内存,同时因为线程与其他线程共享相同的进程空间,可使用共享内存在线程之间通信。可以通过使用主VCL线程、使用线程局部变量和检验其他线程发出的结束消息等方式实现线程函数编写的特殊要求。
2.2  执行线程对象
当定义Execute方法实现线程类后,可在应用程序中使用它来启动Execute方法的代码。要使用线程,首先创建线程类的一个实例。可以创建立即开始运行的线程实例,或创建一个处于临时中断状态的线程,只在调用Resume方法时开始。要创建一个立即开始运行的线程实例,将构造函数的 CreateSuspended参数设为false。例如,下列代码创建一个线程并开始执行:TmyThread *SecondPreocess = new TmyThread(false); //create and run the thread,在完成执行之前线程可被随意开始和停止,要结束或者临时停止线程,调用他们的Terminate或者Suspend方法。需继续时,调用 Resume方法。
2.3  协调线程
当编写线程执代码时,必须考虑到可能同步执行的其他线程的行为。特别要避免两个线程试图同时使用相同的全局对象或变量;另一方面,一个线程中代码可能会依赖其他线程所执行任务的结果。在C+ + Builder中,系统均提供了相应的机制来协调线程间的行为,达到避免冲突并发挥多线程优点的目的。

3  多线程方式下的串行通信
利用C++ Builder开发串口通信软件一般有两种方法:其一是利用Windows的API函数,其二是采用微软的MSComm控件。相对于API函数的方式, MSComm控件使用简单,但可靠性差一些,另外考虑到系统的兼容性和可移植性,推荐使用Windows的API函数来开发相关的串口通信软件。除了上述两种开发方式以外,开发者还可以使用第三方软件供应商针对C++ Builder开发的专用的串行通信组件,这些组件其实已经把Windows API函数以及多线程编程封装在其中,对用户而言只需要像使用普通组件一样来使用它们。但这种方式下,开发者受制于第三方组件的应用条件和功能,不利于自己的功能扩展。
除了少量简单应用外,要利用Windows API函数实现串行通信就必须采用多线程技术。使用多线程实现串行通信需要创建几个相关的线程,除了主线程以外,还包括串口监控线程,串口监控线程也可以单独创建为串口读线程和串口写线程。主线程即系统主程序,一般情况下就是这个主线程被提取到CPU执行,它负责系统功能的实现,同时也完成对串口的打开、关闭和初始化;当主线程在CPU执行时,应用程序还可以创建监控线程,用以监测串口的状态变化,对发生的串口事件做出反应。如果整个系统对串口的读写操作不会发生冲突,那么就可以把串口读线程和串口写线程合并到监控线程中,在监控线程中完成串口数据的读写操作。主线程中创建的线程都有各自的执行周期,监控线程的生命期的长短取决于主线程的功能要求。
多线程方式下,系统的功能块被明确地分开,各个线程完成各自的工作,这样的设计使得线程之间的协调和同步变得尤为重要,所以,在多线程程序设计中,线程之间的同步问题是一个设计的难点。

4  应用实例
下面给出了一个利用串行口进行高速数据采集的应用系统实例,该系统完成对某集群信道通信数据的采集工作。系统中的PC机要实时接收下位机所发送的大量数据,并完成对数据的实时存储;PC机对下发的数据很少,且是在串口数据接收、存储并处理完毕后才发送一个命令信号给下位机。由于系统实时性的要求,本文采用了多线程机制来分别实现PC机的串行通信功能和后台的数据处理功能,单片机作为下位机完成对数据采集设备的控制并完成对PC机的数据传输。
4.1  PC机通信模块
根据上述的系统功能描述,在应用程序中创建一个串口监控线程,用于读串口,完成串行数据接收;因为下发的数据量很小,所以写串口的操作在主线程中完成就可以了。主线程的功能是完成对串口的操作,对数据的存储和处理以及提供良好的人机界面。串口监控线程的功能是完成对串口的实时监控,捕捉串口事件,完成数据接收,并通过消息机制向主线程发送接收到的数据。为了方便对串口进行操作,系统设计了一个串口类,封装了同操作串口通信相关的Windows的API函数。
主线程的程序流程如图1所示:

图1     主线程程序流程图


监控线程的程序流程如图2所示:

图2     监控线程的程序流程图


4.2  单片机通信模块
单片机和集群信道数据源的连接和处理部分在本文中略去,只给出单片机的串行通信实现部分。单片机采用89C51,其串行接口工作于方式3,SMOD=0,采用11.0592MHz的晶振实现 9600波特率的通信速率,定时器/计数器1工作在方式2(自动重装载方式)。下面给出单片机串行连接部分的软件流程图,如图3所示:

图3     单片机串行通信流程图


5  结束语
越来越多的控制平台开始基于Windows系统,有效而充分地利用Windows的多任务机制可以满足控制系统的诸多要求。在利用串行通信的控制系统中,及时把被控对象的信息反馈给控制器,以及在控制端完成中间数据处理过程并实施新的控制命令都需要串行口高速、有效和可靠地工作。实践证明,多线程技术应用于异步串行通信对于提高上述的高速数据采集系统的稳定性和灵活性具有重要的意义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值