我要投搞

标签云

收藏小站

爱尚经典语录、名言、句子、散文、日志、唯美图片

当前位置:最新二四六论坛 > 动态控件 >

用WindowsAPI设计多线程的串行通信ActiveX控件

归档日期:07-04       文本归类:动态控件      文章编辑:爱尚语录

  信是计算机之间及计算机及数字化仪器和设备的一种重要通信手段,是实现工业监控的一种主要方式。Windows下的串行通信主要有两种方法:利用VB的MSCOMM控件和利用Windows API。MSCOMM控件简单易用,但由于其对及调用方式的局限性,不能灵活方便地对串口设备进行控制。而通过Windows API则可以实现对串口设备的完全控制,并且可以提供多线程的通信机制。

  在复杂应用中,通信通常在后台完成,需要采用多线程技术。一个多线程的应用程序实际上是在其内部实现了多任务扩展,为代码赋予了并行执行的特性,适于执行一些实时性或随机性很强的操作,也有利于提高CPU的利用率,加快通信程序的信息处理速度。

  本文以一台工业控制PC机与多台基于单片机的智能控制单片进行串行通信为实例。PC机和各智能控制单元通过RS485总线的通信方式是半双工的,只能由作为主节点的PC机依次轮询网络上的各智能控制单元子节点。每次通信都是由PC机通过串口向智能控制单元发布命令,智能控制单元在接收到正确的命令后做出应答。系统的主节点应用程序是用VB6.0编写的,为了既能提供多线程的串行通信机制,又可使应用程序易于实现串行通信功能,利用VC++6.0开发基于Window API的多线程串行通信ActiveX控件。主节点的应用程序通过对串行通信ActiveX控件的调用完成与各子节点的通信。

  VGC++6.0和MFC是健建ActiveX控件的强大而又灵活的工具。JinRiComm控件创建步骤简单概述如下:

  (3)向控件工程中添加类CserialPort,为该类添加成员变量和成员函数,该类将完成串行通信工作。

  串口通信的基本编程用Windows API函数实现串行通信,其特点是对串口的操作如对文件操作一样,打开和关闭串行设备与打开和关闭文件使用相同的函数。

  MFC执行两种类型的线程:用户界面线程和工作线程。前者用来处理用户输入,响应由用户产生的事件和消息。后者不处理窗口消息,用于完成后台计算、打印和其它一些没有必要强迫用户来等待的任务。在本程序中,用户界面线程就是程序的主线程,另外再添加两个工作线程:通信线程和延时线程。它们的功能介绍如表1所示。

  响应用户对控件的调用(设置控件属性和调用控制方法);初始化串口;处理通信线程接收到的数据,并通知用户(触发控件消息);通知通信线程向串口写数据。

  在主线程初始化串口后被创建。CommThread函数进入死循环,线程一直监视串口事件,当读串口事件发生,读取串口接收到的数据,向主线程发自定义消息WM_COMM_RXCHAR,通知主线程处理数据;收到主线程的写串口命令时,将缓存中的数据写到串口。

  在主线程向串口写数据之后被创建。如果主线置为真,延时线程在检查到其为真后,线程函数返回;否则会延时10ms再判断一次。如果超过八规定时间仍没检查到其为真,则向主线程发自定义消息WM_DELAY_TIMEOUT,通知主线程重发刚才的命令,然后线程函数返回。

  在启动一个工作线程之前,必须为线程编写一个全局的线程函数。这个线位的LPVOID作为参数,返回一个UINT,线程函数的结构为:

  终止线程有两种途径:当线程函数返回时,线程终止;线程函数也可以在内部调用AfxEndThread函数来终止自己。

  主线程可以采用多种方式与工作线程进行通信,最简单的办法是通过全局变量,因为进程中的所有线程都可以访问所有的全局变量。如:定义全局变量bReceiveSuccess,它表示是否收到了正确的响应。在主线程向串口写数据之后它被置为FALSE,然后延时线程启动。当系统收到正确的响应后,bReceiveSuccess被主线程改为TRUE。延时线程根据bReceiveSuccess的值来决定是结束该线程还是给主线)通过参数

  主线程可以向工作线字节的参数,一种使用该参数的常见方式是传递一个指针,它指向这个线程的父类。如:

  多线程的优点之一是所有线程都可以访问相同的全局对象和共享资源,它提供了程序设计的简捷性和便利性,提高了对信息处理的并发度。但如果不妥善处理好线程的并发问题,也会带来数据的错误或是资源的死锁。为了避免这些问题发生,线程在使用共享资源或对象前必须获得一个约束访问同步对象的权力,也就是通过同步的机制来控制这种权力的使用。线程间的同步多种方法。

  事件用来通知线程有一些事件已经发生,比较适合于信号控制。事件有手动复位和自动复位两种。手动复位事件是在应用程序或系统后台控制不改变它的信号状态。当手动复位事件处于有信号状态时,所有等待该事件的线程都被激活,事件保留有信号状态直到被一个应用程序复位为止。当一个自动复位事件处于有信号状态时,只有一个等待线程被激活,并且事件将复位成无信号,其它所有等待着的线程仍将保持挂起状态。

本文链接:http://fudousann.net/dongtaikongjian/503.html