Guten Tag Ich schlag mich so ein bisschen mit Strukturen herum und bin etwas genervt. Genaugenommen geht es im Bitfeldern die ich so definiert habe. int main() { struct { unsigned char status:1; // 1 Bit für bStatus_1 unsigned char status1:1; // 1 Bit für bStatus_1 unsigned char status2:1; // 1 Bit für bStatus_1 unsigned char status3:1; // 1 Bit für bStatus_1 unsigned char status4:1; // 1 Bit für bStatus_1 } byte; while(1) { } } Das funktioniert aus soweit ganz gut, mit bit.status1 u.s.w kann ich alles mit den bits machen. Jetzt dachte ich ich könnte die so veränderten bits nun in den Porta schreiben. Also PORTA = byte; // Der Inhalt von byte wird in den PORTA kopiert geht aber nicht?? Warum, oder wie geht das kopieren. Danke
oder mit einer union... Man muss sich aber bei beiden Varianten klar darüber sein, dass der C-Standard nicht definiert, in welcher Reihenfolge die Bits in einem Bitfeld abgelegt werden. Ausprobieren...
Die union-Variante geht dann z.B. so:
1 | union
|
2 | {
|
3 | struct
|
4 | {
|
5 | unsigned char status:1; |
6 | unsigned char status1:1; |
7 | unsigned char status2:1; |
8 | unsigned char status3:1; |
9 | unsigned char status4:1; |
10 | };
|
11 | unsigned char byte; |
12 | } bit_byte; |
13 | |
14 | bit_byte.status = 1; |
15 | PORTA = bit_byte.byte; |
Oliver
OliverSo wrote: > Die union-Variante geht dann z.B. so: > [...] Exakt. Der AVR-GCC legt übrigens afaik die einzelnen Bitfeld-Elemente "von hinten" ab, also das erste Element des Bitfeldes (im Beispiel status ) am niederwertigen Ende des Bytes (also im Bit Nummer 0).
Die genannte Variante ist IMHO nicht portabel, sondern eine GCC- Erweiterung. Die portable Variante müsste der bitfield-struct noch einen Namen geben:
1 | union
|
2 | {
|
3 | struct
|
4 | {
|
5 | unsigned char status:1; |
6 | unsigned char status1:1; |
7 | unsigned char status2:1; |
8 | unsigned char status3:1; |
9 | unsigned char status4:1; |
10 | } bits; |
11 | unsigned char byte; |
12 | } bit_byte; |
13 | |
14 | bit_byte.bits.status = 1; |
15 | PORTA = bit_byte.byte; |
Jörg Wunsch wrote: > Die genannte Variante ist IMHO nicht portabel, sondern eine GCC- > Erweiterung. Die portable Variante müsste der bitfield-struct > noch einen Namen geben: Stimmt natürlich. Das hatte ich übersehen. Funktioniert das ohne Namen im GCC tatsächlich?
Johannes M. wrote: > Funktioniert das ohne Namen > im GCC tatsächlich? Ja. ;-) http://gcc.gnu.org/onlinedocs/gcc-4.2.3/gcc/Unnamed-Fields.html#Unnamed-Fields
Hallo, schon mal danke, ich werde die Sachen mal ausprobieren. Ich finde es ein bisschen Schade das gcc von Standarts abweicht die sich bei (teuren) Compilern so eingebürgert haben. Z.B. macht Keil das mit " #byte " und " #bit ". Das ist sehr einfach und spart Programmierarbeit. Habe bisher die Assembler Technik genutzt und Bits numeriert um sie später mit einem Byte zu maskieren. Aber mit "if(Byte & (1<<Bit)) u.s.w" bricht man sich die Finger. unsigned int abzukürzen ist ja ganz toll, aber uint16_t ist auch nicht der Hit, wenn man nicht blind zehn Finger schreiben kann. Zugegeben haben Strukturen mehr Möglichkeiten, aber bits zu setzen finde ich so wichtig das man den Elektrotechniker und Nichtinformatiker ein bisschen unterstützen sollte.
bernd wrote: > Hallo, schon mal danke, ich werde die Sachen mal ausprobieren. Ich finde > es ein bisschen Schade das gcc von Standarts abweicht die sich bei > (teuren) Compilern so eingebürgert haben. Falsch ! Das sind eben keine Standards, sondern willkürliche Erweiterungen einiger kommerzieller Embedded-C-Compiler, die nicht vom ANSI-Standard abgedeckt sind. Außerdem kocht da praktisch jeder Anbieter sein eigenes Süppchen, weshalb die Sachen auch bei einer Plattform i.d.R. nicht portierbar sind. Der AVR-GCC ist im Großen und Ganzen ein ANSI-C-Compiler, der zwar mittlerweile auch einige µC-spezifische Erweiterungen bietet, die für notwendig bzw. wirklich sinnvoll erachtet wurden (z.B. Eingabe von Binärzahlen mit 0bxxxx), die aber vom ANSI-Standard nicht abgedeckt werden. Ansonsten kommt man gar nicht erst in Versuchung, Code zu schreiben, den andere C-Compiler nicht verstehen. Hier im Forum tauchen des öfteren Anfragen auf nach dem Motto "Hilfe! Habe Programm für Compiler XYZ geschrieben und es lässt sich mit Compiler ZYX nicht compilieren...". Die Standard-konformen Schreibweisen versteht jeder C-Compiler, der den Namen zu Recht trägt. Einzige Ausnahme bilden dann allerdings trotz allem die µC-spezifischen Bibliotheksfunktionen. Die meisten "Vereinfachungen" der kommerziellen Compiler täuschen auch darüber hinweg, was im Hintergrund abläuft. Und das kann gerade bei Hardware-nahen Anwendungen schonmal zu langen Fehlersuchen führen, wenn man als Programmierer nicht mal weiß, was da eigentlich passiert.
bernd wrote: > später mit einem Byte zu maskieren. Aber mit "if(Byte & (1<<Bit)) u.s.w" > bricht man sich die Finger. .... > Zugegeben haben Strukturen mehr Möglichkeiten, aber bits zu setzen finde > ich so wichtig das man den Elektrotechniker und Nichtinformatiker ein > bisschen unterstützen sollte. Was hindert dich daran, dir selbst mit Standard-C ein paar Hilfsfunktionen bzw. Makros zu schreiben, so dass du dir nicht mehr die Finger brichst? Im Übrigen wird die reine Tipparbeit überschätzt. Das Problem beim Programmieren ist ja nicht das Drücken von Tasten sondern die Logik die es umzusetzen gilt.
bernd wrote: > Aber mit "if(Byte & (1<<Bit)) u.s.w" > bricht man sich die Finger. Das eigentliche Übel ist, dass die Bitkonstanten nicht gleich als Masken definiert worden sind, sondern als Bitnummern. Das wiederum hat seine Ursache darin, dass die entsprechenden Bitnamen auch in Assemblercode verwendbar sein sollten, und dass dort Befehle wie CBI oder SBI eine Bitnummer brauchen. Von einer Nummer auf eine Maske ,,rechnen'' ist trivial, eine Maske in eine Nummer zurückzu- rechnen leider nicht. Du kannst dir das 1<< ja in einem Makro vereinfachen. avr-libc bietet dir dafür den Makro _BV() bereits vorgefertigt an. > unsigned int abzukürzen ist ja ganz toll, aber uint16_t ist auch nicht > der Hit, wenn man nicht blind zehn Finger schreiben kann. Das ist aber C99-Standard. Es hat nichts mit ,,abkürzen'' zu tun, sondern besagt, dass der entsprechende Datentyp unabhängig von der verwendeten Umgebung eben genau 16 bits breit (und vorzeichenlos) ist. Das ist für "unsigned int" nicht gegeben, das kann durchaus auch 32 bits breit sein.
OK OK OK mit Standarts meinte ich jetzt nicht das es quasi genormt ist, sondern wie ja schon gesagt wurde sich um -> sinnvolle <- Erweiterungen handelt, die aber bei jeden teuern Compiler eben vorhanden sind. Ich habe das mal ausprobiert und die Strukturen lassen sich nicht vernümftig watchen. Es wird bei jedem Bit der Byte Wert angezeigt. Zum Debuggen mist, da sich die Bits auch nicht immer mit den Werten setzen lassen (1,2,4,8 u.s.w). Ach ja, ich nutze AVR Studio mit gcc. Werde wohl doch wieder maskieren. Son shit. Habe mal einem Informatiker über die Finger geschaut, da bekommt man ja Augenkrebs. Die nehmen auch für alles Bytes, ist ja auch egal.
Pssss bernd Ist jetzt nicht wirklich wichtig, aber es heist Standard. Hinten mit 'd'.
bernd wrote: > wie ja schon gesagt wurde sich um -> sinnvolle <- Erweiterungen handelt, > die aber bei jeden teuern Compiler eben vorhanden sind. Du kennst ,,jeden teuren'' Compiler? Ich kenne zumindest einen, der zu den teuersten zählt (und vom generierten Code her zu den besten), aber der hält sich mit allem an den C-Standard und die durch den Standard vorgegebenen Syntaxregeln der Sprache. Das bedeutet nicht, dass er keine Erweiterungen hätte (die hat wohl jeder Compiler), aber er bewegt sich mit seinen Erweiterungen (genauso wie GCC) zumindest im durch den Standard vorgegebenen Rahmen.
Das in Foren immer sofort gestritten werden muss kann ich echt nicht nachvollziehen, und einige scheinen Deutschlehrer zu sein. Dabei braucht man nachgewiesener Maßen nur Anfangs und Endbuchstaben eines Wortes um den Satz lesbar zu machen. Da finde ich es schwierieger sinnlos herunterzuscrollen um eine richtige Antwort zu finden. Wer sich noch fürs Thema interessiert: Keil Compiler 8051 und MPLap für Pics z.B. besitzen die #Bit und #Byte Befehle. Standar(d) hin oder her, es zählt was sich durchsetzt und sinnvoll ist. Und das ist struct bei bitfelder in keinster Weise, zumindest nicht bei 8Bit Prozessoren. Ob das Kernigham und Ritchi so wollten ist denen wahrscheinlich ebenso egal wie mir. Die Frage steht also noch im Raum ob es eventuell duch eine .h eine bessere Lösung gibt die auch in AVR Studio debugged werden kann. bools mit endsprechende .h benutzen ja auch immer 1Byte.
bernd wrote: > Keil Compiler 8051 und MPLap für Pics z.B. besitzen die #Bit und #Byte > Befehle. Standar(d) hin oder her, es zählt was sich durchsetzt und > sinnvoll ist. Und wer definiert, was sich ,,durchgesetzt'' hat? Irgendwelche mittelprächtigen Compiler? Keil hat mich vor knapp 20 Jahren mal über einen Arbeitstag gekostet um rauszufinden, dass sie in ihrer OS-9-Version für den m68k nicht in der Lage waren, mit Variablen in geschachtelten Blöcken ordentlich umzugehen (der Platz wurde nicht während des gesamten Funktionslaufs, sondern erst am Beginn des Blocks auf dem Stack eingeräumt, dann aber nie wieder ausgeräumt). Irgendjemand bestätigte mir kürzlich, dass dieses Problem immer noch existiere... Durchgesetzt? Durchgesetzt hat sich wohl ganz eindeutig GCC, und IAR sicher auch. Für Keil kenne ich außer Peter Dannegger (und von mir aus dir) kaum einen, der sich über dessen Qualitäten begeistert geäußert hätte, dafür aber genügend, die mir gesagt haben, dass sie froh sind, dieses Teil dank GCC (und Wechsel von MCS51 weg) nicht mehr benutzen zu müssen. IAR hat zumindest insgesamt eine sehr gute Reputation (und einen extremen Preis), und das interessanterweise, obwohl er mit Erweiterungen wohl eher sparsam umgeht.
Ich habe nie behauptet das ich die Programmer unheimlich toll finde. Es ist die eine Funktion. Ich muss Beruflich Pics, AVRs und Fujitsus Programmieren und mich zwangsläufig auch mit den Compilern auseinandersetzen. Dafor hatte ich es eben mit Keil und diverser damaligen "Puplic Domain" Software zu tun. Alle hatten Qualitäten und Nachteile. Das es AVR Studio nicht auf die Reihe bekommt beim watchen auch eine Bit Anzeige zu machen ist ein weiteres Manko.
bernd wrote:
> Ich habe nie behauptet das ich die Programmer unheimlich toll finde.
(Programmer? Oder Compiler?)
...aber bescheinigst ihnen, dass sich da irgendeine ihrer Erweiterungen
,,durchgesetzt'' hätte...
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.