# daveWriteBytes HILFE



## TheEngineer0815 (18 März 2009)

Hallo!

bräuchte mal wieder Hilfe, verstehe das mit dem buffer in WryteBytes nicht ganz!

Ich habe z.B einen Wert der in einer integer Variablen drinn steht und möchte den in ein Word auf die SPS schreiben.

Integer hat bei C nunmal 4 Bytes, das Word nur 2 Bytes.

Wenn ich nun die Adresse der Variablen übergebe, werden dann nur die ersten beiden Bytes in die SPS übertragen? und die beiden höheren ignoriert?

Gibt es in de library eine Funktion mit der ich das bigEndian und littleEndian problem lösen kann? oder muss ich mich diesmal quasi selbst darum kümmern? 

Danke


----------



## Thomas_v2.1 (18 März 2009)

Hi!

Zeig doch mal ein Codeschnipsel wie du versuchst den Wert zu schreiben.



TheEngineer0815 schrieb:


> Integer hat bei C nunmal 4 Bytes, das Word nur 2 Bytes.



Das ist nicht richtig.
Im C-Standard ist nur festgelegt dass ein Integer _wenigstens _16 Bit haben _muss_. Meistens ist ein Integer aber die natürliche Größe des Prozessors. Auf einem aktuellen x86 dann z.B. 4 Bytes, auf einem 8-Bit AVR hat ein Integer auch nur 2 Bytes.
Den Datentyp Word gibt es im C-Standard gar nicht.

Um Datentypen mit fester Bit-Breite zu benutzen, müsstest du einen C-Compiler nach dem C99 Standard nehmen. Im Header "stdint.h" gibt es dann z.B. den Datentyp uint16_t der fest 16 Bit breit ist.


----------



## TheEngineer0815 (19 März 2009)

So Problem nach einigen Stunden des probierens gelöst!

Integer hat auf meinem Rechner 32 Bit -> Merkeerdoppelworr

Short Integer 16 Bit -> Merkerwort

Hab in CVI eine Library gefunden die das Problem mit den Endians für mich erledigt.

Sollte ich jetzt noch einzelne Bits übertragen wollen "ver-oder" ich die direkt in die Integer an die richtige Position und lass nur ein Byte abschicken.

LG


----------



## Rainer Hönle (19 März 2009)

Ich rate zur Vorsicht. Das Schreiben von einzelnen Bits über ein Byte zu realisieren (wenn nicht alle 8 Bits geschrieben werden sollen) ist gefährlich da die nicht maskierten Bits auch auf einen Wert gesetzt werden. Beim Lesen spielt dies keine Rolle.


----------



## Zottel (19 März 2009)

Du brauschst kein Extra-Bibliotheken:
Wenn du z.B den Wert 4 schreiben willst, erzeugst du eine Variable vom typ int oder short, ganz wie du möchtest.
int i =4;
// in der Variablen steht jetzt: 0x04 0x00 0x00 0x00
i=daveSwapIed_16(i);
// in der Variablen i steht jetzt: 0x00 0x04 0x00 0x00
Das kannst du writeBytes ohne weiteres übergeben:
daveWriteBytes(dc, ....,2, &i);  // die Länge muß 2 sein!
Warum geht das? 
daveSwapIed_16() erwartet eine Parameter vom typ unsigned short und gibt den auch zurück.
Der Compiler übergibt: 0x04 0x00
daveSwapIed_16() dreht die Bytes 0 und 1 und gibt 0x00 0x04 zurück.
Bei der Zuweisung an i (int) kopiert der Compiler diese beiden Bytes und füllt mit 0x0 auf.
Die Benutzung von daveSwapIed_16() hat folgenden Vorteil:
Ied steht für If endiannes differs.
daveSwapIed_16() tut nur etwas, wenn die ausführende Maschine little endian ist.
Du kannst das unveränderte Programm auch für Power PC oder so etwas kompilieren.


----------



## Zottel (19 März 2009)

Eine andere Gruppe von Funktionen kommt ins Spiel, wenn du mehrere Variablen, die in der SPS hintereinanderliegen, auf einmal schreiben willst.
Stell dir vor, du hast in einem DB oder im Merkerbereich:
INT   MW0
REAL MD2
DINT MD6

```
//Du brauchst zunächst einen Puffer mit genügend Bytes
char buf[100];
//und einen Zeiger darauf:
char * p=&buf[0];
p=davePut16(p,4); legt die 4 als big endian 16_bit integer in b[0],b[1] ab.
// p zeigt danach auf b[2]
p=davePutFloat(p,4.444); legt die 4.444 als big endian single in b[2] bis b[5] ab.
// p zeigt danach auf b[6]
p=davePut32(p,4); legt die 4 als big endian 32_bit integer in b[6] bis b[9] ab.
// p zeigt danach auf b[10]
//den Pufferinhalt kann daveWriteBytes nun in einem Rutsch schreiben:
daveWriteBytes(dc, ...,10,b);
```


----------

