松下快球控制,RS485串口通讯,发出去的数据石沉大海:((,郁闷中。有谁做过,提供点资料参考参考,200分拱手送上!!!!!!!!!!!!!!!!!!!!

解决方案 »

  1.   

    to chenquan(嘉威王子) 
    不需要源码,能告诉我串口发出的数据结构说明吗?举个简单的例子就可以了。
      

  2.   

    unit un_ProtocolLayer;interfaceuses
      Variants;type
      TProtocolLayer = class
      public
        procedure CreateFrame(nAddr, nKind: Integer; data: Variant;var adata: Variant);
        procedure DetachFrame(var nAddr, nKind: Integer; InData: Variant; var
          OutData: Variant);
      end;implementationuses un_Public;//------------------------------------------------------------------------------
    //名称: CreateFrame
    //参数: nAddr--地址;nKind--帧类型;data --数据
    //功能: 根据地址和数据形成一帧
    //说明: 序列号和帧校验和没有生成
    //
    //------------------------------------------------------------------------------procedure TProtocolLayer.CreateFrame(nAddr, nKind: Integer; data: Variant;var adata:variant);var
      //varRes            : Variant;
      nLength, i        : Integer;
      aHigh, aLow,hsum,fsum      : Byte;
    begin
      nLength := VarArrayHighBound(data,1)+ 10;
      adata := varArrayCreate([0,nLength+7], varByte);
      //帧头
      adata[0] := $FF;
      adata[1] := $A5;
      DetachWord(nAddr, aHigh, aLow);
      adata[2] := aLow;                    //地址
      adata[3] := aHigh;
      DetachWord(nLength, aHigh, aLow);
      adata[4] := aLow;                    //帧长度
      adata[5] := aHigh;
      adata[6] := 0;                       //序列号
      hsum:=0;
      for i:=0 to 6 do
          hsum:=hsum+byte(adata[i]);
      adata[7] := byte(hsum);                       //帧头校验和
      //数据
      for i := 0 to VarArrayHighBound(data,1) do
        adata[8 + i] := Byte(data[i]);
      //整帧校验和
      fsum:=0;
      for i:=7 to varArrayHighBound(data,1)+1+8 do
         fsum:=fsum+byte(adata[i])+byte(hsum);
      adata[nLength - 1] := byte(fsum);         //整帧校验和
      //8个填充字节
      for i := 0 to 7 do
        adata[nLength + i] := 0;//  Result := varRes;
    end;//------------------------------------------------------------------------------
    //名称: DetachFrame
    //参数: nAddr--地址;nKind--类型;InData--要分解的帧;OutData--分解后的数据
    //功能: 将应答帧分解成所需要的类型
    //说明:
    //
    //------------------------------------------------------------------------------procedure TProtocolLayer.DetachFrame(var nAddr, nKind: Integer; InData: Variant;
      var OutData: Variant);
    var
      nLength           : Integer;
      aHigh, aLow       : Byte;
      i                 : Integer;
    begin
      nLength := VarArrayHighBound(InData,1) - 8;
      OutData := varArrayCreate([0,nLength-1], varByte);
      //地址
      aLow := InData[2];
      aHigh := InData[3];
      nAddr := aHigh shl 8 + aLow;
      //类型
      nKind := InData[8];
      //数据
      for i := 0 to nLength - 1 do
        OutData[i] := InData[8 + i];
    end;
      

  3.   

    unit un_LinkLayer;interfaceuses
      MSCommLib_TLB, ExtCtrls, windows, un_Public, Variants, SysUtils, ActiveX,
      Dialogs, Forms;{$DEFINE VER_DEBUG}const
      ERR_TIMEOUT       = 1;                //超时错
      ERR_VERIFY        = 2;                //校验和错type  //链路层类,负责串口对象
      TLinkLayer = class
        constructor Create(iCom: Integer);
        destructor Destroy; override;
      private
        FCom: TMSComm;                      //串口
        FSerial: Byte;                      //序列号
        FRCAddr: Word;                      //RC地址
        FTimer: TTimer;                     //周期控制时钟
        FTimerSend: TTimer;                 //发送帧时钟
        FOutNum: Int64;                     //记录发送的数据帧个数
        FInNum: Int64;                      //记录收到的数据帧个数
        FOKNum: Int64;                      //记录校验正确帧的个数
        FErrorNum: Int64;                   //记录校验错误帧的个数
        FSendData: Variant;                 //发送的数据
        FSendNum: Integer;                  //帧发送次数
        FSendOK: Boolean;                   //是否发送成功
        FSendTime: Integer;                 //数据发送时间
        FReceiveTime: Integer;              //数据接收时间
        FOpenCOM: Boolean;
        FData: Variant;    FOnData: TOnData;
        FOnError: TOnError;
        FOnSendData: TOnSendData;
        FOnDebugData: TOnDebugData;
      private
        //接收字节变量
        FNewFrame: Boolean;                 //是否新帧
        FTmpData: string;                   //临时数据包
        FFrameLength: Integer;              //帧长度
      private
        //和校验操作
        function VerifyData(data: Variant): Integer;
        //事件处理
        procedure OnTimer(Sender: TObject);
        procedure OnTimerSend(Sender: TObject);
        procedure OnComm(Sender: TObject);
        //打开串口
        procedure DoOpenCOM(bOpen: Boolean);
        //其他
        function GetRealTime: Integer;
        function GetInterval: Integer;
      public
        function SendData(data: Variant; nLength: Integer): Integer;
        property OpenCom: Boolean read FOpenCOM write DoOpenCOM;
        procedure SetInterval(nInterval: Integer);
        property Interval: Integer read GetInterval;
        //事件
        property OnData: TOnData read FOnData write FOnData;
        property OnError: TOnError read FOnError write FOnError;
        property OnSendData: TOnSendData read FOnSendData write FOnSendData;
        property OnDebugData: TOnDebugData read FOnDebugData write
          FOnDebugData;
        //统计数据
        property OKNum: Int64 read FOKNum;
        property ErrorNum: Int64 read FErrorNum;
        property InNum: Int64 read FInNum;
        property OutNum: Int64 read FOutNum;
        property RealTime: Integer read GetRealTime; //实际帧发送--应答的时间
      end;implementation
      

  4.   


    constructor TLinkLayer.Create(iCom: Integer);
    begin
      inherited Create();  //创建设置TMSCOMM
      FCom := TMSComm.Create(nil);
      FCom.CommPort := iCom;
      FCom.RThreshold := 1;
      FCom.InputMode := comInputModeBinary;
      FCom.Settings := '115200,n,8,1';
      FCom.OnComm := Self.OnComm;
      //创建周期时钟
      FTimer := TTimer.Create(nil);
      FTimer.Enabled := False;
      FTimer.Interval := 50;
      FTimer.OnTimer := OnTimer;
      //创建发送时钟
      FTimerSend := TTimer.Create(nil);
      FTimerSend.Enabled := False;
      FTimerSend.Interval := 10;
      FTimerSend.OnTimer := OnTimerSend;
      //初始化值
      FSerial := 0;
      FOutNum := 0;
      FInNum := 0;
      FOKNum := 0;
      FErrorNum := 0;
      FSendNum := 0;  FSendData := varArrayCreate([0, 0], varByte);  FNewFrame := True;
      FTmpData := '';
    end;//------------------------------------------------------------------------------
    //名称:Destroy
    //参数:
    //功能:析构函数,释放对象
    //说明:
    //
    //------------------------------------------------------------------------------destructor TLinkLayer.Destroy;
    begin
      FCOM.Free;
      FTimer.Free;
      FTimerSend.Free;
    end;//------------------------------------------------------------------------------
    //名称:SendData
    //参数:data : 将要发送的数据帧; iLenth : 数据帧的长度
    //功能:将数据帧发向串口,并启动超时重发机制
    //说明:
    //
    //------------------------------------------------------------------------------function TLinkLayer.SendData(data: Variant; nLength: Integer): Integer;
    var
      i                 : Integer;
      sum               : byte;
    {$IFDEF VER_DEBUG}
      str               : string;
    {$ENDIF}
    begin
      //得到RC地址
      FRCAddr := UnitWord(data[3], data[2]);
      //增加序列号和校验和
      Inc(FSerial);
      data[6] := FSerial;
      sum := 0;
      for i := 0 to 6 do                    //帧头校验和
        sum := sum + byte(data[i]);
      data[7] := byte(sum);
      sum := 0;
      for i := 0 to nLength - 8 - 2 do      //整帧校验和
        sum := sum + byte(data[i]);
      data[nLength - 8 - 1] := byte(sum);  VarArrayRedim(FSendData, varArrayHighBound(data, 1));
      FSendData := data;  FCOM.Output := data;
      if Assigned(FOnSendData) then FOnSendData(data);
      FSendTime := GetTickCount;
      //启动超时机制
      FTimer.Enabled := True;
      FSendOK := False;
      FSendNum := 1;
      Result := 0;
      Inc(FOutNum);
    {$IFDEF VER_DEBUG}
      str := Format('%12s', ['Send']);
      for i := 0 to VarArrayHighBound(data, 1) do
        str := str + ' ' + IntToHex(Byte(data[i]), 2);
      OutputDebugString(pChar(str));
    {$ENDIF}  if Assigned(FOnDebugData) then FOnDebugData(data, -1);
    end;//------------------------------------------------------------------------------
    //名称: VerifyData
    //参数: data
    //功能: 校验帧是否有效
    //说明: 返回值0--有效,1--效验和错误,2--序列号错,3--地址错误
    //
    //------------------------------------------------------------------------------function TLinkLayer.VerifyData(data: Variant): Integer;
    var
      nLength           : Integer;
      i                 : Integer;
      sum               : Byte;
    begin
      //判断帧的长度
      if VarArrayHighBound(data,1) < 9 then begin
        Result := ERROR_NOLEN;
        Exit;
      end;
      //序列号校验
      if FSerial <> data[6] then begin
        Result := ERROR_SERIAL;
        Exit;
      end;
      //地址校验
      if FRCAddr <> (UnitWord(data[3], data[2])) then begin
        Result := ERROR_RCADDR;
        Exit;
      end;
      //和校验
      nLength := UnitWord(Byte(data[5]), Byte(data[4]));
      sum := 0;
        //帧头校验
      for i := 0 to 6 do
        sum := sum + Byte(data[i]);
      if sum <> data[7] then
        Result := ERROR_SUM
      else begin
          //整帧校验
        sum := 0;
        for i := 0 to nLength - 2 do
          sum := sum + Byte(data[i]);
        if sum <> Byte(data[nLength - 1]) then
          Result := ERROR_SUM
        else
          Result := 0;
      end;
    end;//------------------------------------------------------------------------------
    //名称: SetTimer
    //参数: nInterval
    //功能: 设置时钟的Interval
    //说明:
    //
    //------------------------------------------------------------------------------procedure TLinkLayer.SetInterval(nInterval: Integer);
    begin
      FTimer.Interval := nInterval;
    end;//------------------------------------------------------------------------------
    //名称: OnTimer
    //参数:
    //功能: 时钟事件触发处理
    //说明:
    //
    //------------------------------------------------------------------------------procedure TLinkLayer.OnTimer(Sender: TObject);
    var
      nAddr             : Integer;
    begin
      if not FSendOK then begin
        if FSendNum >= 3 then begin
          //超时
          FTimer.Enabled := False;
          FSendNum := 0;
          //广播消息不触发事件
          nAddr := UnitWord(FSendData[3], FSendData[2]);
          if (nAddr <> $FFFF) then
            if Assigned(FOnError) then FOnError(FSendData[8])
          else
            if Assigned(FOnError) then FOnError($FF);
        end else begin
          FCOM.Output := FSendData;
          Inc(FSendNum);
        end;
      end;
    end;
      

  5.   

    //------------------------------------------------------------------------------
    //名称: OnComm
    //参数:
    //功能: TMSCOMM数据事件处理
    //说明:
    //
    //------------------------------------------------------------------------------procedure TLinkLayer.OnComm(Sender: TObject);
    var
      nPos              : Integer;
      i                 : Integer;
      varData           : Variant;
      nLength           : Integer;
      nVerifyRes        : Integer;
    {$IFDEF VER_DEBUG}
      str               : string;
    {$ENDIF}
    begin
      case FCOM.CommEvent of
        comEvReceive: begin
            nLength := FCOM.InBufferCount;
            varData := FCOM.Input;
            for i := 0 to nLength - 1 do
              FTmpData := FTmpData + Chr(Byte(varData[i]));        if Length(FTmpData) >= 2 then begin
              nPos := Pos(#$FF#$A5, FTmpData);
              if nPos > 0 then              //有帧头标识
                Delete(FTmpData, 1, nPos - 1);
            end else
              Exit;
            if Length(FTmpData) >= 8 then begin
                //帧头到来
              FFrameLength := UnitWord(byte(Ord(FTmpData[6])),
                byte(Ord(FTmpData[5])));
              if FFrameLength > 256 then begin //帧长度不对,重新接收
                FTmpData := '';
                FNewFrame := True;
                Exit;
              end;
              if Length(FTmpData) >= FFrameLength then begin
                //帧收完毕
                FData := VarArrayCreate([0, FFrameLength - 1], varByte);
                for i := 0 to FFrameLength - 1 do
                  FData[i] := byte(Ord(FTmpData[i + 1]));            Inc(FInNum);
    {$IFDEF VER_DEBUG}
                str := Format('%10s', ['Receive']);
                for i := 0 to VarArrayHighBound(FData, 1) do
                  str := str + ' ' + IntToHex(Byte(FData[i]), 2);
                OutputDebugString(pChar(str));
    {$ENDIF}
                nVerifyRes := VerifyData(FData); //校验数据帧
                if nVerifyRes = 0 then begin
                  //帧接受完毕
                  FTimer.Enabled := False;
                  FSendOK := True;
                  FSendNum := 0;
                  //启动发送下一帧时钟
                  FTimerSend.Enabled := True;
                  Inc(FOKNum);              //增加正确帧计数
                end else begin
                  Inc(FErrorNum);           //增加错误帧计数
                end;
                
                //初始化接受变量
                FTmpData := '';
                FNewFrame := True;            FReceiveTime := GetTickCount;
                if Assigned(FOnDebugData) then FOnDebugData(FData, nVerifyRes);          end;
            end;
          end;
      else
        Exit;
      end;
    end;//------------------------------------------------------------------------------
    //名称: DoOpenCOM
    //参数:
    //功能: 打开端口,将端口状态发向主窗口
    //说明:
    //
    //------------------------------------------------------------------------------procedure TLinkLayer.DoOpenCOM(bOpen: Boolean);
    begin
      try
        FCOM.PortOpen := bOpen;
        FOpenCOM := bOpen;
        PostMessage(Application.MainForm.Handle, WM_PORTSTATUS, FCOM.CommPort, 0);
      except
        FOpenCOM := False;
        PostMessage(Application.MainForm.Handle, WM_PORTSTATUS, FCOM.CommPort, 1);
      end;
    end;function TLinkLayer.GetRealTime: Integer;
    begin
      Result := FReceiveTime - FSendTime;
    end;function TLinkLayer.GetInterval: Integer;
    begin
      Result := FTimer.Interval;
    end;procedure TLinkLayer.OnTimerSend(Sender: TObject);
    begin
      FTimerSend.Enabled := False;
      if Assigned(FOnData) then begin
        FOnData(FData, VarArrayHighBound(FData, 1) + 1);
      end;
    end;end.
      

  6.   

    给你了协议层和链路层的unit单元
      

  7.   

    先谢谢chenquan(嘉威王子) 。
    我的情况是这样的,我手上有一个松下CS850的协议。
    协议结构是这样的:
      STXAD00;GC7:002110CETX  
       A D 0 0 : Unit Address 00 - 99, ZZ
        Note : Only address 01 - 96 is available for CSR camera series. 
        Only address 01 - 16 is available for WV-RM70. 
        ZZ controls all units. 
        STX:02hex of ASCII code table
        GC:Command header, GC:Camera Control Command
        F: Number of commands. Refer Fig - 1
        002: Command distination, 002:Camera functions,202:Receiver functions
        1: Command type, 1:Control command, 0:Status request command, 2:Text data
        10C: Function (Preset position call), Refer table 2 Receiver function 
        ETX :03hex of ASCII code table
    有一个Camera functions列表。一个Receiver functions列表。
    根据我的理解:就是向串口发送一个$02(开始),然后发送字符串如:
    'AD00;GC7:002110C';在发送一个$03(结束)。不知道你们发送的命令是什么一个样子,可否说
    下呢。至于串口通讯这一块,我想程序中应该没问题的,对解码器的控制我试过。现在就是不清楚对快球的控制命令我是否发错了!
        
      

  8.   

    谢谢chenquan(嘉威王子),谢谢各位。