分享
 
 
 

Delphi中串行通信的实现 作者:阮帮秋

王朝delphi·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

Delphi中串行通信的实现作者:阮帮秋发布时间:2001/04/19

文章摘要:

本文就是介绍基于Windows95/NT操作系统用Delphi来实现PC机与下层PLC控制器之间的串口通信方法。

关键词串行通信,Delphi,多线程

正文:

Delphi中串行通信的实现

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

基于WIN95/NT的串行通信机制

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

CreatFile打开串行口

CloseHandle关闭串行口

SetupComm设置通信缓冲区的大小

ReadFile读串口操作

WriteFile写串口操作

SetCommState设置通信参数

GetCommState获取默认通信参数

ClearCommError清除串口错误并获取当前状态

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

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

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

Delphi下的具体实现方法

Delphi的强大功能和支持多线程的面向对象编程技术,使得实现串行通信非常简单方便。它通过调用外部的API函数来实现,主要步骤如下:首先,利用CreateFile函数打开串行口,以确定本应用程序对此串行口的占有权,并封锁其它应用程序对此串口的操作;其次,通过GetCommState函数填充设备控制块DCB,再通过调用SetCommState函数配置串行口的波特率、数据位、校验位和停止位。然后,创建串行口监视线程监视串行口事件。在此基础上就可以在相应的串口上操作数据的传输;最后,用CloseHandle函数关闭串行口。具体的程序如下,本程序用Delphi3.0编制在Win95 环境下调试通过,已投入实际应用中,供广大读者参考。

程序:

unit comdemou;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

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_existing,

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.

作者会员名:ruan_bangqiu

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有