请教通讯掩码的概念及其在串口通讯中的作用 Win32下,通过函数SetCommMask设置通讯掩码,请教通讯掩码的概念及其在串口通讯中的作用 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 你看看吧,不知道有没有用Delphi中串行通信的实现 ----随着现代信息技术的发展以及计算机网络的广泛使用,计算机通信技术已经日臻成熟,但串行通信作为一种灵活方便可靠的通信方式,仍不失为有效的通信手段,被广泛应用于工业控制中。在工业生产实践中,用PC机对工程实现实时监控,通常要求PC机能在用户界面上具有数据采集、数据处理以及控制信号的产生与传输等功能。在这种特定的环境下,PC机要与过程控制的实时信号相联系,就要求能实现对PC机的串行端口直接操作。Borland公司推出的Delphi是一种功能强大的高级编程语言,其具有的可视化面向对象的特性,特别适于在Windows环境下图形界面和用户程序的编制。本文就是介绍基于Windows95/NT操作系统用Delphi来实现PC机与下层PLC控制器之间的串口通信方法。 基于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()创建事件对象,使用SetEvent()或PulseEvent()函数将事件对象设置成信号同步。在应用程序中,利用WaitSingleObject()函数等待同步的触发,等到指定的事件被其它线程设置为有信号时,才继续向下执行程序。 Delphi下的具体实现方法 ----Delphi的强大功能和支持多线程的面向对象编程技术,使得实现串行通信非常简单方便。它通过调用外部的API函数来实现,主要步骤如下:首先,利用CreateFile函数打开串行口,以确定本应用程序对此串行口的占有权,并封锁其它应用程序对此串口的操作;其次,通过GetCommState函数填充设备控制块DCB,再通过调用SetCommState函数配置串行口的波特率、数据位、校验位和停止位。然后,创建串行口监视线程监视串行口事件。在此基础上就可以在相应的串口上操作数据的传输;最后,用CloseHandle函数关闭串行口。具体的程序如下,本程序用Delphi3.0编制在Win95环t境下调试通过,已投入实际应用中,供广大读者参考。 ----程序: unitcomdemou; interface uses Windows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs; const Wm_commNotify=Wm_User+12; type TForm1=class(TForm) procedureFormCreate(Sender:TObject); private Procedurecomminitialize; ProcedureMsgcommProcess(VarMessage:Tmessage);MessageWm_commnotify; {Privatedeclarations} public {Publicdeclarations} end; //线程声明 TComm=Class(TThread) protected procedureExecute;override; end; var Form1:TForm1; hcom,Post_Event:Thandle; lpol:Poverlapped; implementation {$R*.DFM} ProcedureTComm.Execute;//线程执行过程 var dwEvtMask:Dword; Wait:Boolean; Begin fillchar(lpol,sizeof(toverlapped),0); WhileTruedoBegin dwEvtMask:=0; Wait:=WaitCommEvent(hcom,dwevtmask,lpol);//等待串行口事件; ifWaitThenBegin waitforsingleobject(post_event,infinite);//等待同步事件置位; resetevent(post_event);//同步事件复位; PostMessage(Form1.Handle,WM_COMMNOTIFY,0,0);//发送消息; end; end; end; procedureTform1.comminitialize;//串行口初始化 var lpdcb:Tdcb; Begin hcom:=createfile('com2',generic_readorgeneric_write,0,nil,open_existing, file_attribute_normalorfile_flag_overlapped,0);//打开串行口 ifhcom=invalid_handle_valuethen 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; ProcedureTForm1.MsgcommProcess(VarMessage:Tmessage); var Clear:Boolean; Coms:Tcomstat; cbNum,ReadNumber,lpErrors:Integer; Read_Buffer:array[1..100]ofchar; Begin Clear:=Clearcommerror(hcom,lpErrors,@Coms); ifClearThenBegin cbNum:=Coms.cbInQue; ReadFile(hCom,Read_Buffer,cbNum,ReadNumber,lpol); //处理接收数据 SetEvent(Post_Event);//同步事件置位 end; end; procedureTForm1.FormCreate(Sender:TObject); begin comminitialize; post_event:=CreateEvent(nil,true,true,nil);//创建同步事件; Tcomm.Create(False);//创建串行口监视线程; end; end. 答非所问,我又不是要求教Win32串口通信编程,只是问一下通讯掩码的概念及其作用! 编译通不过,大家看看 说说各个内存分配函数的区别 delphi中Oracle的问题 关于如何创建可视化控件问题 用WebBrowser实现另存的功能 MAPX控件如何与D6 的CLIENTDATASET 相连接,谢谢! 一个安装程序在执行过程中怎么启动另外一个安装程序? 菜鸟问题 一个很菜的问题,拜托看一看。 工程在delphi2007下编译已经通过了,run后出现下面信息。高手指点 Setup Factory 7怎么打包Windows Service 请问如何判断一个字符是不是日文?
Delphi中串行通信的实现 ----随着现代信息技术的发展以及计算机网络的广泛使用,计算机通信技术已经日臻成熟,但串行通信作为一种灵活方便可靠的通信方式,仍不失为有效的通信手段,被广泛应用于工业控制中。在工业生产实践中,用PC机对工程实现实时监控,通常要求PC机能在用户界面上具有数据采集、数据处理以及控制信号的产生与传输等功能。在这种特定的环境下,PC机要与过程控制的实时信号相联系,就要求能实现对PC机的串行端口直接操作。Borland公司推出的Delphi是一种功能强大的高级编程语言,其具有的可视化面向对象的特性,特别适于在Windows环境下图形界面和用户程序的编制。本文就是介绍基于Windows95/NT操作系统用Delphi来实现PC机与下层PLC控制器之间的串口通信方法。 基于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()创建事件对象,使用SetEvent()或PulseEvent()函数将事件对象设置成信号同步。在应用程序中,利用WaitSingleObject()函数等待同步的触发,等到指定的事件被其它线程设置为有信号时,才继续向下执行程序。 Delphi下的具体实现方法
----Delphi的强大功能和支持多线程的面向对象编程技术,使得实现串行通信非常简单方便。它通过调用外部的API函数来实现,主要步骤如下:首先,利用CreateFile函数打开串行口,以确定本应用程序对此串行口的占有权,并封锁其它应用程序对此串口的操作;其次,通过GetCommState函数填充设备控制块DCB,再通过调用SetCommState函数配置串行口的波特率、数据位、校验位和停止位。然后,创建串行口监视线程监视串行口事件。在此基础上就可以在相应的串口上操作数据的传输;最后,用CloseHandle函数关闭串行口。具体的程序如下,本程序用Delphi3.0编制在Win95环t境下调试通过,已投入实际应用中,供广大读者参考。
----程序: unitcomdemou;
interface
uses
Windows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs; const
Wm_commNotify=Wm_User+12;
type
TForm1=class(TForm)
procedureFormCreate(Sender:TObject);
private
Procedurecomminitialize;
ProcedureMsgcommProcess(VarMessage:Tmessage);MessageWm_commnotify;
{Privatedeclarations}
public
{Publicdeclarations}
end; //线程声明
TComm=Class(TThread)
protected
procedureExecute;override;
end; var
Form1:TForm1;
hcom,Post_Event:Thandle;
lpol:Poverlapped;
implementation {$R*.DFM} ProcedureTComm.Execute;//线程执行过程
var
dwEvtMask:Dword;
Wait:Boolean;
Begin
fillchar(lpol,sizeof(toverlapped),0);
WhileTruedoBegin
dwEvtMask:=0;
Wait:=WaitCommEvent(hcom,dwevtmask,lpol);//等待串行口事件;
ifWaitThenBegin
waitforsingleobject(post_event,infinite);//等待同步事件置位;
resetevent(post_event);//同步事件复位;
PostMessage(Form1.Handle,WM_COMMNOTIFY,0,0);//发送消息;
end;
end;
end; procedureTform1.comminitialize;//串行口初始化
var
lpdcb:Tdcb;
Begin
hcom:=createfile('com2',generic_readorgeneric_write,0,nil,open_existing,
file_attribute_normalorfile_flag_overlapped,0);//打开串行口
ifhcom=invalid_handle_valuethen
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; ProcedureTForm1.MsgcommProcess(VarMessage:Tmessage);
var
Clear:Boolean;
Coms:Tcomstat;
cbNum,ReadNumber,lpErrors:Integer;
Read_Buffer:array[1..100]ofchar;
Begin
Clear:=Clearcommerror(hcom,lpErrors,@Coms);
ifClearThenBegin
cbNum:=Coms.cbInQue;
ReadFile(hCom,Read_Buffer,cbNum,ReadNumber,lpol);
//处理接收数据
SetEvent(Post_Event);//同步事件置位
end;
end; procedureTForm1.FormCreate(Sender:TObject);
begin
comminitialize;
post_event:=CreateEvent(nil,true,true,nil);//创建同步事件;
Tcomm.Create(False);//创建串行口监视线程;
end; end.