Delphi中ComPort通信中的数据处理范文

合集下载

在delphi7中利用mscomm控件串口通信编程

在delphi7中利用mscomm控件串口通信编程
sleep(10);
Application.ProcessMessages;
i := i + 1;
If i > 30000 Then
begin
showmessage('发送超时!');
break;
end;
Until bzw = true;
redata:=mscomm1.Input; 接收数据
restr:='';
for i:=0 to vararrayhighbound(redata,1) do
restr:=restr + inttohex(redata[i],2)+' ';
sendstr:='';
for i:=1 to 5 do
sendstr:=sendstr + senddata[i];
mscomm1.output:=sendstr; //发送数据
i:=0;
bzw:考人民邮电《DELPHI串口通信编程》
-其他例子均是网络搜索。
:在delphi7中利用mscomm控件编程
Mscomm是微软一个强大的串口通讯的控件,其强大,简单的特点今我们不舍,在delphi中我们也可以使用它。下面这些代码是针对发送和接收为16进制处理的。
var
senddata:array[1..10] of char;
end;
end;
mscomm1.PortOpen:=false;
flatmemo1.Text:=restr;
end;
//oncomm事件
procedure TForm1.MSComm1Comm(Sender: TObject);

Delphi中ComPort通信中的数据处理范文

Delphi中ComPort通信中的数据处理范文

Delphi中ComPort通信中的数据处理范文在Delphi中使用ComPort进行通信时,数据处理是一个非常重要的步骤。

本文将详细介绍如何在Delphi中进行ComPort通信的数据处理。

首先,我们需要使用Delphi的ComPort组件来建立与外部设备的通信。

在使用ComPort组件之前,我们需要在Delphi的工具箱中添加ComPort组件。

添加完成后,我们可以在Delphi的窗体上放置一个ComPort组件。

接下来,我们需要在代码中对ComPort进行配置。

首先,我们需要设置ComPort的端口号和波特率。

例如,我们可以将端口号设置为COM1,波特率设置为9600。

可以通过以下代码实现:```ComPort1.Port := 'COM1';ComPort1.BaudRate := br9600;```然后,我们需要打开ComPort以建立与外部设备的连接。

可以使用以下代码打开ComPort:```ComPort1.Open;```在建立了与外部设备的连接后,我们就可以开始进行数据的发送和接收了。

数据的发送可以通过ComPort的WriteStr方法实现。

例如,我们可以发送一个字符串“Hello”到外部设备:```ComPort1.WriteStr('Hello');```数据的接收可以通过ComPort的OnRxChar事件来处理。

在该事件中,我们可以读取接收到的数据并进行相应的处理。

例如,我们可以将接收到的数据显示在一个文本框中:```procedure Port1RxChar(Sender: TObject; Count: Integer);varData: string;beginData := ComPort1.ReadStr(Count);Edit1.Text := Data;end;```在上面的代码中,我们使用了ComPort的ReadStr方法来读取接收到的数据,并将其赋值给一个字符串变量Data。

Delphi com口编程

Delphi com口编程

delphi中使用spcomm来实现串口通讯最近两天一直在研究spcomm控件的使用,之前也是很不太明白,看了很多的例子,可是按照网上很多的例子它们多少都有点瑕疵,运行不了,鉴于自己在做这方面的项目,也用了645规约试验了下,现在终于明白了一点。

不过要想精通还再要学习!先把我的学习经验跟大家分享下,也让很多新手快点上手。

其实相对于mscomm来讲,spcomm简单明了容易操作,其主要有几个属性要设置和它的方法判断以及事件驱动三大块,掌握了这三个步骤那全盘解决了!一、属性设置-(不过我还没研究好怎么在程序中动态设置)mName:=‘COM1’; //串口号comm1.BaudRate:=1200;//波特率1200 4800 9600 115200当然也可以有范围比方1201 1205comm1.ByteSize:=_8; //数据位 5 6 7 8comm1.Parity:=Even; //检验位Even Odd None Space Markcomm1.StopBits:=_1; //停止位1 1.5 2comm1.OnReceiveData:=Comm1ReceiveData; //这个是你以后写事件驱动时的名称,你可以改成你的名字二、方法comm1.StartComm; //打开串口当然它也有异常捕获共七种::⑴串口已经打开;⑵打开串口错误;⑶文件句柄不是通信句柄;⑷不能够安装通信缓存;⑸不能产生事件;⑹不能产生读进程;⑺不能产生写进程;comm1.StopComm方法用于关闭串口,没有返回值;comm1.WriteCommData(pDataToWrite: PChar;dwSizeofDataToWrite:Word )方法是个带有布尔型返回值的函数,用于将一个字符串发送到写进程,发送成功返回true,发送失败返回false。

执行此函数将立即得到返回值,发送操作随后执行。

该函数有两个参数,其中pDataToWrite是要发送的字符串,dwSizeofDataToWrite是发送字符串的长度。

Delphi编写串口通讯方法(转)

Delphi编写串口通讯方法(转)

Delphi编写串⼝通讯⽅法(转)前段时间做了个东西,计算机和单⽚机通讯,⽤到了串⼝编程,上位机⽤的是delphi,下位机⽤ats51,程序也做完了,顺便把Delphi串⼝编程给⼤家介绍以下.Delphi串⼝通讯可以同过以下⼏种⽅式:1.windows API函数。

2.Spocmm组件。

3.PComm库函数。

4.Mscomm控件。

1.windows API函数。

由于API函数实现起来⽐较⿇繁,这⾥就不做介绍了,主要介绍其它三种⽅式 .第三⽅组件或控件封装了API函数,简化了编程的难度,并提供详细帮助。

2.Spocmm组件。

SPcomm是专为delphi开发的组件,虽然它也是封装了windows api,但是我们可以看到它的源代码。

它提供了事件驱动的⽅式接收数据,在编程的时候,我们可以在OnReceiveData函数中接收到数据,并做相应的处理,SPcomm组件的主要属性:CommName:设置通讯端⼝BaudRate:设置端⼝波特率StartComm:打开串⼝StopComm:关闭串⼝WriteCommData:向串⼝写数据函数OnReceiveData:接收数据事件3.PComm库函数。

PComm库函数PComm 库函数是台湾MOXA公司提供的,他为⽤户提供了基于win32 api的开发接⼝。

PComm库函数分为7⼤类控制函数数据输⼊函数数据输出函数状态函数事件驱动函数传输⽂件函数特殊设定函数控制函数主要包括sio_open,sio_close,sio_ioct,sio_flushsio_open(PortNum) 打开串⼝sio_close(PortNum) 关闭串⼝sio_ioct(PortNum, baud, mode)设置串⼝的⼯作模式,包括 波特率,数据位,停⽌位,效验等sio_flush(portNum,func)清除发送,接收缓冲区 其中func 为0清空输⼊ ,为1清空输出,为2清空输⼊输出数据输⼊函数主要包括sio_getch,sio_readsio_getch(PortNum) 从输⼊缓冲区读⼀个字符sio_read(PortNum,buf,len)从输⼊缓冲区读指定个数的字符数据输⼊函数主要包括sio_putch sio_writesio_putch(PortNum) 写⼀个字符到输出缓冲区sio_write(PortNum,buf,len)写指定个数的字符到输出缓冲区状态函数主要包括 sio_lstatus,sio_getbaud,sio_getmodesio_lstatus(portNum)获取串⼝的CTS,DSR,DCD,RI线的状态sio_getbaud(portNum)获取串⼝的波特率sio_getmode(portNum)获取串⼝的⼯作模式。

使用Delphi对手机通讯的编程

使用Delphi对手机通讯的编程

使用Delphi对手机通讯的编程2009-06-18 21:52unit PanasonicGD;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, RXClock, ExtCtrls, RXCtrls, Gauges, OoMisc, AdPort, DsFancyButton;type TPanasonicGD92 = class(TForm)SoftwareTitle: TRxLabel;ComPortItem: TPanel;PhoneInfo: TPanel;ComPort1: TRadioButton;ComPort2: TRadioButton;ComPort3: TRadioButton;ComPort4: TRadioButton;Com1Port: TRxLabel;Com2Port: TRxLabel;Com3Port: TRxLabel;Com4Port: TRxLabel;RealClock: TRxClock;Autohor: TRxLabel;SoftwareVersion: TRxLabel;PhoneIMEI: TRxLabel;GD92SW: TEdit;GD92IMEI: TEdit;JobItem: TPanel;ProcessInfo: TPanel;PhoneLockCode: TRxLabel;GD92CODE: TEdit;ProcessBar: TGauge;PromptInfo: TPanel;UserInfo: TLabel;ComPort: TApdComPort;ExitProgram: TDsFancyButton;TestMode: TDsFancyButton;ReadInfo: TDsFancyButton;Chinese: TDsFancyButton;ExitTestMode: TDsFancyButton;function GetCOMData(Count: integer): string;procedure ExitProgramClick(Sender: TObject);procedure TestModeClick(Sender: TObject);procedure ComPortTriggerAvail(CP: TObject; Count: word); procedure ChineseClick(Sender: TObject);procedure ExitTestModeClick(Sender: TObject);procedure ReadInfoClick(Sender: TObject);private { Private declarations }public { Public declarations }end;var PanasonicGD92: TPanasonicGD92;ResponseArray: array[1..300] of string;Step: integer;PanaGD9xIMEI: string;PanaGD9xCode: string;PanaGD9xSW: string;DoStop: boolean;implementation{$R *.DFM}function TPanasonicGD92.GetCOMData(Count: integer): string; var I: integer;beginResult := ';for I := 1 to Count doResult := Result + IntToHex(byte(ComPort.GetChar), 02); end;procedure TPanasonicGD92.ExitProgramClick(Sender: TObject); beginClose;end;procedure TPanasonicGD92.TestModeClick(Sender: TObject); beginif TestMode.Caption = 'Stop Jobs' thenDoStop := True elsebeginTestMode.Caption := 'Stop Jobs';Step := 1;if ComPort1.Checked thenNumber := 1;if ComPort2.Checked thenNumber := 2;if ComPort3.Checked thenNumber := 3;if ComPort4.Checked thenNumber := 4;UserInfo.Caption := 'Press Phone Power On Key ...'; ResponseArray[Step] := '00';while Step = 1 do begin Application.ProcessMessages;if DoStop thenbeginTestMode.Caption := 'Test Mode';Exit;end;ProcessBar.Progress := 0;ReadInfo.Enabled := True;Chinese.Enabled := True;ExitTestMode.Enabled := True;UserInfo.Caption := 'Phone Test Mode OK !';end;end;procedure TPanasonicGD92.ChineseClick(Sender: TObject); beginStep := 5;ProcessBar.ForeColor := clLime;ResponseArray[Step] := '00800110';ComPort.PutChar(#$00);ProcessBar.Progress := 4;ComPort.PutChar(#$80);ProcessBar.Progress := 8;ComPort.PutChar(#$02);ProcessBar.Progress := 12;ComPort.PutChar(#$E2);ProcessBar.Progress := 15;ComPort.PutChar(#$00);ProcessBar.Progress := 19;while Step = 5 do begin Application.ProcessMessages; if DoStop then Exit;end;Step := 6;ResponseArray[Step] := '00800110';ComPort.PutChar(#$00);ProcessBar.Progress := 23;ComPort.PutChar(#$80);ProcessBar.Progress := 27;ComPort.PutChar(#$03);ProcessBar.Progress := 31;ComPort.PutChar(#$9A);ProcessBar.Progress := 35;ComPort.PutChar(#$00);ProcessBar.Progress := 38;ComPort.PutChar(#$FF);ProcessBar.Progress := 42;while Step = 6 do beginApplication.ProcessMessages;if DoStop then Exit;Step := 7;ResponseArray[Step] := '00800110';ComPort.PutChar(#$00);ProcessBar.Progress := 46;ComPort.PutChar(#$80);ProcessBar.Progress := 50;ComPort.PutChar(#$0B);ProcessBar.Progress := 54;ComPort.PutChar(#$CB);ProcessBar.Progress := 58;ComPort.PutChar(#$02);ProcessBar.Progress := 62;ComPort.PutChar(#$00);ProcessBar.Progress := 65;ComPort.PutChar(#$00);ProcessBar.Progress := 69;ComPort.PutChar(#$00);ProcessBar.Progress := 73;ComPort.PutChar(#$00);ProcessBar.Progress := 77;ComPort.PutChar(#$07);ProcessBar.Progress := 81;ComPort.PutChar(#$00);ProcessBar.Progress := 85;ComPort.PutChar(#$00);ProcessBar.Progress := 88;ComPort.PutChar(#$00);ProcessBar.Progress := 92;ComPort.PutChar(#$00);ProcessBar.Progress := 96;ComPort.PutChar(#$00);ProcessBar.Progress := 100;while Step = 7 dobeginApplication.ProcessMessages;if DoStop then Exit;end;ProcessBar.Progress := 0;UserInfo.Caption := 'Chinese Language Active OK !';end;procedure TPanasonicGD92.ExitTestModeClick(Sender: TObject); beginExitTestMode.Enabled := False;Step := 30;ResponseArray[Step] := '0080015A';ProcessBar.ForeColor := clRed;ProcessBar.Progress := 0;ComPort.PutChar(#$00);ProcessBar.Progress := 25;ComPort.PutChar(#$80);ProcessBar.Progress := 50;ComPort.PutChar(#$01);ProcessBar.Progress := 75;ComPort.PutChar(#$23);ProcessBar.Progress := 100;while Step = 30 do beginApplication.ProcessMessages;if DoStop then Exit;end;ProcessBar.Progress := 0;ReadInfo.Enabled := False;Chinese.Enabled := False;TestMode.Enabled := True;UserInfo.Caption := 'Phone Exit Test Mode OK !'; TestMode.Caption :='Stop';end;procedure TPanasonicGD92.ReadInfoClick(Sender: TObject);var IMEI92: string;Code92: string;Soft92: string;beginStep := 20;UserInfo.Caption := 'Please Wait ...'; ProcessBar.ForeColor := clBlue; ProcessBar.Progress := 0;ComPort.PutChar(#$00);ProcessBar.Progress := 8;ComPort.PutChar(#$80);ProcessBar.Progress := 15;ComPort.PutChar(#$01);ProcessBar.Progress := 23;ComPort.PutChar(#$98);ProcessBar.Progress := 31;while Step = 20 do begin Application.ProcessMessages;if DoStop then Exit;end;Code92 := Copy(PanaGD9xCode, 10, 1);Code92 := Code92 + Copy(PanaGD9xCode, 12, 1);Code92 := Code92 + Copy(PanaGD9xCode, 14, 1);Code92 := Code92 + Copy(PanaGD9xCode, 16, 1);Code92 := Code92 + Copy(PanaGD9xCode, 18, 1); GD92CODE.Text := Code92; ProcessBar.Progress := 0;UserInfo.Caption := 'Read Phone Code OK !'; Step := 21;ComPort.PutChar(#$00);ProcessBar.Progress := 38;ComPort.PutChar(#$80);ProcessBar.Progress := 46;ComPort.PutChar(#$01);ProcessBar.Progress := 53;ComPort.PutChar(#$90);ProcessBar.Progress := 62;while Step = 21 dobeginApplication.ProcessMessages;if DoStop then Exit;end;IMEI92 := Copy(PanaGD9xIMEI, 10, 1);IMEI92 := IMEI92 + Copy(PanaGD9xIMEI, 12, 1);IMEI92 := IMEI92 + Copy(PanaGD9xIMEI, 14, 1);IMEI92 := IMEI92 + Copy(PanaGD9xIMEI, 16, 1);IMEI92 := IMEI92 + Copy(PanaGD9xIMEI, 18, 1);IMEI92 := IMEI92 + Copy(PanaGD9xIMEI, 20, 1);IMEI92 := IMEI92 + Copy(PanaGD9xIMEI, 22, 1);IMEI92 := IMEI92 + Copy(PanaGD9xIMEI, 24, 1);IMEI92 := IMEI92 + Copy(PanaGD9xIMEI, 26, 1);IMEI92 := IMEI92 + Copy(PanaGD9xIMEI, 28, 1);IMEI92 := IMEI92 + Copy(PanaGD9xIMEI, 30, 1);IMEI92 := IMEI92 + Copy(PanaGD9xIMEI, 32, 1);IMEI92 := IMEI92 + Copy(PanaGD9xIMEI, 34, 1);IMEI92 := IMEI92 + Copy(PanaGD9xIMEI, 36, 1);IMEI92 := IMEI92 + Copy(PanaGD9xIMEI, 38, 1); GD92IMEI.Text := IMEI92; UserInfo.Caption := 'Read Phone IMEI OK !';Step := 22;ComPort.PutChar(#$00);ProcessBar.Progress := 69;ComPort.PutChar(#$80);ProcessBar.Progress := 77;ComPort.PutChar(#$02);ProcessBar.Progress := 85;ComPort.PutChar(#$94);ProcessBar.Progress := 92;ComPort.PutChar(#$00);ProcessBar.Progress := 100;while Step = 22 dobeginApplication.ProcessMessages;if DoStop then Exit;end;Soft92 := 'GAD' + Copy(PanaGD9xSW, 16, 1);Soft92 := Soft92 + Copy(PanaGD9xSW, 18, 1);Soft92 := Soft92 + 'A' + Copy(PanaGD9xSW, 22, 1); Soft92 := Soft92 + Copy(PanaGD9xSW, 24, 1);GD92SW.Text := Soft92;ProcessBar.Progress := 0;UserInfo.Caption := 'Read Phone Info OK !';end;procedure PortTriggerAvail(CP: TObject; Count: word); var ST: string; Rs: string; // I: Integer;begin if Step = 1 then beginProcessBar.Progress := 0;ComPort.PutChar(#$00);ProcessBar.Progress := 25;ComPort.PutChar(#$80);ProcessBar.Progress := 50;ComPort.PutChar(#$01);ProcessBar.Progress := 75;ComPort.PutChar(#$5C);ProcessBar.Progress := 100;end; St := GetCOMData(Count);Rs := ResponseArray[Step];if Step = 20 then beginPanaGD9xCode := St;Rs := St;end;if Step = 21 thenbeginPanaGD9xIMEI := St; Rs := St;end;if Step = 22 then beginPanaGD9xSW := St;Rs := St;end;if Pos(Rs, St) > 0 thenInc(Step);end;end.。

(整理)精通DelphiMSComm串口通信主要属性及事件

(整理)精通DelphiMSComm串口通信主要属性及事件

Delphi MSComm 串口通信Delphi 2009-08-28 11:07:51 阅读214 评论0 字号:大中小用Delphi开发串口通信软件一般有两种方法:一是利用Windows的通信API函数,另一种是采用Microsoft的MSComm控件。

利用API编写串口通信程序较为复杂,需要掌握大量通信知识,其优点是可实现的功能更强大,应用面更广泛,更适合于编写较为复杂的低层次通信程序。

而利用MSComm控件则相对较简单,该控件具有丰富的与串口通信密切相关的属性及事件,提供了对串口的各种操作。

一、MSComm控件的主要属性及事件(1)CommPort:设置或返回串行端口号,缺省为1。

(2)Setting:设置或返回串口通信参数,格式为“波特率,奇偶校验位,数据位,停止位”。

例如:MSComm1.Setting:='9600,n,8,1'(3)PortOpen:打开或关闭串行端口,格式为:MSComm1.PortOpen:={True|False}(4)InBufferSize:设置或返回接收缓冲区的大小,缺省值为1024字节。

(5)InBufferCount:返回接收缓冲区内等待读取的字节数,可通过设置该属性为0来清空接收缓冲区。

(6)RThreshold:该属性为一阀值,它确定当接收缓冲区内的字节个数达到或超过该值后就产生代码为ComEvReceive的OnComm事件。

(7)SThreshold:该属性为一阀值,它确定当发送缓冲区内的字节个数少于该值后就产生代码为ComEvSend的OnComm事件。

(8)InputLen:设置或返回接收缓冲区内用Input读入的字节数,设置该属性为0表示Input读取整个缓冲区的内容。

(9)Input:从接收缓冲区读取一串字符。

(10)OutBufferSize:设置或返回发送缓冲区的大小,缺省值为512字节。

(11)OutBufferCount:返回发送缓冲区内等待发送的字节数,可通过设置该属性为0来清空缓冲区。

delphi串口通讯编程

delphi串口通讯编程

delphi串口通讯编程龚建伟评论:本文对在Delphi中使用ActiveX控件,使用行间汇编,用Delphi调用可执行应用程序三种方法实现串口通信进行了阐述。

不过在Delphi中进行串口编程并不象作者所说的那样令人头疼,我就知道几个很好用的串口程序是用Delphi编写的(我不太会用Delp hi)。

Delphi 是新一代可视化开发工具,它具有功能强大、简便易用和代码执行速度快等特点,D elphi系列开发工具在国际各媒体上曾获得过三十多项大奖,是全球公认的快速应用开发工具技术的先驱者,他越来越在构架企业信息系统方面发挥着重要作用。

它的功能很强大,但在对串口通信的控制上Delphi的帮助文档和其他书籍中很少提及,可这是在开发应用系统时会经常遇到却又令人头痛的事情。

下面介绍三种解决方案,以实现接收和发送数据的功能。

一、使用ActiveX控件由于Delphi中没有串口控件可用,所以首先需要把ActiveX控件MSCOMM加到元件选项板上。

这是一个非常好的控件它不仅能对串口进行操作,而且还可以对Modem进行控制。

下面结合一个具体的实例来说明如何用MSCOMM控件开发出串口通信程序。

创建一个Communication.dpr工程,把窗体的Name属性变为CommForm,将标题改为T he Communication Test,选择File/Save As将新的窗体存储为CommFrm.pas,接下来参照图1和图2将控件添加到主窗体中。

图1 图2由图1和图2我们可以看出,通过设置页可选定进行数据传输的通信端口和端口的波特率、奇偶校验、数据位和停止位,通信时每传输一个字符都将触发响应事件,在通信页“传输显示”位置可看到当前正在进行传输的数据。

同时当出现回车换行符时将整行内容显示在me mDisplay新的一行中,而全部接收的内容还将存在一个文件中。

部分源代码如下:变量说明varCommForm: TCommForm;ss :string;savef,readf :file of char;i,j :longint;初始化procedure TCommForm.FormCreate(Sender: TObject);beginmport:=1;mscomm.settings:='9600,n,8,1';mscomm.inputlen:=1;mscomm.inbuffercount:=0;mscomm.portopen:=true;ss:='';i:=0;j:=0;assignfile(savef,'save1');rewrite(savef);assignfile(readf,'read1');reset(readf);end;设置确定procedure TCommForm.btnConfirmClick(Sender: TObject); beginif mscomm.portopen thenmscomm.portopen:=false;mport:=strtoint(edtCommport.text); mscomm.settings:=edtCommsetting.Text;end;传输事件procedure TCommForm.MSCommComm(Sender: TObject); varfilenrc :char;buffer :variant;s1:string;c :char;begincase mEvent ofcomEvSend:beginwhile not(eof(readf)) dobeginread(readf,filenrc);mscomm.output:=filenrc;j:=j+1;lblDisplay.caption:=inttostr(j);if mscomm.outbuffercount>=2 thenbreak;end;end;comEvReceive:beginbuffer:=mscomm.Input;s1:=buffer;c:=s1[1];ss:=ss+c;i:=i+1;lblDisplay.caption:=c+inttostr(i);write(savef,c);if (c=chr(10))or(c=chr(13)) thenbeginlblDisplay.caption:='cr'+inttostr(i);memDisplay.lines.add(ss);ss:='';end;end;end;end;当然还有许多串口控制的ActiveX控件,有控件用是方便,但是是否说没有控件就不能用D elphi本身解决问题呢。

Delphi串口通信的实现

Delphi串口通信的实现

Delphi中串口通信的实现Delphi是一种具有功能强大、简便易用和代码执行速度快等优点的可视化快速应用开发工具,它在构架企业信息系统方面发挥着越来越重要的作用,许多程序员愿意选择Delphi作为开发工具编制各种应用程序。

但是,美中不足之处是 Delphi没有自带的串口通信控件,在它的帮助文档里也没有提及串口通信,这就给编制通信程序的开发人员带来许多不便。

目前,利用 Delphi实现串口通信的常用的方法有3种:一是利用控件,如MSCOMM控件和 SPCOMM控件;二是使用 API函数;三是调用其他串口通信程序。

其中利用 API编写串口通信程序较为复杂,需要掌握大量的通信知识。

相比较而言,利用 SPCOMM控件则相对较简单,并且该控件具有丰富的与串口通信密切相关的属性及事件,提供了对串口的各种操作,而且还支持多线程。

下面本文结合实例详细介绍SPCOMM控件的使用。

SPCOMM的安装1.选择下拉菜单 Component中的 Install Component选项,在 Unit file name处填写SPCOMM控件所在的路径,其他各项可用默认值,点击 OK按钮。

2.安装后,在 System控件面板中将出现一个红色控件 COM。

现在就可以像 Delphi 自带控件一样使用 COM控件了。

SPCOMM的属性、方法和事件1.属性●CommName:表示 COM1、 COM2等串口的名字;●BaudRate:根据实际需要设定的波特率,在串口打开后也可更改此值,实际波特率随之更改;●ParityCheck:表示是否需要奇偶校验;●ByteSize:根据实际情况设定的字节长度;●Parity:奇偶校验位;●StopBits:停止位;●SendDataEmpty:这是一个布尔型属性,为 true时表示发送缓存为空,或者发送队列里没有信息;为 false时表示发送缓存不为空,或者发送队列里有信息。

2.方法●Startcomm方法用于打开串口,当打开失败时通常会报错。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Delphi中ComPort通信中的数据处理1.串口通信的基本原理:一般计算机与外部设备通讯有两种方式:并行传送(Parallel ):一次的传输量为8个位(1字节),通过并行端口,如打印机串行传送(Serial ):一次只传输1个位,通过串行端口,如RS-232位与字节的概念:二进制中的每一位0和1,被叫做一个位,每8个位构成一个字节一个字节中最右面的位被称为第0位,最左面的位被称为第7位。

传输过程中的字节类型:一般有两种。

1.文本(字符字母、标点符号等)在计算机中存储时,每个不同的字符都用不同的数值来表示。

这些数值的范围通常在0-127或0-255范围。

7位:ASCII码,每个字节留一个备用位8位:前128个遵循ASCII码规则,其余的128个用来做扩展字符、数字符号、图形字符等编码。

2.二进制数据:某些可执行指令文件和图形图像文件就是以二进制形式而不是ASCII码形式存储的。

一个数据可用二进制形式存储,可以占多个字节。

在通信领域,常常把这种类型的资料叫做二进制数据。

今天要讲的就是有关二进制数据的处理方法。

几个概念:波特率:每秒所能产生的最大电压状态改变率(一秒钟可以振荡的次数)bps 通信双方必须要取得一样的通信速度。

原始信号经过不一样的波特率取样后,所得的结果完全不一样,如取样速度只有原来一半时,信号被跳着取样,数据因此错误。

数据位:有5,6,7,8四种停止位:在奇偶位(选择有奇偶校验)或数据位(选择无奇偶校验)之后发送或接收的停止位。

停止位的长度可在1、1.5或2位三者中选择)。

奇偶校验位:数据传输之后是可供选择的奇偶校验位发送和接收。

奇偶位的状态取决于选择的奇偶校验类型。

如果选择奇校验,则该字符数据中为1的位数与校验位相加,结果应为奇数。

可选奇,偶或无。

如果要保证通讯畅通。

通讯双方以上4项设置必须一致。

一个字节是8位,数据位可以7位,然后一位校验位就8位了。

这些参数可以自己设置。

但是如果要保证通讯畅通。

通讯双方以上4项设置必须一致。

2.Delphi中串口通信常用的常用控件进行串口通讯可以用Windows的Api函数:Delphi的Windows.pas单元文件中已经将Win32 API均声明进去,因此在Delphi 里面使用API时只要在uses 区段中加入Windows,使其引用该单元文件即可。

串行通信相关函数:CreateFile:建立文件,在此用打开通信端口CloseHandle:关闭由CreateFile建立的文件,在此用于关闭通信端口GetCommState:取得计算机串口的设置参数SetCommState:设置计算机串口的参数WriteFile:将数据写入文件,在此用来将数据由串口送出ReadFile:由文件中读取数据,在此用来取得送到串口的数据ClearCommError:清除串行端口的错误,并取得信息PurgeComm:清除串口上的缓冲区EscapeCommFunction:控制串口的硬件状态SetCommMask:设置事件的掩码,用以触发事件WaitCommEvent:等待设置事件的发生GetCommModemStatus:取得串口上的硬件线路状态这里不推荐使用Windows API函数。

虽然用API函数可以实现很强大很灵活的功能,但是势必要花更多的时间和精力在通讯细节上。

而Delphi的是RAD的经典代表,当然会有更简单的方法,那就是使用封装好的控件。

较常用的控件有spcomm,mscomm,comport,apro等。

其中mscomm是ActiveX 控件,另外3个控件都是Delphi控件,自带源码,可以到delphi盒子,Delphi 园地,sourceforge等网站下载。

具体使用方法这里不详细介绍。

3.数据帧的概念今天我们主要讲的是二进制数据的处理,所以先介绍下数据帧的概念。

我们要进行数据通讯,那么通讯双方必须遵循一定的协议,这样,通讯双方才能够相互理解从对方所接收过来的数据。

帧是传送信息的基本单元,每帧由帧起始符标志域,控制域,数据长度域,数据域,帧信息纵向校验域及帧结束域等6个域组成。

每个域由若干字节组成。

比如有这样一个帧格式:代码字节数说明68H 1 帧起始符RTUA 4 终端逻辑地址MSTA 2 主站地址与命令序号68H 1 帧起始符C 1 控制码L 2 数据长度DATA 变长数据域CS 1 校验码16H 1 结束码从这个数据帧格式可以看出,一个数据帧至少有13个字节。

而且前后中间都有规定。

这样我们就可以通过处理分析其中的某些字节来判断这一个数据帧的意义,来进行其他相关的工作。

当然不同的系统数据帧格式会有不同。

我们今天就用这个格式作例子。

4.数据的接收与发送今天我只介绍下使用Comport控件接收和发送数据。

接收数据:在OnRxChar事件中。

onRxChar的原型:procedur PortRxChar(Sender: TObject; Count: Integer)这个事件当接收缓冲区中有数据时触发,count为缓冲区中的字节数。

发送数据:发送数据本控件提供了6个函数:WaitForAsyncWaitForEventWriteWriteAsyncWriteStrWriteStrAsync较常使用的是WriteStr。

function WriteStr(const Str: String): Integer;参数为字符串类型,返回实际发送的字节数。

apro功能很强大,而且开发这个控件组的公司已经倒闭,贡献了所有的源代码。

除了mscomm以外,另外3个都有源代码。

为什么用WriteStr,这里要解释下string类型。

Delphi的String类型非常强大,可以兼容PChar,Array of Char,WideString 等字符串或字符数组类型。

还有一个很关键的作用是可以作为动态Byte数组来使用。

虽然很多参考书上没有介绍这种用法,但是经过我多次测试以及实践经验,发现没有出现任何不良反应。

比如你要发送$68 80 50 60 20 30 10 00 00 20这几个字符,可以定义一个字符串A:string;然后用下面的代码:setlength(A,10);A[1]:=Chr(68);A[2]:=Chr(80);。

A[9]:=Chr(00)A[10]:=Chr(20)writestr(A);当然看起来很烦琐,其实这不是String的优势所在。

它真正的优势在于1.无须管理内存,交给Delphi来管理。

2.可以很方便的作为参数或者变量来进行处理。

后面讲。

5.数据的处理前面讲了4节,都是废话。

重点在这一节。

如果从终端不断的发送数据到服务器上来,例如每隔10毫秒发送一帧数据,我们如何区分这些数据呢?要知道,串口通讯是一位一位来传送的,接收则是一个字节一个字节来接收的,不是一帧一帧来接收的。

为了要判断一个字节是前一帧的数据还是后一帧的数据,我们也只能一个字节一个字节的判断。

先看一段代码,然后我再解释这段代码。

这样我们就可以明确地获取每一帧的数据了。

讲完这个之后,我再解释如何利用Delphi的面向对象特性来处理收到的这一帧数据。

帧格式就用刚才介绍的那个格式。

先定义几个全局变量:FDataStatus:Word; //0 就绪 1.帧头1 2.帧头2FNextLength:Word; //接下来要读的长度FCurrentLength:Word; //当前的长度FtmpStr:string;//一帧数据代码如下:procedure ComPortRxChar(Sender: TObject; Count: Integer);varS1:string;J:Integer;begincase FDataStatus of0:beginJ:=0;FtmpStr:='';repeatComPort.ReadStr(S1,1);J:=J+1;until (Ord(S1[1])=$68) or (J=Count);if Ord(S1[1])=$68 thenbeginFtmpStr:=S1;FDataStatus:=1;FNextLength:=10;FCurrentLength:=0;end;end;1:beginJ:=FCurrentLength;repeatComPort.ReadStr(S1,1);FtmpStr:=FtmpStr+S1;FCurrentLength:=FCurrentLength+1;until (FCurrentLength=FNextLength) or(FCurrentLength-J=Count);if FCurrentLength=FNextLength thenbeginFDataStatus:=2;FNextLength:=(Ord(FtmpStr[11]) shl 8) +Ord(FTmpStr[10])+2;FCurrentLength:=0;end;end;2:beginJ:=FCurrentLength;repeatComPort.ReadStr(S1,1);FtmpStr:=FtmpStr+S1;FCurrentLength:=FCurrentLength+1;until (FCurrentLength=FNextLength) or(FCurrentLength-J=Count);if FCurrentLength=FNextLength thenbeginFDataStatus:=0;FNextLength:=0;FCurrentLength:=0;FReceiveFrame.Str:=FtmpStr;SendMessage(CommServer.Handle,XM_OutData,0,LongWord(@F ReceiveFrame));end;end;end;end;case FDataStatus of判断目前接收的数据段。

0:beginJ:=0;FtmpStr:='';repeatComPort.ReadStr(S1,1);J:=J+1;until (Ord(S1[1])=$68) or (J=Count);if Ord(S1[1])=$68 thenbeginFtmpStr:=S1;FDataStatus:=1;FNextLength:=10;FCurrentLength:=0;end;end;如果是一帧开始,那么就对相关参数进行初始化,数据帧初始化为空。

J:=0;FtmpStr:='';然后开始读,直到读到帧起始符$68或者读完为止,没有的话,就抛弃读到的数据(当然你也可以另外记下来,不过意义不大)。

相关文档
最新文档