double bitweiseoperation?

OP #4247847
Lesenswert?
• ▲
▼
Hallo Community,

ich möchte mit einem Mikrocontroller CAN Nachrichten verschicken. Die 
Nachrichten sollen 8 Byte lang sein. Jetzt kann nur double 8 Byte 
speichern.
Aber wenn ich die Nachricht nachricht=0x1254674389543456 an meine 
Funktionübergeben möchte und dann auf die 4 Sende Buffer verteilen 
möchte, stellt sich der Compiler quer.

    C2TX0B1 = nachricht;
    C2TX0B2 = nachricht>>16;
    C2TX0B3 = nachricht>>32;
    C2TX0B4 = nachricht>>64;

Fehlermeldung:
error: invalid operands to binary >> (have 'double' and 'int')
error: invalid operands to binary >> (have 'double' and 'int')
error: invalid operands to binary >> (have 'double' and 'int')

mit int funktioniert es, aber ich möchte die Nachricht gerne am Stück 
übergeben.
Gast #4247853
Lesenswert?
• ▲
▼
Ein anderer Weg wäre, die Daten in einem Array zu speichern.

[c]
uint8_t data[8];

data[] = 0x12;
data[] = 0x54; // usw.

[/]

Deine Frageformulierung setzt allerdings voraus, dass die Daten schon in 
irgendeiner Form gespeichert vorliegen. Wenn nachricht selbst schon ein 
Array ist, dann erübrigt sich ein umspeichern und Du kannst direkt die 
Variable nachricht senden.

Möglicherweise ist aber das Problem noch nicht vollständig beschrieben 
oder von mir verstanden.
OP #4247864
Lesenswert?
• ▲
▼
Also ich habe einfach nur zum test erstmal:

double test = ox...; gemacht das sind meine Daten
Kann ich das array auch auf einmal komplett beschreiben und auslesen?

"ohne auf einzelne Plätze zuzugreifen"?

uint8_t blub[8];

z.B. blub[] = 0x46575364573892;
und aus lesen mit blub[] ?
OP #4247866
Lesenswert?
• ▲
▼
Wenn das nicht geht kann ich meinem Quellcode fast so lassen wie er ist, 
denn momentan speichere ich eine nachricht auf 4 Variablen. Aber ich 
möchte nicht immer 4 Variablen an die Funktion übergeben.

und mein Compiler streigt bei uint8_t data[8]; uint8_t ist ihm nicht 
bekannt
Gast #4247904
Lesenswert?
• ▲
▼
Dirk P. schrieb:
> C2TX0B1 = nachricht;
>     C2TX0B2 = nachricht>>16;
>     C2TX0B3 = nachricht>>32;
>     C2TX0B4 = nachricht>>64;

Aber schickst du nicht so in jedem Buffer die selben werte? Halt nur 
verschoben? du kannst ja eh nur 16(?) bits in einem buffer schreiben.
Wenn deine Nachricht
0x1254674389543456
ist,
dann schreibst du in C2TX0B2 gar ncihts mehr, da du alles rausgeschoben 
hast. Wenn ich richtig verstanden habe, möchtest du die Nachricht in den 
vier Buffern aufteilen?
dann würde ich

C2TX0B1 = (nachricht >> 0x14) & 0xFFFF; // (ergibt 0x1234)
C2TX0B2 = (nachricht >> 0x04) & 0xFFFF; // (ergibt 0x5678)
...

Oder ich habe es falsch verstanden, dann vergiss meinen Beitrag
Gast #4247907
Lesenswert?
• ▲
▼
C2TX0B1 = nachricht;

so so, da soll also eine Nachricht mit 8 Bytes auf ein Word abgelegt 
werden?

Ev. dafür eine Struc definieren.

Auf die schnelle habe ich das nur für Word_Byt  da:

union
{ u16 W2B;
  struct
  { u08 L;
    u08 H;
  } byte;
} W2B;

Anwendung:
  W2B.W2B           = EX1_Pressure;
  commandData[EX1H] = W2B.byte.H;
  commandData[EX1L] = W2B.byte.L;

Da wird ohne schieben direkt geladen.
#4247965
Lesenswert?
• ▲
▼
Dirk P. schrieb:
> und mein Compiler streigt bei uint8_t data[8]; uint8_t ist ihm nicht
> bekannt

Dafür gibt es die stdint.h, also binde die ein. Das setzt aber einen 
Compiler aus diesem Jahrtausend voraus. Die da definierten Typen sind 
übrigens äußerst praktisch, und uint64_t speichert 8 Bytes.

Ansonsten kannst du mal "long long" probieren, auch das müsste ein 
64-bit Datentyp sein (prüfe dann aber nach, ob "sizeof(long long) == 8" 
auch bei deinem Compiler gilt!)
#4248052
Lesenswert?
• ▲
▼
Dirk P. schrieb:
> nachricht=0x1254674389543456

Wenn nachricht eindouble ist, dann wird aber nicht das Bitmuster für die 
Integerzahl 0x1254674389543456 in nachricht abgelegt

>     C2TX0B1 = nachricht;
>     C2TX0B2 = nachricht>>16;
>     C2TX0B3 = nachricht>>32;
>     C2TX0B4 = nachricht>>64;
Das letzte sollte wohl 48 (statt 64) sein.

Dirk P. schrieb:
> denn momentan speichere ich eine nachricht auf 4 Variablen. Aber ich
> möchte nicht immer 4 Variablen an die Funktion übergeben.

Dann mach ein Array.
#4248141
Lesenswert?
• ▲
▼
Pieter schrieb:
> Ev. dafür eine Struc definieren.
>
> Auf die schnelle habe ich das nur für Word_Byt  da:

Ich hätte auf die schnelle eine für CANopen
1
typedef struct{
2
    CANOPEN_COBID   cobID;
3
    CANOPEN_RTF_DLC rtf_dlc;
4

5
    union{
6
        struct{
7
            CANOPEN_REQ     request;
8
            quint16         object;
9
            quint8          subindex;
10
            quint32         data_sdo;
11
        }sdo;
12
        struct{
13
            quint64         data_pdo;
14
        }pdo;
15
    };
16
}CANOPEN_MESSAGE;

SDO und PDO sind zwei verschiedene Zugriffsmoglichkeiten.
Würde genauso gehen mit:
1
     struct{
2
            quint64         data_pdo;
3
        }pdo;
4
        struct{
5
            quint8          data_bytes[8];
6
        }bytes;
oder jeder anderen beliebigen ...

<edit> (sorry für die Qt Typen)
Gast #4248171
Lesenswert?
• ▲
▼
Dirk P. schrieb:
> Also ich habe einfach nur zum test erstmal:
>
> double test = ox...; gemacht das sind meine Daten
> Kann ich das array auch auf einmal komplett beschreiben und auslesen?
>
> "ohne auf einzelne Plätze zuzugreifen"?
>
> uint8_t blub[8];
>
> z.B. blub[] = 0x46575364573892;
> und aus lesen mit blub[] ?

In dem Fall solltest Du Peter Danneggers Vorschlag folgen. (an stdint.h 
denken).

Falls Dein Compiler tatsächlich kein stdint kennt, kannst Du die 
tatsächlichen Grössen, sofern sie fraglich sind, in limits.h erkennen 
(sofern der Compiler wenigstens das kennt).

Wenn ich mir noch den Zusatz erlauben darf. Maßgeblich sind im ersten 
Schritt die Datentypen der Sendefunktion und der Daten, so wie sie in 
das System hineinkommen (also etwa Messwerte, Eingaben etc.). Im zweiten 
kann man sich den Unterschied zwischen den Typen anschauen und in der 
Regel relativ schnell (das geschieht meist routinemäßig) einen Ausdruck 
bzw. einen Ablauf formulieren der die Daten zwischen diesen entweder 
castet oder transportiert.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.