Forum: Compiler & IDEs Array für 20 bit ?


von AVRli (Gast)


Lesenswert?

Hallo!

Besteht die Möglichkeit ein Array mit 10 Werten zu definieren wo die 
Breite von jedem einzelnen Element 20bit ist? Wenn ja, wie? ;-)

Ich habe bisher nur 8,16 oder 32 Bit breite Array verwendet. Da der Wert 
aber nie mehr als 20 Bit haben wird, wäre es Verschwendung 10x32 Bit zu 
nehmen.

Dankbar für jeden Tip, AVRli...

von Sam .. (sam1994)


Lesenswert?

Nein, man kann nur ganze Bytes nehmen. Also hast du 3 Möglichkeiten:
- Du nimmst ein 13 Byte großes Array und schreibst die Bitgenaue 
Zugriffe
- Du verschenkst 12bit / Wert und nimmst ein 32bit Array
- Du verwendest den neuen Avrgcc 4.7.1 und benutzt den Typ __uint24 und 
verschenkst somit nur 4bit / Wert.

von xfr (Gast)


Lesenswert?

Wenns extrem kompakt sein soll, ginge auch ein Bitfeld:
1
struct feld {
2
  unsigned wert0 :20
3
  unsigned wert1 :20
4
  ...
5
  unsigned wert9 :20
6
}
Allerdings ist der Zugriff auf die Daten langsam und es ist kein Array.

24 Bit könnte man auch in einem struct ablegen:
1
struct element {
2
  uint8_t byte2
3
  uint8_t byte1
4
  uint8_t byte0
5
};
6
7
struct element feld[10];

Ist beim Zugriff etwas mühsam, wenn man mit dem ganzen Wert rechnen 
will. Wenn der Speicher nicht extrem knapp ist, würde ich einfach 32 Bit 
nehmen.

von Ingo (Gast)


Lesenswert?

Dafür gibts doch die Union.

von Helfender (Gast)


Lesenswert?

@Ingo: Wie?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Eine andere Möglichkeit:
1
struct array20 {
2
  uint8_t  high4[5];
3
  uint16_t low16[10];
4
} arr;
5
6
uint32_t read20(uint8_t i) {
7
  if(i&1)
8
    return arr.low16[i] | (uint32_t)arr.high4[i>>1] >> 4 << 16;
9
  else
10
    return arr.low16[i] | (uint32_t)(arr.high4[i>>1] & 0x0f) << 16;
11
}
12
13
void write20(uint8_t i, uint32_t val) {
14
  arr.low16[i] = (uint16_t)val;
15
  if(i&1)
16
    arr.high4[i>>1] = arr.high4[i>>1] & 0x0f | val >> 16 << 4;
17
  else
18
    arr.high4[i>>1] = arr.high4[i>>1] & 0xf0 | val >> 16;
19
}

Der Lesezugriff dauert 37, der Schreibzugriff 39-42 Taktzyklen (GCC
4.7.2), was IMHO gar nicht so schlecht ist. Du kannst ja mal mehrere der
vorgestellten Methoden gegeneinander laufen lassen, um die beste zu
finden.

Schneller und kürzer geht es aber auf jeden Fall, wenn du jedem Array-
Element 24 oder 32 Bits zugestehst. Bei nur 10 Elementen sollte das ja
auch nicht das große Problem sein.

von AVRli (Gast)


Lesenswert?

Yalu X. schrieb:
> Bei nur 10 Elementen sollte das ja
> auch nicht das große Problem sein.

Stimmt schon, nur ich wollte prinzipiell wissen ob es möglich ist und 
wenn ja wie. Danke für alle Ansätze, worüber ich mich wirklich gefreut 
habe.

Der Einfachheit halber werde ich 120 Bit verschenken, bei größeren 
Array's würde ich Deinen Vorschlag berücksichtigen. Derzeit 15 Byte für 
nix... hmmm schade ;-)


Gruß AVRli...

von amateur (Gast)


Lesenswert?

struct element {
  char etwas [ 3 ];      // 24 Bit
};
struct element feld[10]; // verschwendet 40 Bit bei 240 gesamt

char alle [ 25 ];        // Passt

Wenn du keinen Platz (RAM) und wenig Rechenzeit übrig hast, böte sich 
die erste Version an.

Hast Du noch weniger Platz, aber Rechenzeit über, so kannst Du via 
Bitpfriemelei alles in die zweite Version packen.

von Klaus (Gast)


Lesenswert?

AVRli schrieb:
> Der Einfachheit halber werde ich 120 Bit verschenken, bei größeren
> Array's würde ich Deinen Vorschlag berücksichtigen. Derzeit 15 Byte für
> nix... hmmm schade ;-)

Ich hab ein Deal mit meinem Distri gemacht. Für jedes Byte RAM, das ich 
endgültigen Design nicht verwende, bekomme ich eine Rückvergütung ;-)

MfG Klaus

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.