控制工程师论坛

现场总线

MODBUS驱动设计与实现

wj321
wj321

2008-10-31

控件安装完后在DELPHI里调用此控件,打开源代码可直接修改,支持DELPHI5、6、7

 初始化属性

constructor TModbusM.Create( AOwner: TComponent );
begin
  inherited Create( AOwner );
  // Initialize to default values
  FComPortHandle             := 0;       // Not connected
  FComPort                   := pnCOM2;  // COM 2
  FComPortBaudRate           := br9600;  // 9600 bauds
  FComPortDataBits           := db8BITS; // 8 data bits
  FComPortStopBits           := sb1BITS; // 1 stop bit
  FComPortParity             := ptNONE;  // no parity
  FComPortHwHandshaking      := hhNONE;  // no hardware handshaking
  FComPortSwHandshaking      := shNONE;  // no software handshaking
  FComPortInBufSize          := 1028;    // input buffer of 1024 bytes
  FComPortOutBufSize         := 1028;    // output buffer of 1024 bytes
  FComPortPollingDelay       := 80;    // poll COM port every 80ms
  FOutputTimeout             := 5000;    // output timeout - 5000ms
  FEnableDTROnOpen           := false;   // DTR high on connect
  // Temporary buffer for received data
  ......
  ......
end;

//MODBUS发送
procedure TModbusM.Query;
var
  CadenaCRC: word;
  Cadena: TDataByte;
  PCadena: PByte;
  LCadena,i: Integer;
  ByteTemp: Byte;
begin
  if not connected then begin
    FError:=11;
    if Assigned(FOnError) then FOnError(Self, SErrorCodes[11] );
    Exit;
  end;
  if FBusy then begin
    FError:=10;
    if Assigned(FOnError) then FOnError(self, SErrorCodes[11]);
    exit;
  end;

  FBusy:=True;
  FError:=0;
  SetLength(ReadBuffer, 0);


  //功能码1数据打包,依次累推可增加自己所需的其它功能码
  case FFunction of
  1: begin
       Setlength(Cadena,8);
       Cadena[0]:=FslaveId;
       Cadena[1]:=FFunction;
       Cadena[2]:=Hi(Foffset);
       Cadena[3]:=Lo(Foffset);
       Cadena[4]:=Hi(Fquantity);
       Cadena[5]:=Lo(Fquantity);
       CadenaCRC:=CRC(Cadena);
       Cadena[high(Cadena)-1]:=lo(CadenaCRC);
       Cadena[high(Cadena)]:=hi(CadenaCRC);
       PCadena:=@Cadena[0];
       LCadena:=High(Cadena)+1;
       if SendData(PCadena,LCadena)=LCadena
         then FTimer.Enabled:=True
         else begin
           FError:=9;
           if Assigned(FOnError) then FOnError(Self, SErrorCodes[FError]);
           FBusy:=False;
         end;
     end;
  ......
  ......
end;


//MODBUS接收
procedure TModbusM.Response( Sender: TObject; DataPtr: pointer; DataSize: integer );
var
  CadenaCRC: Word;
  PCadena: PByte;
  i, LCadena : Integer;
  ByteTemp: Byte;

begin

  FTimer.Enabled:=False;  //定时器停止

  PCadena:=DataPtr;
  LCadena:=DataSize;

  //SetLength(Cadena, Legth(Cadena)+LCadena);
  //Setlength(Cadena,  LCadena);

  for i:=0 to LCadena-1 do
  begin
    SetLength(ReadBuffer, Length(ReadBuffer)+1 );
    ReadBuffer[Length(ReadBuffer)-1]:=PCadena^;
    inc(PCadena);
  end;

  CadenaCRC:=CRC(ReadBuffer);
  if (Lo(CadenaCRC)<>ReadBuffer[high(ReadBuffer)-1]) or (Hi(CadenaCRC)<>ReadBuffer[high(ReadBuffer)]) then
  begin
    FError:=9;
    if Assigned(FOnError) then FOnError(Self, SErrorCodes[FError]);;
    FBusy:=False;
    Exit;
  end;
  //功能码1解析,依次累推可增加自己所需的其它功能码
  case ReadBuffer[1] of
  1: begin
       if Fquantity Mod 8>0 then
         ByteTemp:=(FQuantity div 8)+1
       else ByteTemp:=Fquantity div 8;
       if length(ReadBuffer)= ByteTemp+5 then
         begin
           SetLength(FReadValues, ReadBuffer[2]);
           for i:=0 to ReadBuffer[2]-1 do
           FReadValues[i]:=ReadBuffer[3+i];
         end
       else begin
         FError:= 4;
         if Assigned(FOnError) then FOnError(Self, SErrorCodes[FError]);;
         FBusy:=False;
         exit;
       end;
     end;
  ......
  ......
end;

回帖

评论1

总共 , 当前 /
首页 | 登录 | 注册 | 返回顶部↑
手机版 | 电脑版
版权所有 Copyright(C) 2016 CE China