Wie immer Low Byte und High Byte zusammensetzen

Gast #2714574
Lesenswert?

Hallo Leute,

ich empfange Daten über die RS232 Schnittstelle. An die Nutzdaten habe 
ich eine CRC16 Checksumme drangehängt (2Bytes).

Von der Checksumme wird zuerst das Low Byte und anschließend das High 
Byte übertragen.

Ich habe eine For-Schleife. Diese For-Schleife liest das 1.Byte aus dem 
RS232-Buffer aus und soll dieses Byte im unsigned short crc16_checksum 
speichern.

Die habe ich wie folgt gelöst:
1
received_checksum = ((unsigned short) rs232_data);

Jedoch beim 2. Schleifendurchlauf lese ich das High Byte aus dem RS232 
Buffer aus. Nun kann ich ja nicht die gleiche Anweisung wie oben nehmen.

Ich könnte in der For-Schleife eine Fallunterscheidung vornehmen dies 
benötigt aber wieder zusätzlich Laufzeit.

Gibt es denn auch eine elegenate Lösung um dann das High Byte in den 
Datentype short zu schreiben?
#2714587
Lesenswert?

Sebastian schrieb:
> Ich könnte in der For-Schleife eine Fallunterscheidung vornehmen dies
> benötigt aber wieder zusätzlich Laufzeit.

Ich behaupte mal das diese zusätzliche Laufzeit (insbesondere im 
Vergleich zu der Zeit die die serielle Datenübertragung benötigt) 
vernachlässigbar ist.

Wenn Du aber die folgende Zeile nur dann aufrufst, wenn auch 
Checksummen-Bytes empfangen werden, dann ist keine weitere 
Unterscheidung nötig:
1
received_checksum = (received_checksum >> 8) | (((unsigned short) rs232_data)<<8);
#2714613
Lesenswert?

Kannst Du mir auf die Sprünge helfen wo ich mich vertan habe?

Es sollte so funktionieren, daß beim ersten Aufruf das empfangene 
Low-Byte zunächst als High-Byte vermerkt wird. Beim zweiten Aufruf wird 
das vorher empfangene Byte an die richtige Stelle geschoben und das 
zusätzlich empfangene Byte als High-Byte gespeichert.

Damit braucht man nur die Fall-Unterscheidung machen, ob 
Checksummenbytes empfangen werden oder nicht, sie sortieren sich dann 
selber.

Aber wenn ich da einen Denk- oder Umsetzungsfehler gemacht habe, nur her 
damit.
#2714685
Lesenswert?

Volkmar Dierkes schrieb:
> Kannst Du mir auf die Sprünge helfen wo ich mich vertan habe?

Das Low-Byte ist doch schon an der richtigen Stelle. Wenn Du das nochmal 
8 Bits nach rechts schiebst, ist es im Orkus.

Es gibt noch eine elegantere Lösung:
1
typedef union
2
{
3
  unsigned short s;
4
  struct
5
  {
6
    unsigned char lo;
7
    unsigned char hi;
8
  } b;
9
} hilo16_t;
10

11
hilo16_t received_checksum;
12

13
// erster Schleifendurchlauf
14
received_checksum.b.lo=rs232_data;
15

16
// zweiter Schleifendurchlauf
17
received_checksum.b.hi=rs232_data;
18

19
// 16 Bit-Wert benutzen
20
check_crc(received_checksum.s);

Damit gibts keine Bitschiebereien, sondern die Bytes landen gleich da, 
wo sie hinsollen.

fchk
Gast #2714766
Lesenswert?

Ich habe s jetzt so gemacht:
1
 if(i == 0)
2
 {
3
    // Das Low Byte der Checksummer
4
    received_checksum = (unsigned short) rs232_data;
5
 }
6
 else
7
 {
8
    // Das High Byte der Checksummer
9
    received_checksum |= ((unsigned short) rs232_data) << 8;    
10
 }
#2714986
Lesenswert?

Wutheini schrieb:
> Frank K. schrieb:
>> Es gibt noch eine elegantere Lösung:
> Und du bist dir sicher dass das ohne "#pragma pack" oder ähnlichen Kram
> überall funktioniert?

Nö. Und die Endianess ist auch wichtig. Weiß ich auch. Wenn aber der 
Rest der Applikation ohnehin sehr hardwarenah ist, spielt die 
Portabilität keine große Rolle mehr.

Man muss halt wissen, was man macht.

http://www-users.cs.york.ac.uk/susan/joke/foot.htm

fchk
#2714996
Lesenswert?

Frank K. schrieb:
> Wenn aber der Rest der Applikation ohnehin sehr hardwarenah ist,
> spielt die Portabilität keine große Rolle mehr.
Ich hab mir zum Prinzip gemacht, alles was über uart_putc und uart_getc 
liegt, hardwareunabhängig zu proggen. Wenn man tatsächlich mal ein 
Programm auf eine andere Zielarchitektur portieren muss, ist es durchaus 
von Vorteil eine klare Trennlinie zwischen hardwareabhängigem und 
hardwareunabhängigem Teil zu haben. Je weiter unten die Trennung 
erfolgt, desto schneller ist dann portiert.

Gruß Oliver

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren