Hi Leute,
ich speichere einen 24-Bit Wert in einer signed long (32-Bit) Variable
und möchte diese dann über USART übertragen.
Ich habe jetzt eine Funktion geschrieben die den Wert in 3 x 8-Bit Werte
zerlegt und dann sendet.
1
// USART: Transmit 3 Bytes (MSB first)
2
// ----------------------------------
3
voidUSART_Transmit_3Bytes(signedlongdata)
4
{
5
unsignedchardata_1,data_2,data_3;
6
// write first byte into 8-bit variable data_1 (MSB first)
7
data_1=data;
8
USART_Transmit(data_1);
9
// write second byte into 8-bit variable data_2
10
data_2=data>>8;
11
USART_Transmit(data_2);
12
// write third byte into 8-bit variable data_3
13
data_3=data>>16;
14
USART_Transmit(data_3);
15
}
Geht das überhaupt so?
Speichert er bei der Zuweisung "data_1 = data" die letzten 8-Bit der
32-Bit Variable?
Loomit schrieb:> Geht das überhaupt so?
Im Prinzip ja.
Das einzige Problem.
Angenommen der Empfänger weiß nicht, was da jetzt daherkommt. Woher weiß
er, welches das erste Byte deines 24 Bit Wertes ist?
> Speichert er bei der Zuweisung "data_1 = data" die letzten 8-Bit der> 32-Bit Variable?
Jep. recht viel anderes bleibt ihm nicht übrig. Oder was hast du
erwartet?
> Im Prinzip ja.> Das einzige Problem.> Angenommen der Empfänger weiß nicht, was da jetzt daherkommt. Woher weiß> er, welches das erste Byte deines 24 Bit Wertes ist?
Das ist kein Problem das festzustellen, da die Werte an LabVIEW gesendet
werden.
> Jep. recht viel anderes bleibt ihm nicht übrig. Oder was hast du> erwartet?
Ich war mir irgendwie nicht mehr 100% sicher, deswegen habe ich lieber
gefragt!!
Danke!
so am Rande: wenn mit den drei Variablen nicht mehr passiert, als daß
sie gesendet werden, so reicht doch eine Variable aus, die die
jeweiligen 8 bit aufnimmt. Oder es geht natürlich auch ganz ohne extra
Variablen?
Loomit schrieb:> Das ist kein Problem das festzustellen, da die Werte an LabVIEW gesendet> werden.
Wow, daß LabVIEW hellsehen kann, ist ja super.
Wozu dann aber die Daten überhaupt erst senden?
Peter
Es gibt bei Deiner Methode keine Möglichkeit, durch ein Trennzeichen
(etwa CR/LF) Anfeng und Ende eines Datenpakets zu bestimmen, da ja diese
Werte auch in einer Zahl vorkommen können.
Das wird also nur funktionieren, wenn mit entsprechenden Pausen zwichen
den Werten und Timeouts gearbeitet wird. Ist aber eher unüblich.
Besser die Zahl als String übertragen, Dezimal oder HEX.
Das Erleichtert auch die Fehlersuche, da man dann sofort den Wert sieht.
Markus Vohburger schrieb:> Es gibt bei Deiner Methode keine Möglichkeit, durch ein Trennzeichen> (etwa CR/LF) Anfeng und Ende eines Datenpakets zu bestimmen, da ja diese> Werte auch in einer Zahl vorkommen können.
Da lob´ ich mir doch UARTs mit 9-tem Datenbit ;-)
Loomit schrieb:>> Im Prinzip ja.>> Das einzige Problem.>> Angenommen der Empfänger weiß nicht, was da jetzt daherkommt. Woher weiß>> er, welches das erste Byte deines 24 Bit Wertes ist?>> Das ist kein Problem das festzustellen, da die Werte an LabVIEW gesendet> werden.
Das muss dann das neue 'Kristallkugel' Modul sein.
Jaa Leute da war ich wohl etwas zu voreilig mit meiner Aussage ohne
vorher das Problem zu durchdenken!!! :-)
Vielen Dank für die hilfreichen Bemerkungen in Bezug auf Magie!! ;-)
Naja Spaß beiseite:
Also dieser 24-Bit Wert repräsentiert einen Wandlungswert und ich muss
ihn irgendwie rüber senden und zusammensetzen!
Die Idee mit dem 9-ten Datenbit finde ich schon ganz hilfreich.
Loomit schrieb:> 24-Bit Wert in einer signed long (32-Bit) Variable
Hat denn dein 24 bit Wert ein Vorzeichen, ist das ebenso signed? Dann
musst du eh alle 4 Bytes des long übertragen.
Karl Heinz Buchegger schrieb:> Das muss dann das neue 'Kristallkugel' Modul sein.
Wird im Katalog als 'Prophetschaltung' verkauft und gibts mit
verschiedenen Vorhersagezeiträumen :-)
Nich wirklich.
Das 2er Komplement ist da schon ausgefuchst.
Wenn er alles empfangen hat, dann bei bit23 gucken ob 1 oder 0 und die
restlichen MSB genauso ausfüllen.
Loomit schrieb:> Also dieser 24-Bit Wert repräsentiert einen Wandlungswert und ich muss> ihn irgendwie rüber senden und zusammensetzen!
Nun ja, da du das "Datenübertragungsprotokoll" selbst erstellt hast,
sollte das ja kein Problem sein.
Man muß ja immer und überall wissen, wie die einzelnen Bits zu
interpretieren sind. Ansonsten ist ja jede Bitfolge völlig wertlos, wenn
das nicht weiß.
Es wäre schlauer, du würdest deinen 24-Bit-Wert anstelle in 3 Byte
aufdröseln und in 4 Byte übertragen wie folgt:
Bit7 Bit6 Bit5...Bit0
Byte 1: 0 0 untereste 6 Bit deines 24-Bit-Werts ( 5 - 0 )
Byte 2: 0 1 nächste 6 Bit " " ( 11 - 6 )
Byte 3: 1 0 nächste 6 Bit " " ( 17 - 12 )
Byte 4: 1 1 oberste 6 Bit " " ( 23 - 18 )
So kannst du anhand der "Kennung" in den oberen 2 Übertragungsbits am
Empfänger die Werte wieder passend zusammenstückeln.
Evtl. noch die Reihenfolge der "Kennung" mitprüfen, damit kannst dann
erkennen daß die Werte (höchstwahrscheinlich) aufeinanderfolgend
zusammengehören.
Wertübernahme als 24-Bit-Wert empfangsseitig nur gültig, wenn diese 4-er
Reihenfolge komplett war.
Anschliessend (kann) nächster 4-Byte-Kette kommen, für den nächsten Wert
24-Bit-Wert.
Gruss
Ich denke, was meine Vorredner sagen wollen, ist, daß es sinnvoll ist,
die einzelnen 24Bit-Werte gegeneinander abzugrenzen.
Falls Dir mal ein Byte verloren geht, könnte dir Deine ganze
Kommunikation "verrutschen":
Beispiel:
Soll: 0x12 0x34 0x56 0x12 0x34 0x56 0x12 0x34 0x56 0x12 0x34 0x56
Jetzt geht das 5. Byte verloren:
Ist: 0x12 0x34 0x56 0x12 0x56 0x12 0x34 0x56 0x12 0x34 0x56 0x12
Da nun jedes Byte Deines 24Bit Wertes jeden Inhalt zwischen 0 und 255
annehmen kann, kannst Du nicht einfach Trennzeichen definieren, denn wie
willst Du unterscheiden, ob es ein Trennzeichen oder ein echter Wert
ist?
Du könntest aber z.B. eine Pause zwischen den Telegrammen definieren,
mit der sich der Empfänger synchronisieren kann.