![]() |
Binär Datei über RS232 versenden Delphi
Ich versuch seit einiger Zeit eine Binär Datei über eine RS232 Schnittstelle zu versenden, aber aus irgendeinem Grund bricht er nach dem ersten Byte ab.
Mein Code Bis jetzt:
Delphi-Quellcode:
AFileStream := TFileStream.Create(DatName, fmOpenRead); try DataSize := AFileStream.Size; AFileStream.Position := 0; CanSend := 1; GetMem(DataPtr, CanSend); while DataSize > 0 do begin AFileStream.Read(DataPtr, CanSend); Move(DataPtr, SendByte, CanSend); ComSerial.SendByte(SendByte); DataSize := DataSize - CanSend; SendDataSize := SendDataSize + CanSend; end; FreeMem(DataPtr); finally AFileStream.Free; end; Hat irgendjemand eine Idee? |
Re: Binär Datei über RS232 versenden Delphi
Soll CanSend später größer werden? Ansonsten könntest Du ja auf den DataPtr verzichten und die StreamDaten gleich in SendByte einlesen.
Ich glaube das müsste so aussehen:
Delphi-Quellcode:
was aber erst mal nur für falsche Daten gesorgt hätte.
Move(DataPtr^, SendByte, CanSend);
|
Re: Binär Datei über RS232 versenden Delphi
Ich habe auch so das selbe Problem und zwar das er mit dem ersten gesendeten Byte aus dem Redboot rausspringt und den Versuch abbricht. Das bringt mich in der Hinsicht trotzdem nicht weiter. Eine weiter Möglichkeit für mich wäre. Das ich die Daten direkt mit SendData(Pointer, DataSize) an den ComPort schicke das funktioniert aber auch nicht so wie es sein soll.
Diese Routine sieht dann so aus:
Delphi-Quellcode:
Doch bei diesem Versuch empfange ich überhaupt keine Daten an meiner Gegenstelle.
AFileStream := TFileStream.Create(DatName, fmOpenRead);
try DataSize := AFileStream.Size; AFileStream.Position := 0; CanSend := 1; GetMem(DataPtr, CanSend); while DataSize > 0 do begin AFileStream.Read(DataPtr, CanSend); ComSerial.SendData(DataPtr, CanSend); DataSize := DataSize - CanSend; SendDataSize := SendDataSize + CanSend; end; finally AFileStream.Free; FreeMem(DataPtr); end; Das CanSend ist blos noch dabei weil ich vorher Daten mit einer Größe von 2048 verschickt habe und sich die SendeGröße beim letzten Sendevorgang geändert hat. |
Re: Binär Datei über RS232 versenden Delphi
TStream.Read() erwartet einen untypisierten Parameter (Inhalt beliebigen Typs). Wenn du einen Zeiger hast, dann musst du ihn dereferenzieren, um auf den Inhalt zu zeigen (DataPtr^, ...).
Dein jetziger Code überschreibt den Zeiger (und die im Speicher nachfolgenden Daten), was sicher nicht beabsichtigt ist. |
Re: Binär Datei über RS232 versenden Delphi
Jetzt habe ich wieder das selbe Problem das er sofort nach dem ersten senden den Vorgang abbricht.
RedBoot> ^C RedBoot> fload CCCan't load '<null>': Cancelled |
Re: Binär Datei über RS232 versenden Delphi
Im PComm Terminal machen sie das selbe, aber die Daten die geschickt werden sehen anders aus wie meine, obwohl es die selbe Datei ist.
Sie benutzen da auch das Protokoll X-Modem crc um Binäre Daten zu verschicken. Kann es vllt an der Art wie ich die Daten aus der Datei lese liegen? |
Re: Binär Datei über RS232 versenden Delphi
Spricht Deine Gegenstelle denn das Protokoll XModem?
Wenn ja, dann solltest Du bzw. Dein Programm es auch sprechen. ![]() Grüße Klaus |
Re: Binär Datei über RS232 versenden Delphi
Hab jetzt endlich wieder Zeit zum Delphi programmieren und hänge bei der CRC Berechnung.
Danke übrigens für den Tip Klaus CRC XModem ist die Lösung oder sollte sie sein. Ich komme einfach nicht auf die Checksum die vom PComm Terminal errechnet wird. Hier ein Auszug aus einem gesendeten Block: 01 01 FE 18 F0 9F E5 18 F0 9F E5 18 F0 9F E5 18 F0 9F E5 18 F0 9F E5 00 00 00 00 18 F0 9F E5 18 F0 9F E5 40 00 00 60 20 02 00 60 44 02 00 60 70 02 00 60 8C 02 00 60 00 00 00 00 8C 03 00 60 54 03 00 60 40 15 9F E5 B0 00 D1 E1 FF 00 80 E3 B0 00 C1 E1 B4 00 D1 E1 FF 00 80 E3 B4 00 C1 E1 B8 00 D1 E1 FF 00 80 E3 B8 00 C1 E1 1B 13 A0 E3 18 05 9F E5 B0 00 C1 E1 B4 00 C1 E1 10 05 9F E5 B8 00 C1 E1 F0 FC 01 01 FE = Ist die Initialisierung mit Begin eines Blockes(01), Block Nummer(01), Komplement der Block Nummer (FE) F0 FC = Checksum CRC XModem Bei mir kommt als Checksum immer nur 70D8 raus, was mach ich blos falsch? Hier ein Auszug aus dem Code mit dem ich die Checksum berechne
Delphi-Quellcode:
function CalculateXYZModemCRC16(const Data; Length: LongWord): Word;
type TCRC16Table = array[0..255] of Word; TBytes = array[0..MaxInt - 1] of Byte; const Crc16Tab: Array[0..$FF] of Word = ($00000, $01021, $02042, $03063, $04084, $050a5, $060c6, $070e7, $08108, $09129, $0a14a, $0b16b, $0c18c, $0d1ad, $0e1ce, $0f1ef, $01231, $00210, $03273, $02252, $052b5, $04294, $072f7, $062d6, $09339, $08318, $0b37b, $0a35a, $0d3bd, $0c39c, $0f3ff, $0e3de, $02462, $03443, $00420, $01401, $064e6, $074c7, $044a4, $05485, $0a56a, $0b54b, $08528, $09509, $0e5ee, $0f5cf, $0c5ac, $0d58d, $03653, $02672, $01611, $00630, $076d7, $066f6, $05695, $046b4, $0b75b, $0a77a, $09719, $08738, $0f7df, $0e7fe, $0d79d, $0c7bc, $048c4, $058e5, $06886, $078a7, $00840, $01861, $02802, $03823, $0c9cc, $0d9ed, $0e98e, $0f9af, $08948, $09969, $0a90a, $0b92b, $05af5, $04ad4, $07ab7, $06a96, $01a71, $00a50, $03a33, $02a12, $0dbfd, $0cbdc, $0fbbf, $0eb9e, $09b79, $08b58, $0bb3b, $0ab1a, $06ca6, $07c87, $04ce4, $05cc5, $02c22, $03c03, $00c60, $01c41, $0edae, $0fd8f, $0cdec, $0ddcd, $0ad2a, $0bd0b, $08d68, $09d49, $07e97, $06eb6, $05ed5, $04ef4, $03e13, $02e32, $01e51, $00e70, $0ff9f, $0efbe, $0dfdd, $0cffc, $0bf1b, $0af3a, $09f59, $08f78, $09188, $081a9, $0b1ca, $0a1eb, $0d10c, $0c12d, $0f14e, $0e16f, $01080, $000a1, $030c2, $020e3, $05004, $04025, $07046, $06067, $083b9, $09398, $0a3fb, $0b3da, $0c33d, $0d31c, $0e37f, $0f35e, $002b1, $01290, $022f3, $032d2, $04235, $05214, $06277, $07256, $0b5ea, $0a5cb, $095a8, $08589, $0f56e, $0e54f, $0d52c, $0c50d, $034e2, $024c3, $014a0, $00481, $07466, $06447, $05424, $04405, $0a7db, $0b7fa, $08799, $097b8, $0e75f, $0f77e, $0c71d, $0d73c, $026d3, $036f2, $00691, $016b0, $06657, $07676, $04615, $05634, $0d94c, $0c96d, $0f90e, $0e92f, $099c8, $089e9, $0b98a, $0a9ab, $05844, $04865, $07806, $06827, $018c0, $008e1, $03882, $028a3, $0cb7d, $0db5c, $0eb3f, $0fb1e, $08bf9, $09bd8, $0abbb, $0bb9a, $04a75, $05a54, $06a37, $07a16, $00af1, $01ad0, $02ab3, $03a92, $0fd2e, $0ed0f, $0dd6c, $0cd4d, $0bdaa, $0ad8b, $09de8, $08dc9, $07c26, $06c07, $05c64, $04c45, $03ca2, $02c83, $01ce0, $00cc1, $0ef1f, $0ff3e, $0cf5d, $0df7c, $0af9b, $0bfba, $08fd9, $09ff8, $06e17, $07e36, $04e55, $05e74, $02e93, $03eb2, $00ed1, $01ef0); var CRC16: word; index: byte; i:LongWord; begin CRC16 := 0; // $FFFF for i:=0 to Length-1 do begin index := ((CRC16 shr 8) xor TBytes(Data)[i]) and $FF; CRC16 := CRC16Tab[Index] xor (CRC16 shl 8); end; Result := CRC16; end; |
Re: Binär Datei über RS232 versenden Delphi
Wenn Du die ersten drei Bytes (01 01 FE) wegläßt, erhältst Du den gewünschten CRC-Wert $F0DC.
Gruß Gammatester |
Re: Binär Datei über RS232 versenden Delphi
Ich lasse sie ja weg und komme irgendwie trotzdem nicht auf den Wert.
Hier mal noch mein Funktionsaufruf mit dem ich teste.
Delphi-Quellcode:
procedure TFWork.TestCRCClick(Sender: TObject); var AFile, AStr: String; SendByte: Byte; Data: Array [1..128] of Byte; AFileStr: TFileStream; i, crc: Integer; Erg: Word; begin AFile := Fu.GetExeDir + 'test.bin'; if FileExists(AFile) then begin AFileStr := TFileStream.Create(AFile, fmOpenRead); try AFileStr.Position := 0; for i:=1 to 128 do begin AFileStr.Read(SendByte,1); Data[i] := SendByte; end; crc := Fu.CalculateXYZModemCRC16(Data, High(Data)); EdBefSer.Text := IntToHex(crc, 4); finally AFileStr.Free; end; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:54 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz