怎样用DELPHI实现串口通信(200分)

  • 主题发起人 主题发起人 小小飞侠
  • 开始时间 开始时间

小小飞侠

Unregistered / Unconfirmed
GUEST, unregistred user!
我有一FOXPRO数据库是变动的,想当数据库变动时通过MODEM传送到另一台机器,请问各位高手用DELPHI编程怎样实现。(MODEM是异步MODEM)
 
<<计算机世界周报>>

Delphi中串行通信的实现
王琛

--------------------------------------------------------------------------------

____随着现代信息技术的发展以及计算机网络的广泛使用,计算机通信技术已经日臻成熟 ,但串行通信作为一种灵活、方便、可靠的通信方式,仍不失为有效的通信手段,被广泛应用于工业控制中。在工业生产实践中,用PC机对工程实现实时监控,通常要求PC机能在用户界面上具有数据采集、数据处理以及控制信号的产生与传输等功能。在这种特定的环境下,PC机要与过程控制的实时信号相联系,就要求能实现对PC机的串行端口直接操作。 Borland公司推出的Delphi是一种功能强大的高级编程语言,其可视化面向对象的特性,适于在Windows环境下图形界面和用户程序的编制。本文介绍基于Windows 95/NT操作系统用Delphi来实现PC机与下层PLC控制器之间的串口通信方法。

____基于Windows 95/NT的串行通信机制

____Windows操作系统禁止应用程序直接访问计算机硬件,但它为程序员提供了一
系列标准API函数,使得应用程序的编制更加方便,并且免除了对有关硬件调试的
麻烦。在Windo ws 95/NT中,原来Windows 3.X的WM_COMMNOTIFY消息已被取消,操
作系统为每个通信设备开辟了用户可定义大小的读/写缓冲区,数据进出通信口均
由操作系统后台完成,应用程序只需对读/写缓冲区操作即可。Windows 95/NT中
几个常用的串行通信操作函数如下:

CreateFile 打开串行口
CloseHandle 关闭串行口
SetupComm 设置通讯缓冲区大小
ReadFile 读串口操作
WriteFile 写串口操作
SetCommState 设置通信参数
GetCommState 获取默认通信参数
ClearCommError 清除串口错误并获取当前状态

表1

____除上述几个函数外,还要经常用到一个重要的记录DCB(设备控制块)。DCB中
记录有可定义的串行口参数,设置串行口参数时必须先用GetCommState函数将系
统默认值填入DCB 控制块,然后才可设定用户想改变的自定义值。

____在Windows 95/NT中实现串行通信除了要了解基本的通信操作函数外,还要掌
握多线程编程。线程是进程内部执行的路径,是操作系统分配CPU时间的基本实
体,每个进程都由单线程开始完成应用程序的执行。串行通信需要利用多线程技
术实现,其主要的处理逻辑可以表述如下:进程一开始先由主线程做一些必要的初
始化工作,然后主线程根据需要在适当时候建立线程监视通信口,当指定的串行口
事件发生时,向主线程发送WM_COMMNO FY消息(由于Windows 95取消了
WM_COMMNOTIFY消息,因此程序员必须自己创建),主线程对其进行处理。若不需要
WM_COMMNOTIFY消息,则主线程终止通信监视线程。

____多线程同时执行可能会引起对共享资源的冲突,为避免冲突,需要用同步多线
程对共享资源进行访问。Windows 95提供了许多保持线程同步的方法,笔者采用
创建事件对象来保持线程同步。通过CreateEvent()创建事件对象,使用SetEvent
()或PulseEvent()函数将事件对象设置成信号同步。在应用程序中,利用
WaitSingleObject()函数等待同步的触发,等到指定的事件被其它线程设置为有
信号时,才继续向下执行程序。

____Delphi下的具体实现方法

____Delphi的强大功能和支持多线程的面向对象编程技术,使得实现串行通信非
常简单方便。它通过调用外部的API函数来实现,主要步骤如下。

____1. 利用CreateFile函数打开串行口,以确定本应用程序对此串行口的占有
权,并封锁其它应用程序对此串口的操作;

____2. 通过GetCommState函数填充设备控制块DCB,再通过调用SetCommState函
数配置串行口的波特率、数据位、校验位和停止位;

____3. 创建串行口监视线程监视串行口事件,在此基础上就可以在相应的串口上
操作数据的传输;

____4. 用CloseHandle函数关闭串行口(具体的程序如下)。本程序用Delphi3.0
编写,在 Windows 95环境下调试通过,已投入实际应用中,供广大读者参考。

____程序:

____unit comdemou;

____interface

____uses

____Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialo gs;

____const

____Wm_commNotify=Wm_User+12;

____type

____TForm1 = class(TForm)

____procedure FormCreate(Sender: TObject);

____private

____Procedure comminitialize;

____Procedure MsgcommProcess(Var Message:Tmessage); Message Wm_commnotify;

____{ Private declarations }

____public

____{ Public declarations }

____end;

____//线程声明

____TComm=Class(TThread)

____protected

____procedure Execute;override;

____end;

____var

____Form1: TForm1;

____hcom,Post_Event:Thandle;

____lpol:Poverlapped;

____implementation

____{$R *.DFM}

____Procedure TComm.Execute;

____//线程执行过程

____var

____dwEvtMask:Dword;

____Wait:Boolean;

____Begin

____fillchar(lpol,sizeof(toverlapped),0);

____While True do Begin

____dwEvtMask:=0;

____Wait:=WaitCommEvent(hcom,dwevtmask,lpol);

____//等待串行口事件;

____if Wait Then Begin

____waitforsingleobject(post_event,infinite);  //等待同步事件置位;

____resetevent(post_event);

____//同步事件复位;

____PostMessage(Form1.Handle,WM_COMMNOTIFY,0,0);//发送消息;

____end;

____end;

____end;

____procedure Tform1.comminitialize;

____//串行口初始化

____var

____lpdcb:Tdcb;

____Begin

____hcom:=createfile(‘com2’,generic_read or generic_write,0,nil,open_exist ing,

____file_attribute_normal or file_flag_overlapped,0);//打开串行口

____if hcom=invalid_handle_value then

____else

____setupcomm(hcom,4096,4096);

____//设置输入、输出缓冲区皆为4096字节

____getcommstate(hcom,lpdcb);

____//获取串行口当前默认设置

____lpdcb.baudrate:=2400;

____lpdcb.StopBits:=1;

____lpdcb.ByteSize:=8;

____lpdcb.Parity:=EvenParity;

____//偶校验

____Setcommstate(hcom,lpdcb);

____setcommMask(hcom,ev_rxchar);

____//指定串行口事件为接收到字符;

____end;

____Procedure TForm1.MsgcommProcess(Var Message:Tmessage);

____var

____Clear:Boolean;

____Coms:Tcomstat;

____cbNum,ReadNumber,lpErrors:Integer;

____Read_Buffer:array[1..100]of char;

____Begin

____Clear:=Clearcommerror(hcom,lpErrors,@Coms);

____if Clear Then Begin

____cbNum:=Coms.cbInQue;

____ReadFile(hCom,Read_Buffer,cbNum,ReadNumber,lpol);

____//处理接收数据

____SetEvent(Post_Event);

____//同步事件置位

____end;

____end;

____procedure TForm1.FormCreate(Sender: TObject);

____begin

____comminitialize;

____post_event:=CreateEvent(nil,true,true,nil); //创建同步事件;

____Tcomm.Create(False);

____//创建串行口监视线程;

____end;

____end.

 
此问题已提过很多次了,你可以用"串口"查一下。
答案很多。
 
给你一个例程.

mail me.
 
我们最近正在搞这个东西,做一个交通信息管理系统。你可以去找HEXI,他是这方面的专家,也在“大富翁论坛”中
 
接受答案了.
 
后退
顶部