DELPHI 串口通讯编程 SPCOMM

来源:互联网 发布:军用gps定位软件 编辑:程序博客网 时间:2024/05/18 21:43

最近接触到串口通信,遇到了很多问题,在网上也查了很多,最终实现了,总结一下要点,以备后用

1.属性

●CommName:表示   COM1、   COM2等串口的名字;

●BaudRate:根据实际需要设定的波特率,在串口打开后也可更改此值,实际波特率随之更改;

●ParityCheck:表示是否需要奇偶校验;

●ByteSize:根据实际情况设定的字节长度;

●Parity:奇偶校验位;

●StopBits:停止位;   

●SendDataEmpty:这是一个布尔型属性,为 true时表示发送缓存为空,或者发送队列里没有信息;为false时表示发送缓存不为空,或者发送队列里有信息。 

2.方法

●Startcomm 用于打开串口

●StopComm 用于关闭串口

 3.事件       

ReceiveData(Sender: TObject; Buffer: Pointer;BufferLength: Word);      当有数据输入缓存时将触发该事件,在这里可以对从串口收到的数据进行处理。   Buffer中是收到的数据,   BufferLength是收到的数据长度。   

编程中问题的解决方法:

1.如何查看端口是否打开:

 总结网上的几个方法,最终选择了句柄判断。

//检测端口是否打开function  TForm1.IsOpened(Comm: TComm):Boolean;begin  if comm1.Handle >0 then     Result:=true  else     Result:=false;end;

2.发送事件: 

procedure TForm1.SendString(const str: string);begin  Comm1.WriteCommData(Pchar(str),Length(str))    //发送数据end;

调用发送    

SendString(HexStrToStr('$01'));

 //16进制字符串转换成字符串

 function HexStrToStr(const S:string):string;var  t:Integer;  ts:string;  M,Code:Integer;begin  t:=1;  Result:='';  while t<=Length(S) do  begin                                  while (t<=Length(S)) and (not (S[t] in ['0'..'9','A'..'F','a'..'f'])) do      inc(t);    if (t+1>Length(S))or(not (S[t+1] in ['0'..'9','A'..'F','a'..'f'])) then      ts:='$'+S[t]    else      ts:='$'+S[t]+S[t+1];    Val(ts,M,Code);    if Code=0 then      Result:=Result+Chr(M);    inc(t,2);  end;end;

 

//字符串转换成16进制字符串function StrToHexStr(const S:string):string;var  I:Integer;begin  for I:=1 to Length(S) do  begin    if I=1 then      Result:=IntToHex(Ord(S[1]),2)    else Result:=Result+' '+IntToHex(Ord(S[I]),2);  end;end;

4.最简单的校验方式

//校验函数   正确返回 true 错误返回falsefunction CheckCode(str: string):Boolean;var   s:Integer;   p: string;begin      s:= StrToInt('$'+StrToHexStr(copy(str,2,1))) xor StrToInt('$'+StrToHexStr(copy(str,3,1)))      xor StrToInt('$'+StrToHexStr(copy(str,4,1))) xor StrToInt('$'+StrToHexStr(copy(str,5,1)))      xor StrToInt('$'+StrToHexStr(copy(str,6,1))) xor StrToInt('$'+StrToHexStr(copy(str,7,1)))      xor StrToInt('$'+StrToHexStr(copy(str,8,1))) xor StrToInt('$'+StrToHexStr(copy(str,9,1)));   p:=StrToHexStr(copy(str,10,1));       if IntToHex(s,1)=p then          Result:=true        else          Result:=false;end;

5.最重要的接收事件

procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;BufferLength: Word);var  str : string;begin       SetLength(Str,BufferLength);       move(buffer^,pchar(@Str[1])^,BufferLength);         ...  ...end;

 

ReadIntervalTimeOut是个重要属性:用来设置SPCOMM间隔多长时间触发onReciveData事件,单位为ms。只要任何两个字节到达的时间间隔小于1OOms,都被认为是属于同一帧数据.