Byte zerlegen und zusammensetzten

  • Allgemein

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von jvbsl.

    Byte zerlegen und zusammensetzten

    Hallo zusammen,

    ich bin noch recht neu im Thema Programmieren. Jetzt soll ich für die Firma in kleines Programm erstellen das Werte eines CAN-Bus Gerätes anzeigen kann. Leider kommen ich mit der Zerlegung der CAN-Nachrichten nicht ganz zurecht.

    Die nachrichten kommen mit einer Gesamtlänge von 8 Bytes, von der Schnittstellen-dll bekommen ich diese Bytes einzel übergeben. Jetzt ist es aber so, das der erste Wert der darin enthalten ist 14 Bit lang ist und somit dann über 2 Bytes geht, der nächste Wert folgt direkt anschließend.

    Wert 1: von Byte 1, Bit 1 bis Byte 2, Bit 6 (14 Bit lang)
    Wert 2: von Byte 2, Bit 7 bis Byte 3, Bit 7 (9 Bit lang)

    Wert 1 ist dann eine Längenangabe in 0,1 mm und Wert 2 ist die Stromstärke in 0,1 A.

    Wie kann/muss ich das jetzt umwandeln damit ich die Werte in einen Integer scheiben kann. Ich stehe da gerade voll auf dem Schlauch und finden auch keinen Ansatz wie ich das hinbekommen könnte.
    Hmm. Ich frage mich grade ob die Ordnung so ist:
    Beispiel 1:
    |{00000010|100000}{10|0000000}0|
    Oder so
    Beispiel2:
    |{..01000000}|{..00}{000001..}|0{00000000..}|

    Also zusammenhängender Bitstream oder immer von LSB ausgehend?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Marcel1997“ ()

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo Marcel,

    so wie ich das verstanden habe werden die Bits ja von rechts nach links durchgezählt, somit sollte die Reihenfolge aus Beispiel 2 dem entsprechen was vorliegt. Hier noch mal eine Darstellung wir die in einem anderen Anwendungsprogramm verwendet wird:

    Bit 8
    Bit7
    Bit 6
    Bit 5
    Bit 4
    Bit 3
    Bit 2
    Bit 1
    Byte 1
    8
    7
    6
    5
    4
    3
    2
    1
    Byte 2
    16
    15
    14
    13
    12
    11
    10
    9
    Byte 3
    24
    23
    22
    21
    20
    19
    18
    17

    Ich habe jetzt schon mal etwas mit Bit shiften (Wert2 << 2) herumgespielt, leider aber noch nicht das richtige Ergebnis bekommen.

    Ich glaube, das ich es jetzt hinbekommen habe:
    Wert 1 = Byte 1 + (( Byte 2 << 2) >> 2) * 256
    Hiermit habe ich zumindest die erwarteten Werte bekommen, ob das die Einfachste und Eleganteste Lösung ist, weis ich nicht.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Markus_78“ ()

    @Markus_78 Den Hinweis mit der BitConverter-Klasse hätte ich auch ignoriert. X(
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    In .Net musst du das manuell machen, in C/C++ geht es so:

    C-Quellcode

    1. union bla
    2. {
    3. uint64_t value;
    4. #ifdef _MSC_VER
    5. #pragma pack(push, 1)
    6. #endif
    7. struct
    8. {
    9. int16_t length : 14;
    10. int16_t current : 9;
    11. }
    12. #ifdef _MSC_VER
    13. ;
    14. #pragma pack(pop)
    15. #else
    16. __attribute__((packed));
    17. #endif
    18. };

    bin mir nicht sicher ob das packing wirklich nötig ist, sollte aber zumindest nicht schaden.
    und die Verwendung wäre dann einfach so:

    C-Quellcode

    1. struct bla x;
    2. x.value = deinevalue;
    3. //value und die struct stehen an der gleichen memory stelle, somit hast du automatisch length und current beschrieben
    4. int16_t current = x.current;//9bit value

    Natürlich darfst du dabei endianess nicht vergessen, was das ganze wieder umdreht. Man könnte z.B. immer für BigEndian programmieren und dann htonl nehmen um den wert zu setzen...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---