谁有没有关于串口方面 的资料。如串口方面的组件等!高分相送 谁有没有关于串口方面 的资料。如串口方面的组件等! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 Delphi中串行通信的实现随着现代信息技术的发展以及计算机网络的广泛使用,计算机通信技术已经日臻成熟,但串行通信作为一种灵活、方便、可靠的通信方式,仍不失为有效的通信手段,被广泛应用于工业控制中。在工业生产实践中,用PC机对工程实现实时监控,通常要求PC机能在用户界面上具有数据采集、数据处理以及控制信号的产生与传输等功能。在这种特定的环境下,PC机要与过程控制的实时信号相联系,就要求能实现对PC机的串行端口直接操作。Borland公司推出的Delphi是一种功能强大的高级编程语言,其可视化面向对象的特性,适于在Windows环境下图形界面和用户程序的编制。本文介绍基于Windows 95/NT操作系统用Delphi来实现PC机与下层PLC控制器之间的串口通信方法。基于Windows 95/NT的串行通信机制Windows操作系统禁止应用程序直接访问计算机硬件,但它为程序员提供了一系列标准API函数,使得应用程序的编制更加方便,并且免除了对有关硬件调试的麻烦。在Windows 95/NT中,原来Windows 3.X的WM_COMMNOTIFY消息已被取消,操作系统为每个通信设备开辟了用户可定义大小的读/写缓冲区,数据进出通信口均由操作系统后台完成,应用程序只需对读/写缓冲区操作即可。Windows 95/NT中几个常用的串行通信操作函数如下:@@0474300.JPG;表1@@除上述几个函数外,还要经常用到一个重要的记录DCB(设备控制块)。DCB中记录有可定义的串行口参数,设置串行口参数时必须先用GetCommState函数将系统默认值填入DCB控制块,然后才可设定用户想改变的自定义值。在Windows 95/NT中实现串行通信除了要了解基本的通信操作函数外,还要掌握多线程编程。线程是进程内部执行的路径,是操作系统分配CPU时间的基本实体,每个进程都由单线程开始完成应用程序的执行。串行通信需要利用多线程技术实现,其主要的处理逻辑可以表述如下:进程一开始先由主线程做一些必要的初始化工作,然后主线程根据需要在适当时候建立线程监视通信口,当指定的串行口事件发生时,向主线程发送WM_COMMNOFY消息(由于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;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;constWm_commNotify=Wm_User+12;type TForm1 = class(TForm)procedure FormCreate(Sender: TObject); privateProcedure comminitialize;Procedure MsgcommProcess(Var Message:Tmessage); Message Wm_commnotify;{ Private declarations } public{ Public declarations } end; //线程声明 TComm=Class(TThread) protectedprocedure Execute;override; end;var Form1: TForm1; hcom,Post_Event:Thandle; lpol:Poverlapped;implementation{$R *.DFM}Procedure TComm.Execute;//线程执行过程vardwEvtMask:Dword;Wait:Boolean;Beginfillchar(lpol,sizeof(toverlapped),0);While True do Begin dwEvtMask:=0; Wait:=WaitCommEvent(hcom,dwevtmask,lpol); //等待串行口事件; if Wait Then Beginwaitforsingleobject(post_event,infinite); //等待同步事件置位;resetevent(post_event);//同步事件复位;PostMessage(Form1.Handle,WM_COMMNOTIFY,0,0);//发送消息;end; end;end;procedure Tform1.comminitialize;//串行口初始化varlpdcb:Tdcb;Beginhcom:=createfile(‘com2’,generic_read or generic_write,0,nil,open_existing, file_attribute_normal or file_flag_overlapped,0);//打开串行口if hcom=invalid_handle_value thenelsesetupcomm(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);varClear:Boolean;Coms:Tcomstat;cbNum,ReadNumber,lpErrors:Integer;Read_Buffer:array[1..100]of char;BeginClear:=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);begincomminitialize;post_event:=CreateEvent(nil,true,true,nil); //创建同步事件;Tcomm.Create(False);//创建串行口监视线程;end;end. 我有tubroPower和例程,需要发消息 SPCOMM的使用 下面是一个利用 SPCOMM控件的串口通信的例子。 以实现 PC机与单片机 8051之间的通信为例,首先要调通它们之间的握手信号。假定它们之间的通信协议是: PC到 8051一帧数据 6个字节, 8051到 PC一帧数据也为 6个字节。当 PC发出( F0,01,FF,FF,01,F0)后 8051能收到一帧( F0,01,FF,FF,01,F0),表示数据通信握手成功,两者之间就可以按照协议相互传输数据。 图 2 1.设定 COMM1属性: ●波特率: 4800; ●奇偶校验位:无; ●字节长度: 8; ●停止位: 1; ●串口: COM1。 Memo1中将显示发送和接收的数据。将新的窗体存储为 Comm.pas。 2.编写源代码 //变量说明 var fcomm: TFCOMM; viewstring:string; i:integer; rbuf,sbuf:array[16] of byte; //打开串口 procedure TFCOMM.FormShow(Sender: TObject); begin comm1.StartComm; end; //关闭串口 procedure TFCOMM.FormClose(Sender: TObject; var Action: TCloseAction); begin comm1.StopComm; end; //自定义发送数据过程 procedure senddata; var i:integer; commflg:boolean; begin viewstring:=‘’ ; commflg:=true; for i:=1 to 6 do begin if not fcomm.comm1.writecommdata(@sbuf[i],1) then begin commflg:=false; break; end; //发送时字节间的延时 sleep(2); viewstring:=viewstring+ inttohex(sbuf[i],2)+‘’ ; end; viewstring:=‘发送’+ viewstring; fcomm.memo1.lines.add(viewstring); fcomm.memo1.lines.add(‘’ ); if not commflg then messagedlg(‘发送失败 !’ ,mterror,[mbyes],0); end; //发送按钮的点击事件 procedure TFCOMM.Btn_sendClick(Sender: TObject); begin sbuf[1]:=byte($ f0); //帧头 sbuf[2]:=byte($ 01); //命令号 sbuf[3]:=byte($ ff); sbuf[4]:=byte($ ff); sbuf[5]:=byte($ 01); sbuf[6]:=byte($ f0); //帧尾 senddata;//调用发送函数 end; //接收过程 procedure TFCOMM.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;BufferLength: Word); var i:integer; begin viewstring:=‘’ ; move(buffer^,pchar(@rbuf^),bufferlength); for i:=1 to bufferlength do viewstring:=viewstring+ inttohex(rbuf[i],2)+‘’ ; viewstring:=‘接收’+ viewstring; memo1.lines.add(viewstring); memo1.lines.add(‘’ ); end; 如果 memo1上显示发送 F0 01 FF FF 01 F0和接收到 F0 01 FF FF 01 F0,这表示串口已正确地发送出数据并正确地接收到数据,则串口通信成功。 mscomm:微软的东西,ActivX控件,使用简单,在VB中带的,性能一般,由于是ActivX控件,打包时需要注册好多信息,不推荐使用。spcomm:比较好的vcl,算是比较专业的,解剖了一下,功能比较完善。TurboPower:公认的专业通讯控件。可以到其站点下载,开放源码了。我在制作串口通讯软件时三种都用过,最终全部使用TurboPower!所以也推荐大家使用它。写了个例子,基本的串口通讯都可以实现,可提供参考。下载地址:http://www.kaer.cn/default.aspx(网站安全性较差,经常当机,如果急用,mail我)多多指正:[email protected] html 转 mht 的问题。是否有方法可以设置 CdoMHTMLFlags 属性而不需要调用CreateMHTMLBody 函数 InterBase中的cache 在计算机中是怎样处理的? 高分求教!!如何用QRprot将树形报表打印出来? 数据交换 帮新手了!!!!帮者有分 翻译代码了 从delphi 到C# 如何建立一个动态连接库.dll,菜鸟发问 delphi的最小化问题? 关于的MASKEDIT的问题请指教谢谢 Delphi中如何删除ListView1中选中的一行 有关函数locate的问题?谁能帮我看一下 哪位老大帮我解决一下串口读写问题!
SPCOMM的使用
下面是一个利用 SPCOMM控件的串口通信的例子。
以实现 PC机与单片机 8051之间的通信为例,首先要调通它们之间的握手信号。假定它们之间的通信协议是: PC到 8051一帧数据 6个字节, 8051到 PC一帧数据也为 6个字节。当 PC发出( F0,01,FF,FF,01,F0)后 8051能收到一帧( F0,01,FF,FF,01,F0),表示数据通信握手成功,两者之间就可以按照协议相互传输数据。
图 2
1.设定 COMM1属性:
●波特率: 4800;
●奇偶校验位:无;
●字节长度: 8;
●停止位: 1;
●串口: COM1。
Memo1中将显示发送和接收的数据。将新的窗体存储为 Comm.pas。
2.编写源代码
//变量说明
var
fcomm: TFCOMM;
viewstring:string;
i:integer;
rbuf,sbuf:array[16] of byte;
//打开串口
procedure TFCOMM.FormShow(Sender: TObject);
begin
comm1.StartComm;
end;
//关闭串口
procedure TFCOMM.FormClose(Sender: TObject; var Action: TCloseAction);
begin
comm1.StopComm;
end;
//自定义发送数据过程
procedure senddata;
var
i:integer;
commflg:boolean;
begin
viewstring:=‘’ ;
commflg:=true;
for i:=1 to 6 do
begin
if not fcomm.comm1.writecommdata(@sbuf[i],1) then
begin
commflg:=false;
break;
end;
//发送时字节间的延时
sleep(2);
viewstring:=viewstring+ inttohex(sbuf[i],2)+‘’ ; end;
viewstring:=‘发送’+ viewstring;
fcomm.memo1.lines.add(viewstring);
fcomm.memo1.lines.add(‘’ );
if not commflg then messagedlg(‘发送失败 !’ ,mterror,[mbyes],0);
end;
//发送按钮的点击事件
procedure TFCOMM.Btn_sendClick(Sender: TObject);
begin
sbuf[1]:=byte($ f0); //帧头
sbuf[2]:=byte($ 01); //命令号
sbuf[3]:=byte($ ff);
sbuf[4]:=byte($ ff);
sbuf[5]:=byte($ 01);
sbuf[6]:=byte($ f0); //帧尾
senddata;//调用发送函数
end;
//接收过程
procedure TFCOMM.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;BufferLength: Word);
var
i:integer;
begin
viewstring:=‘’ ;
move(buffer^,pchar(@rbuf^),bufferlength);
for i:=1 to bufferlength do
viewstring:=viewstring+ inttohex(rbuf[i],2)+‘’ ;
viewstring:=‘接收’+ viewstring;
memo1.lines.add(viewstring);
memo1.lines.add(‘’ );
end;
如果 memo1上显示发送 F0 01 FF FF 01 F0和接收到 F0 01 FF FF 01 F0,这表示串口已正确地发送出数据并正确地接收到数据,则串口通信成功。
spcomm:比较好的vcl,算是比较专业的,解剖了一下,功能比较完善。
TurboPower:公认的专业通讯控件。可以到其站点下载,开放源码了。
我在制作串口通讯软件时三种都用过,最终全部使用TurboPower!所以也推荐大家使用它。
写了个例子,基本的串口通讯都可以实现,可提供参考。
下载地址:http://www.kaer.cn/default.aspx(网站安全性较差,经常当机,如果急用,mail我)
多多指正:[email protected]