Forum: Compiler & IDEs 24 Bit Variable in AVR-GCC


von Patrick B. (p51d)


Lesenswert?

Hallo miteinander.

Ich hab mal eine kleine Frage betreffend den Variablentypen:

Kann man bei AVR GCC irgendwie eine 24Bit Variable definieren?

ich kenne
- int (8Bit)
- uint_t 16 (16Bit)
- uint_t 32 (32Bit)
- uint_t 64 (64Bit)

da ich für ein "Zwischenspeichern" möglichst viele Werte in 2 Array's 
packen will (8Bit wert und 2 12Bit Werte) möchte ich ungern für die 2 
2Bitwerte eine 32Bit respektive zwei 16Bit Variablen nutzen, da ein Byte 
ungenutzt bleiben würde.
=> beide 12Bit Variablen in ein 24Bit-Array abspeichern, und 
entsprechend maskiert wieder auslesen.

Danke für die Antworten
MFG
P51D

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Wenn Du ein Bitfeld verwendest, sollten alle drei zusammen in einen 
32-Bit-Wert passen:

struct
{
  unsigned int wert1:8;
  unsigned int wert2:12;
  unsigned int wert3:12;
}

Der Zugriff auf die Elemente wird naturgemäß etwas langsam vonstatten 
gehen.

von Marcus O. (marcus6100)


Lesenswert?

Hallo Patrik,

da bietet sich eine Struktur mit Bitfeldern an.

typedef struct value_t
{
    uint8_t a;
    uint16_t b : 12;
    uint16_t c : 12;
} __attribute__((_packed_)) value_t;


value_t val;
sizeof (val) == 3


Hab ich jetzt aber nicht getestet.

Gruß
Marcus

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> value_t val;
> sizeof (val) == 3

Das sollte 4 ergeben, nicht 3.

von Patrick B. (p51d)


Lesenswert?

Rufus t. Firefly schrieb:
> Der Zugriff auf die Elemente wird naturgemäß etwas langsam vonstatten
> gehen.

langsam ist genau dass, was es nicht sein sollte.

Das ferne Ziel wäre es ein Buffersystem zu bauen, welches bis max 30'000 
Zustände an je wert1, wert2 und wert3 auszugeben.

sprich ist die hälfte der Zustände ausgegeben, sollte während die andere 
hälfte ausgegeben wird, die "lehre" hälfte wieder über die uart gefüllt 
werden => es sind immer Werte zum ausgeben vorhanden.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Patrick B. schrieb:

> langsam ist genau dass, was es nicht sein sollte.

Schnell und platzsparend passt halt selten zusammen.  Wenn du
nicht gerade auf einem 4-bit-Prozessor arbeitest, kannst du auf
12 bit breite Daten gepackt halt nur aufwändig zugreifen.  Wenn
dich das stört, musst du die 12 bit auf 16 bit aufblasen, dann
geht's wieder schneller, braucht aber 1/3 mehr Platz.

von Marcus O. (marcus6100)


Lesenswert?

@Rufus t. Firefly
hast Recht, da war ich etwas unaufmerksam.

@Patrick B.
So extrem langsam sollte das eigentlich nicht sein.

Wenn du einen kleinen Trick machst, und die oberen
4 bit der beiden 12 bit Werte im gleichen Byte speicherst,
dann kannst du noch etwas Zeit rausholen.

Angenommen du hast die Daten in r15:r16, r17:r18 und r19,
und y ist der zeiger, dann sollte das schreiben ungefähr
so aussehen.

swap r16
andi r16, 0xf0
andi r18, 0x0f
ori r16, r18
std y, r19
std y+1, r15
std y+2, r17
std y+3, r16

Und wenn du weißt, das die obersten 4 bit eh null sind, kannst
du die andi natürlich auch noch sparen.

Zerlegung ist analog.

Gruß
Marcus

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.