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
Hallo! Ich habe gestern einen Blick in das avr-gcc Tutorial geworfen, und von "Bitfeldern" gehört: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Bitfelder Laut Beschreibung (bin zum ersten Mal auf das Konstrukt gestossen) sollte das genau das sein, was Du suchst? SalutI! Ludwig
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
> 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.
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:
1 | struct { |
2 | unsigned char bStatus_1:1; // 1 Bit für bStatus_1 |
3 | unsigned char bStatus_2:1; // 1 Bit für bStatus_2 |
4 | unsigned char bNochNBit:1; // Und hier noch mal ein Bit |
5 | unsigned char b2Bits:2; // Dieses Feld ist 2 Bits breit |
6 | // All das hat in einer einzigen Byte-Variable Platz.
|
7 | // die 3 verbleibenden Bits bleiben ungenutzt
|
8 | } x; |
Warum muss denn jetzt vor jedes Bit/Bitpaar noch "unsigned char stehen" ? Wenn ich
1 | struct { |
2 | unsigned char bStatus_1:1; // 1 Bit für bStatus_1 |
3 | } 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!
+ [/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...
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.
@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.
> 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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.