delphi---spcomm

Spcomm共实现了三个类:串口类Tcomm、读线程类TreadThread以及写线程类TwziteThread[1]。Tcomm的某个实例在方法StartComm中打开串口,并实例化了一个读线程ReadThread和一个写线程WriteThread,它们和主线程之间进行消息的传递,实现串口通信。

3.1 Spcomm控件的基本属性、方法和事件
Spcomm串口通信控件的基本属性、方法和事件说明如下:
CommName属性:计算机串口端口号的名字,COM1、COM2……等,在打开串口前,必须填写好此值。
Parity属性:校验位 None、Odd、Even、Mark、Space等。
BaudRate:设定支持串口通信用的波特率9600,4800等,根据实际需要来定,在串口打开后也可更改波特率,实际波特率随之更改。
ByteSize属性:表示一个字节中,使用多少个数据位收发数据,根据具体情况设定5、6、7、8等。
StopBits属性:表示一个字节中,使用停止位的位数,根据具体情况设定1、1.5、2等。
SendDataEmpty属性:布尔属性,为True时表示发送缓存为空,或者发送队列里没有信息;为False时表示表示发送缓存不为空,或者发送队列里有信息。
StartComm方法:用来打开通信串口,开始通信。如果失败,则会导致串行口错误。错误类型大致分为串行口己处于打开状态,所以不能打开串行口,不能创建读写进程,不能建立串行口缓冲区等。
StopComm方法:用来停止通信串行口的所有进程,关闭串口。
WriteCommData
(pDataToWriteChar;dwSizeofDataToWrite:Word)方法是带有布尔型返回值的函数,其中参量pszStr-ingToWrite是要写入串行口的字符串,DwSizeaf- DataToWrite是要写入的字符串的长度。该函数通过一个写线程向串行口输出缓冲区发送数据。发送操作将在后台默认执行。如果写线程PostMessage成功,则返回值是True,若写线程失败,返回值是False。
OnReceiveData(Bufferointer;BufferLength:Word),其中Buffer是指向输入缓冲区的指针。BufferLength是从缓冲区收到的数据长度。当输入缓冲区收到数据时,该事件被触发。当输入缓存有数据时将触发该事件,对从串口收到的数据进行处理。

3.2 Spcomm串口通信的实现
Spcomm串行通信控件具有多线程的特性,接收和发送数据分别在两个线程内完成,接收线程负责收到数据时触发OnReceiveData事件;用WriteCommData()函数将待发送的数据写入输出缓冲器,发送线程在后台完成数据发送工作。在接收和发送数据前需要初始化串口,用StartComm方法打开串口,退出程序时用StopComm方法关闭串口。
实现PC机与单片机之间的数据发送及接收需要以下步骤:
(1)初始化并打开串口

需要选择本次通信使用的串口,确定通信协议,即设置波特率、校验方式、数据位、停止位等属性,打开该串口。示例代码如下:

//初始化并打开串口
Comm1.BaudRate:=9600;//波特率9600bps
Comm1.Parity:=None;//奇偶检验无
Comm1.ByteSize:=8;//数据位8
Comm1.StopBits:=1;//停止位1
Comm1.StartComm; //打开串口

(2)建立握手信号
实现PC机与单片机之间的通信,首先要调通它们之间的握手信号,握手信号可以随意选择某特定字符串, 当PC发出这样一帧数据后,通过接收事件能收到单片机返回的这一帧数据或特定的某字符串,则表示握手成功,系统通信正常。两者之间就可以按照协议相互传输数据。否则需重新建立握手信号。
(3)发送数据
在编写基于串口的计算机工业测控时,通常需要由PC机向下位机发送命令以控制下位机的行为,同时向下位机发送有关数据。利用Spcomm串口控件向下位机发送数据示例代码如下:

//发送数据和控制字程序
procedure senddata;
	var
	i:integer; commflg : Boolean;
begin
	commflg:=true ;
	for i:=1 to 8 do
	begin
	if not fcomm comml writecommdata(sendbutter,i) then
		begin
		Commflg=false;
		break;
		end;
	end;
end;

(4) 接收数据
在编写基于串口的计算机工业测控时,通常需要由下位机向PC机发送数据以使PC机了解系统的测试数据或下位机的运行状态,并进而控制下位机的行为。利用Spcomm串口控件接收下位机发送的数据信息的示例代码如下:

//事件驱动方式接收数据程序
procedure TForm1.CommlReceiveData(Sender:Tobject;
Bufferointer; bufferLength:Word);
var
receivedata:array of byte;
begin
sleep(100);//等待100ms,保证接收到所有数据
move(buffef ,receivedata,bufferlength);
//将接收缓存区中的数据转移到数组中
……
end;

(5) 关闭串口
在系统开发中,应注意在不使用串口时应及时关闭串口,释放系统资源,否则可能会影响系统的其它应用。关闭串口的代码如下:

procedure TForm1.FormClose ( Sender;TObj ect:var Action:TCIoseAction );
begin
comml.StopComm ;
end;

4 Spcomm串口通信的关键技术问题
Spcomm应用的核心在于主线程、读线程和写线程之间的消息传递机制,而通信数据相关信息的传递也是以消息传递的方式进行的。在使用Spcomm进行串口通信编程,除按照说明使用外,还需要特别注意以下两个问题。
首先,Spcomm是通过ReadIntervalTimeout属性的设置,来确定所接收到的数据是否属子同一帧数据,其默认值是100ms,也就是说,只要任何两个字节到达的时间间隔小于1OOms,都被认为是属于同一帧数据,在与单片机协同工作时,要特别注意这个问题[2]。
另外,Spcomm的默认属性设置是支持软件流控制的,用于流控制的字符是13H(XoffChar)和11H(XonChar),当单片机以二进制方式发送数据时,必须要禁用Spcomm对于软件流控制的支持,否则,在数据帧中出现的13H,11H会被Spcomm作为控制字符而加以忽略。
3.1 串口调试助手的概要设计
端口初始化就是对波特率、校验、数据位和停止位的设置。当端口打开时指示灯为绿色,当端口为打开时指示灯为红色。
当接收数据后对数据进行变换时,要先判断接收的数据是否符合变换的条件,例如当以十进制显示时,接收的数据不是十六进制数就会报错。
发送数据之前必须保证串口打开,所以先判断端口有没有打开。由于发送空内容没有意义,所以还要保证发送内容不能为空。
自动发送当选中CheckAutosend时,串口调试助手以设置好的时间间隔发送数据。

procedure TForm1.Button2Click(Sender: TObject);
var
   i ,j,TextLen: Integer;
   //aucBuf : array[0..4096] of byte;
   SendBuf : string;
   strbuf : string;
begin
     strbuf :=Memo2.text;
     sendbuf := '';
     if HexSendFlag = True then
     begin
          strbuf := StringReplace(strbuf, #10, '', [rfReplaceAll]);
          strbuf := StringReplace(strbuf, #13, '', [rfReplaceAll]);
          strbuf := StringReplace(strbuf, ' ', '', [rfReplaceAll]);
          strbuf := StringReplace(strbuf, #9, '', [rfReplaceAll]);
          TextLen := Length(strbuf);
          i:=1;
          while (i <= TextLen) and (strbuf[i] in ['0'..'9','A'..'F','a'..'f']) do
                inc(i);
          if i <= TextLen then
          begin
               ShowMessage('非法的十六进制数');
               Exit;
          end;
          if TextLen > 0 then
          begin
              for j:=0 to (TextLen div 2 - 1) do
              begin
                  //aucBuf[j] := Byte(StrToIntDef('$' + strbuf[2*j + 1] + strbuf[2*j + 2], 0));
                  SendBuf := SendBuf + Char(StrToIntDef('$' + strbuf[2*j + 1] + strbuf[2*j + 2], 0));
              end;
              if TextLen mod 2 <> 0 then
              begin
                   //aucBuf[j] := Byte(StrToIntDef('$0'+ strbuf[2*j + 1], 0));
                   SendBuf := SendBuf + Char(StrToIntDef('$0'+ strbuf[2*j + 1], 0));
              end;
              //comm1.writecommdata(@aucBuf, TextLen div 2 + textLen mod 2);
              comm1.writecommdata(pchar(SendBuf), TextLen div 2 + textLen mod 2);
              //ShowMessage(IntToStr(TextLen div 2 + TextLen mod 2));
              SendLen := SendLen + TextLen div 2 + textLen mod 2;
          end;
     end
     else
     begin
         if Length(Memo2.Text) > 0 then
         begin
              comm1.writecommdata(pchar(strbuf), Length(Memo2.Text));
         end;
         if CheckBox6.Checked = true then
         begin
              strbuf := #13;
              comm1.writecommdata(pchar(strbuf), 1);
              SendLen := SendLen + 1;
         end;
         if CheckBox7.Checked = true then
         begin
              strbuf := #10;
              comm1.writecommdata(pchar(strbuf), 1);
              SendLen := SendLen + 1;
         end;
         SendLen := SendLen + Length(Memo2.Text);
     end;
     StatusBar1.Panels[0].Text := 'S:' + IntToStr(SendLen);
end;




j:=trunc((length(s1)/2))-1;
  for i:=0 to j do
  //s2:= s2+char(strtoint('$'+(copy(s1,2*i+1,2))));
  s3[i]:=char(strtoint('$'+(copy(s1,2*i+1,2))));
  comm1.writecommdata(s3,trunc((length(s1)/2)));



procedure sendhex(s:string);
var
  i,j,TextLen:integer;
  sendbuf,strbuf:string;
  p:pchar;
begin
  strbuf:='';
  sendbuf:= '';
  for i:=1 to length(s) do
    begin
      if ((copy(s,i,1)>='0') and (copy(s,i,1)<='9'))or((copy(s,i,1)>='a') and (copy(s,i,1)<='f'))or((copy(s,i,1)>='A') and (copy(s,i,1)<='F')) then
         begin
           strbuf:=strbuf+copy(s,i,1);
         end;
    end;
  showmessage(strbuf);
  TextLen:= Length(strbuf);
  showmessage(inttostr(TextLen));
  p:=pchar(strbuf);
  showmessage(p);
  try
  comm1.writecommdata(p,TextLen-1);
  except
    exit;
  end;
  if TextLen > 0 then
          begin
              for j:=0 to (TextLen div 2 - 1) do
              begin
                  //aucBuf[j] := Byte(StrToIntDef('$' + strbuf[2*j + 1] + strbuf[2*j + 2], 0));
                  SendBuf:= SendBuf + Char(StrToIntDef('$' + strbuf[2*j + 1] + strbuf[2*j + 2], 0));
              end;
              if TextLen mod 2 <> 0 then
              begin
                   //aucBuf[j] := Byte(StrToIntDef('$0'+ strbuf[2*j + 1], 0));
                   SendBuf:= SendBuf + Char(StrToIntDef('$0'+ strbuf[2*j + 1], 0));
              end;
              showmessage(SendBuf);
              //comm1.writecommdata(@aucBuf, TextLen div 2 + textLen mod 2);
       //       comm1.writecommdata(pchar(SendBuf), TextLen div 2 + textLen mod 2);
              //ShowMessage(IntToStr(TextLen div 2 + TextLen mod 2));
              //SendLen := SendLen + TextLen div 2 + textLen mod 2;
          end;

SPCOMM的主要属性,方法和事件 1.属性 CommName:填写COM1,COM2…等串口的名字,在打开串口前,必须填写好此值。 BaudRate:设定波特率9600,4800等,根据实际需要来定,在串口打开后也可更改波特率,实际波特率随之更改。 ParityCheck:奇偶校验。 ByteSize:字节长度_5,_6,_7,_8等,根据实际情况设定。 Parity:奇偶校验位 pBits:停止位 SendDataEmpty:这是一个布尔属性,为true时表示发送缓存为空,或者发送队列里没有信息;为False时表示表示发送缓存不为空,或者发送队列里有信息。 2.方法 Startcomm过程用于打开串口,当打开失败时通常会报错,错误主要有7种: ⑴串口已经打开 ; ⑵打开串口错误 ; ⑶文件句柄不是通讯句柄; ⑷不能够安装通讯缓存; ⑸不能产生事件 ; ⑹不能产生读进程; ⑺不能产生写进程; StopComm过程用于关闭串口,没有返回值。 函数WriteCommData(pDataToWrite: PChar;dwSizeofDataToWrite:Word ): boolean 用于发送一个字符串到写线程,发送成功返回true,发送失败返回false, 执行此函数将立即得到返回值,发送操作随后执行。函数有两个参数,其中 pdatatowrite是要发送的字符串,dwsizeofdatatowrite 是发送的长度。 3.事件 OnReceiveData : procedure (Sender: TObject;Buffer: Pointer;BufferLength: Word) of object 当输入缓存有数据时将触发该事件,在这里可以对从串口收到的数据进行处理。Buffer中是收到的数据,bufferlength是收到的数据长度。 OnReceiveError : procedure(Sender: TObject; EventMask : DWORD) 当接受数据时出现错误将触发该事件。
Delphi spcomm是一个非常常用的串口通信组件,用于在Delphi开发环境中实现串口通信功能。以下是Delphi spcomm的安装方法: 1. 首先,下载最新版本的Delphi spcomm组件文件,一般以.dcu、.pas或.dpk为扩展名。 2. 将下载的组件文件复制到Delphi安装目录的Lib文件夹中,一般路径为C:\Program Files (x86)\Embarcadero\Studio\version\Lib。 3. 打开Delphi IDE,在菜单栏选择"Component",然后选择"Install Component"。 4. 在打开的对话框中,选择"Into new package"选项,然后点击"OK"。 5. 在下一个对话框中,输入一个名称和路径来创建一个新的包,并点击"OK"。 6. 在包编辑器中,点击"File",选择"Open...",找到刚刚创建的包文件并打开。 7. 在包编辑器中,点击"Component",然后选择"Install Packages"。 8. 在打开的对话框中,点击"Add...",选择之前复制的组件文件,然后点击"Open"。 9. 确保组件文件已被添加到列表中,并点击"OK"。 10. 返回Delphi IDE的主界面,打开"Component"菜单,选择"Install Component",然后在出现的对话框中,点击"OK"。 11. 在出现的对话框中,选择你想要安装的组件,然后点击"OK"。 12. 安装完成后,Delphi IDE会自动加载并注册spcomm组件。 13. 现在你可以在Delphi中使用spcomm组件了,可以在"Component"菜单的"spcomm"子菜单中找到相关的组件。 以上就是Delphi spcomm组件的安装方法。希望对你有所帮助!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值