unit ToolsRS; interface uses Forms, AdPort, OoMisc; var BufIn, BufOut : Array [0..200000] of byte; FlagRS : Boolean = false; FlagAbortKey : Boolean = false; Count_error : Integer = 0; RSTimeOut : Boolean = True; procedure SendAddress (AdrCon:Byte); function RunCmdNew (Cmd : Byte; LengthOut,LengthIn :LongWord): Byte; function ContrlolSumCRC16(BufCRC : Array of Byte; LengthB : LongWord): Word; function LB(X: Word): Byte; function HB(X: Word): Byte; implementation uses CAN_Terminal; Function ContrlolSumCRC16(BufCRC : Array of Byte; LengthB : LongWord) : Word; Var CRC : Word; Index1, Index2: LongWord; rb : Byte; Begin CRC := $ffff; For Index1 := 0 To LengthB-1 Do Begin CRC := (CRC and $FFFF); CRC := (CRC XOR (BufCRC[Index1])); For Index2 := 1 To 8 Do If ((CRC And $1) <> 0) Then CRC := ((CRC SHR 1) xor $A001) else CRC := (CRC SHR 1) end; Result := (CRC and $FFFF); end; procedure SendAddress (AdrCon:Byte); var ET : EventTimer; begin if AdrCon = 0 then exit; CANTerminal.MyCommPort.Parity:=pNone; CANTerminal.MyCommPort.PutChar(Chr(AdrCon)); end; function RunCmdNew(Cmd : Byte; LengthOut,LengthIn :LongWord): Byte; var b : Byte; CSum,PAdr : Word; CSumb : Byte; BB : LongWord; bb1,bb2 : Word; i,i1,i2 : LongWord; ET : EventTimer; Ch : Char; BufSize : LongWord ; Posit : LongWord; Block1 : Array [0..9000] of byte; FlagOpenRS : Boolean; Fr : Byte; begin if CANTerminal.MyCommPort.OutBuffUsed <> 0 then exit; FlagRs:=True; FlagAbortKey:=False; CANTerminal.AbortKey.Visible:=True; FlagOpenRS := CANTerminal.MyCommPort.Open; CANTerminal.MyCommPort.Open:=True; CANTerminal.MyCommPort.FlushInBuffer; CANTerminal.MyCommPort.FlushOutBuffer; Posit:=0; CANTerminal.PBRs.Position:=0; CANTerminal.PBRs.Max:=LengthOut+LengthIn; Count_error := 0; BufIn[0]:=0; BufIn[1]:=0; BufIn[2]:=0; BufIn[3]:=0; BufIn[4]:=0; BufIn[5]:=0; BufIn[6]:=0; BufIn[7]:=0; BufIn[8]:=0; BufIn[9]:=0; Padr:=$3f8+5; if Cmd<>0 then SendAddress(Cmd); BufOut[LengthOut]:=0; BufOut[LengthOut+1]:=0; BufOut[LengthOut+2]:=0; BufOut[LengthOut+3]:=0; i1:=LengthOut+1; i2:=0; repeat if i1>=1024 then begin for i:=0 to 1023 do Block1[i] := BufOut[i+i2]; while CANTerminal.MyCommPort.OutBuffUsed<>0 do; CANTerminal.MyCommPort.PutBlock(Block1,1024); Posit:=Posit+1024; i1:=i1-1024; i2:=i2+1024; end else begin if ((i1<1024) and (i1>0)) then begin for i:=0 to i1-1 do Block1[i] := BufOut[i+i2]; while CANTerminal.MyCommPort.OutBuffUsed<>0 do; CANTerminal.MyCommPort.PutBlock(Block1,i1); Posit:=Posit+i1; while CANTerminal.MyCommPort.OutBuffUsed<>0 do; i1:=0; i2:=LengthOut; end; end; CANTerminal.PBRs.Position:=Posit; Application.ProcessMessages; if FlagAbortKey then begin Result:=3; FlagRs:=False; CANTerminal.MyCommPort.Open:=FlagOpenRS; exit; FlagAbortKey:=False; CANTerminal.AbortKey.Visible:=False; end; until (i1=0); while CANTerminal.MyCommPort.OutBuffUsed<>0 do; i:=0; while i<(LengthIn) do begin bb:=0; RSTimeOut:= false; NewTimer(ET,Round(CANTerminal.TimeWait.Value)); repeat CANTerminal.MyCommPort.ProcessCommunications; // Application.ProcessMessages; if CANTerminal.MyCommPort.InBuffUsed>1024 then begin CANTerminal.MyCommPort.GetBlock(Block1,1024); for i1:=0 to 1023 do BufIn[i+i1]:=Block1[i1]; i:=i+i1; Posit:=Posit+1024; end; If CANTerminal.MyCommPort.CharReady then begin inc(Posit); CANTerminal.PBRs.Position:=Posit; Ch:=CANTerminal.MyCommPort.GetChar; bb:=1; BufIn[i]:=Ord(Ch); inc(i); // if not ((i>2) and (i > BufIn[2]+4)) // then Application.ProcessMessages; Break; end; if FlagAbortKey then begin FlagAbortKey:=False; CANTerminal.AbortKey.Visible:=False; Result:=3; // Получение прервано кнопкой FlagRs:=False; CANTerminal.MyCommPort.Open:=FlagOpenRS; exit; end; until TimerExpired(ET) { or (RSTimeOut) }; If bb=0 then Break; end; CANTerminal.MyCommPort.FlushInBuffer; CANTerminal.MyCommPort.FlushOutBuffer; FlagAbortKey:=False; CANTerminal.AbortKey.Visible:=False; If bb=0 then begin Result:=1; // ничего не пришло... CANTerminal.MyCommPort.Open:=FlagOpenRS; FlagRs:=False; exit; end; Csum:=ContrlolSumCRC16(BufIn,LengthIn-2); if CSum<>(BufIn[LengthIn-2]+BufIn[LengthIn-1]*256) then begin Result:=2; // не сошлась контрольная сумма FlagRs:=False; CANTerminal.MyCommPort.Open:=FlagOpenRS; exit; end else Result:=0; CANTerminal.MyCommPort.Open:=FlagOpenRS; FlagRs:=False; CSum:=i; if PAdr=0 then CSum:=i; end; {Получение младшего байта} function LB(X: Word): Byte; var b1: Byte; begin asm mov ax,X mov b1,al end; Result:=b1; end; {Получение старшего байта} function HB(X: Word): Byte; var b1: Byte; begin asm mov ax,X mov b1,ah end; Result:=b1; end; end.