mikrocontroller.net

Forum: Compiler & IDEs 2bit array[ ] ?


Autor: tronic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo mal wieder,

eine 8bit Variable definiert man ja so:

uint8_t variable;

ich hab nun 30 Module die entweder den Zustand "0" oder "1" haben,
diese Zustände möchte ich möglichst in einem array speichern.

uint8_t array[30];

so ein array verbraucht viel platz, ist auch nur ein 2bit array
möglich?
wie sieht der code hierfür aus?

thx
tronic

Autor: tronic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
äh natürlich ein 1-bit array nicht 2

Autor: Ludwig Meyerhoff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe gestern einen Blick in das avr-gcc Tutorial geworfen, und von
"Bitfeldern" gehört:
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Laut Beschreibung (bin zum ersten Mal auf das Konstrukt gestossen)
sollte das genau das sein, was Du suchst?



SalutI!

Ludwig

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wär's mit einem 32 Bit Integer? Da haben 32 x (0 oder 1) Platz in
bloss vier Bytes! ;o))

#define MyBit0 = 0x00000001UL
#define MyBit1 = 0x00000002UL
#define MyBit2 = 0x00000004UL
#define MyBit3 = 0x00000008UL
#define MyBit4 = 0x00000010UL
#define MyBit5 = 0x00000020UL
//etc...

uint_32t MyFlags;

Falls Du ein 8 Bit-uC verwendest(z.B. den AVR), dann wird es natürlich
effizienter, wenn Du stattdessen 4 x uint_8t statt 1 x uint32t
benutzt:

uint_8t MyFlagsA,MyFlagsB,MyFlagsC,MyFlagsD;
// oder auch als Array
uint_8t MyFlags[4]   // => MyFlags[0..3]

Du musst Dir dann halt merken, welches Flag-Bit in welchem Byte steht!

C bietet sogar die Möglichkeit, Strukturen Bit-Weise zu definieren,
hab's aber noch nie verwendet, da es ohne genau so gut geht!

Gruss Peter

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> C bietet sogar die Möglichkeit, Strukturen Bit-Weise zu
> definieren, hab's aber noch nie verwendet, da es ohne genau so gut
> geht!

Das sind die Bitfelder, von denen Ludwig schreibt. Sie eignen sich
hervorragend dafür. Man muß allerdings beachten (egal welche Methode
man verwendet), daß durch die Bitschubsereien der Code ein Stück größer
wird. Man erkauft sich also die RAM-Ersparnis mit mehr Codegröße. Aber
man hat ja meistens mehr Code- als Datenspeicher überig.
Ach ja, bei manchen Controllern, wie z.B. dem Atmega88 gibt's auch
noch (ich glaub' drei) I/O-Register, die vom Benutzer beliebig
verwendet werden können. Da der Prozessor spezielle Instruktionen zum
Ändern und zum Abfragen eines I/O-Regiter-Bits hat, gibt's hier den
Overhead nicht. Auf anderen Controllern dürften sich bei akutem
Platzmangel auch unbenutzte I/O-Register zweckentfremden lassen, Z.B.
ein OCR-Register, wenn man die entsprechende Compare-Unit nicht
benutzt.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für zwei Zustände braucht man übrigens nur 1 bit...

PS: Kleine Frage zu den Bitfeldern. Dazu nehme ich mal das Beispiel aus
dem Tutorial:
struct {
   unsigned char bStatus_1:1; // 1 Bit für bStatus_1
   unsigned char bStatus_2:1; // 1 Bit für bStatus_2
   unsigned char bNochNBit:1; // Und hier noch mal ein Bit
   unsigned char b2Bits:2;    // Dieses Feld ist 2 Bits breit
   // All das hat in einer einzigen Byte-Variable Platz.
   // die 3 verbleibenden Bits bleiben ungenutzt
} x;

Warum muss denn jetzt vor jedes Bit/Bitpaar noch "unsigned char
stehen" ?

Wenn ich
struct {
   unsigned char bStatus_1:1; // 1 Bit für bStatus_1
} x;

definiere, ist dann sizeof(x) == 1 ? Sprich 8 Bit groß, nur 7 Bits
werden nicht benutzt?

Würde das heißen, dass sizeof(x) bei folgendem Fall 2 sein wird?
(Sprich 2 Bytes werden reserviert, 7 Bits ungenutzt)

[C]
struct {
   unsigned char bStatus_1:8;
   unsigned char bStatus_2:1;
} x;


Danke schonmal!

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
+ [/C]


Achja: Bitfeldoperationen sollten (beim AVR zumindest) doch nicht
langsamer oder größer als "normale" Variablenoperationen.

Dabei denke ich an Anweisungen wie sbr, cbr etc...

Autor: tronic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das problem ist das ich die Zustände nur durch eine Zählschleife einfach
übergeben möchte,
also von 1-30 zählen, und den abgefragten Zustand (1 oder 0) zuweisen.
wenn ich  4 variablen à 8bit habe geht das komplizierter, als wenn man
einfach ein 1Bit array[]
durchnummeriert...
gibts hierfür was?
thx.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@tronic

Dafür gibts nichts in C. Es gibt kein 1-Bit-Array.

@Simon
> Warum muss denn jetzt vor jedes Bit/Bitpaar noch "unsigned char
> stehen" ?

Bei einem einzelnen Bit macht das zugegebenermassen nicht
wirklich Sinn. Aber ein 2-Bit Bitfeld (oder größer) könnte
theoretisch auch 'signed' sein. Kommt zwar selten vor,
ist aber möglich. Und es muss auch nicht char sein. Wenn
du 16 Bits brauchst (und ein int 16 Bits gross ist, dann
spricht nichts dagegen die Bits in einen signed/unsigned
int hineinzupfriemeln.

> definiere, ist dann sizeof(x) == 1 ? Sprich 8 Bit groß, nur 7 Bits
> werden nicht benutzt?

Ja. Kleiner als sizeof(x) == 1 geht nicht. (*)

> Würde das heißen, dass sizeof(x) bei folgendem Fall 2 sein wird?
> (Sprich 2 Bytes werden reserviert, 7 Bits ungenutzt)

Ganz genau.
sizeof ist immer eine ganze Zahl. (*)

> doch nicht langsamer oder größer als "normale"
Variablenoperationen.

Doch, natürlich. Dein µC arbeitet ja genauso Byte-orientiert.
Wenn du nur ein Bit setzen willst, muss trotzdem das komplette
Byte aus dem Speicher geholt werden. Dann wird das Bit gesetzt
und das Byte zurückgeschrieben. Dem gegenüber steht eine Zuweisung
an einen normalen unsigned char, bei dem der vorhergehende Zustand
des kompletten Bytes völlig uninteressant ist.
Im Grunde kann der Compiler auch nicht zaubern. Um ein Bit zu setzen
kommt er nicht an
   x = x | Maske;
vorbei. Nur sparst du dir halt mit Bitfeldern den Schreibaufwand.
Den übernimmt dann der Compiler für dich.


(*) Das hat beides damit zu tun, dass man ja mit diesem struct
wieder Arrays aufbauen können muss.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl Heinz: Danke für die Erläuterung. Damit wäre für mich alles
geklärt ;)

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Achja: Bitfeldoperationen sollten (beim AVR zumindest) doch nicht
> langsamer oder größer als "normale" Variablenoperationen.
>
> Dabei denke ich an Anweisungen wie sbr, cbr etc...

sbr ist nur ein anderer Name für ori, cbr für andi. Deshalb hat der AVR
hier keinerlei Vorteil durch diese Befehle. Und dann kommt der von Karl
Heinz erwähnte Speicherzugriff dazu. Nur bei I/O-Registern hat der AVR
mit sbi und cbi die Möglichkeit, direkt einzelne Bits zu ändern und mit
sbic und sbis basierend auf ihnen zu verzweigen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.