Forum: Mikrocontroller und Digitale Elektronik double bitweiseoperation?


von Dirk P. (crunso)


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.

von Klaus (Gast)


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.

von Klaus (Gast)


Lesenswert?

Ups.

Es muss natürlich heissen:

1
uint8_t data[8];
2
3
data[7] = 0x12;
4
data[6] = 0x54; // usw.

von Peter D. (peda)


Lesenswert?

Dirk P. schrieb:
> Jetzt kann nur double 8 Byte
> speichern.

Nö.
1
#include <stdint.h>
2
  uint8_t blub[8];
3
// oder
4
  uint64_t bla;

von Dirk P. (crunso)


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[] ?

von Dirk P. (crunso)


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

von Johannes (Gast)


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

von Pieter (Gast)


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.

von S. R. (svenska)


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!)

von Dirk B. (dirkb2)


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.

von Volker S. (vloki)


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)

von Klaus (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.