Ich verwende einen Atmega32 , um verschiedene Sensoren mit seinem ADC zu lesen.
Mit digitaler Logik und einigen Multiplexern habe ich die gesamte PORTA gemultiplext, wobei PA0: 6 als Adresse und PA7 als Eingang verwendet wurden. Daher kann ich maximal 128 Eingänge von nur einem PORT haben.
Da der Benutzer das System nun über einen Computer (mit RS232) bedient, können Sensoren hinzugefügt oder entfernt werden. Das System muss daher nachverfolgen, welche Adressen zum Hinzufügen von Sensoren frei sind und von welchen Adressen gelesen werden kann.
Ich dachte daran, ein boolesches 128-Bit-Array als Flags zu verwenden, um anzuzeigen, ob sich an einer bestimmten Adresse ein Sensor befindet.
Während C keine native Unterstützung für Einzelbitvariablen bietet, ist es möglich, Bitfelder zu verwenden, um bis zu 8 "Bool-Variablen" in ein einzelnes vorzeichenloses Zeichen zu packen.
Also habe ich die folgende Struktur erstellt:
typedef struct bool_s{
uint8_t bit1:1;
}bool_t;
Dann habe ich ein Array vom Typ bool_t mit einer Größe von 128 erstellt, in der Hoffnung, dass alles gut zusammen gepackt wird, aber sizeof()
mir wird gesagt, dass die Arraygröße 128 Bytes anstelle der 16 Bytes beträgt, die ich erwartet hatte.
Technisch könnte ich eine einzelne Struktur mit 128 1-Bit-Variablen erstellen:
typedef struct Flag_s{
uint8_t F1:1;
uint8_t F2:1;
uint8_t F3:1;
[...]
uint8_t F128:1;
}Flag_t;
Das Problem bei diesem Ansatz ist, dass er zwar die Speichernutzung reduziert, aber nicht sehr praktisch ist und viel zu viel Platz im Code einnimmt.
Gibt es eine einfache Möglichkeit, eine große Anzahl von Flaggen zu erstellen, oder verlange ich zu viel? Ich meine, es ist nicht so, als würde das Speichern von 112 Bytes einen großen Unterschied machen, wenn 2 KB verfügbar sind, aber was ist, wenn ich noch mehr Flags benötige?
Antworten:
Bitfelder funktionieren so nicht. Die Antwort von Cventu zeigt eine korrekte Verwendung, aber in diesem Fall empfehle ich, sie ganz zu vermeiden.
Erstellen Sie stattdessen ein Array mit 8-Bit-Werten und verwenden Sie Shifting und Masking, um darauf zuzugreifen:
Dies ist wahrscheinlich das, was der Compiler ohnehin mit Bitfeldzugriffen macht, und es ist einfacher, damit zu arbeiten. Einige Optimierer sind schlecht darin, Bitfelder zu optimieren, sodass der Compiler möglicherweise sogar schlechter abschneidet. Alle Compiler, die ich gesehen habe, wandeln Division und Modul durch eine konstante Zweierpotenz in Rechtsverschiebung und UND-Anweisungen um. Sie können diese Operationen direkt verwenden, wenn Sie sich paranoid fühlen:
Bitfelder ähneln eher Strukturen als Arrays. Nach meiner Erfahrung sind sie nur für Dinge nützlich, die Namen haben, wie z. B. Registerfelder.
quelle
<<
Operator generiert oder als Konstanten definiert wird mit Makros.Es klingt ein bisschen verwirrend, aber vielleicht kann so etwas helfen:
Nachdem Sie diese definiert haben, deklarieren Sie die folgende Variable:
Mit my_data.b können Sie eine ganze Gruppe von acht Bits zusammen schreiben
Oder Sie können jedes Bit einzeln schreiben mit: my_data.a.bit_7 (oder 6,5,4,3,2,1,0)
Wenn dies für Sie funktioniert, replizieren Sie dies 16 Mal (mithilfe eines Arrays oder einer Struktur), und Sie können 128 Bit einzeln verarbeiten.
Lassen Sie uns wissen, ob es funktioniert hat! Viel Glück
quelle
Erstellen Sie eine Struktur, in der Sie acht Bit-Flags deklarieren, die letztendlich ein Byte sind. Erstellen Sie dann ein Array dieser 8-Bit-Strukturen.
quelle