Hallo! Ich beschäftige mich gerade mit dem 8051 und hab da eine Frage. Ich hab ein Programm in C vorliegen bei dem das hier drinne steht: bit _sw1; bit _sw2; P5 |= 0x0F; P5 &= ~0xF0; _sw1 = P5 & 0x01; _sw2 = P5 & 0x02; Steht in _sw2 eine 1 oder eine 0?
Da dieser Datentyp im offiziellen C nicht vorkommt ist einzig das Handbuch des Compilers die Referenz.
Knut schrieb: > _sw1 = P5 & 0x01; Offensichtlich benutzt dein Programm die Bit-Befehle des 8051 überhaupt nicht. Das ist die ganz normale Bitpfriemelei wie bei jedem anderen Prozessor auch. Wenn das alles ist, sind die 8051-Bitbefehle nur per Assembler benutzbar. Georg
Der Keil C-Compiler kennt auch den Datentyp "bit". Der 8051 hat einen Bereich im Speicher, der für Bits und Befehle dazu besonders geeignet ist. Näheres findest du im Compiler Handbuch. Was in sw2 steht, ist mit deinem Programmschnipsel nicht zu sagen. Die Ports sind halbwegs bidirektional (Prozessor Handbuch lesen). Bei offenem Port wird es eine 1 sein. Wenn der Port extern nach GND geschaltet wird, wird es eine 0.
Was ist bit für ein Datentyp? Wenn es sich um einen boolschen Typ handelt, ist das Programm murks. Und was soll der Blödsinn P5 |= 0x0F; P5 &= 0x0F; Und dann noch ... = P5 & 0x0... Um welches Fach und welche Jahrgangsstufe handelt es sich?
Also die Aufgabe lautet wie folgt: Gegeben ist das nachfolgende C-Programm von einem Tresor-Schloss für den C8051F020/21. An den Mikrocontroller sind zwei Taster SW1 und SW2 angeschlossen, die bei Betätigung eine logische 0 an dem Port-Bits P5.0 bzw. P5.1 liefern. An P5.7 ist über einen Verstärker ein automatischer Öffner angeschlossen, der bei P5.7 = 1 die Tresortüre entriegelt. (a) Kommentieren Sie die Programmzeilen nach dem //. (b) Knacken Sie das Tresor-Schloss! Welche Tastenfolge muss an SW1 und SW2 eingegeben werden, damit sich der Tresor öffnet ? (c) Wieviele Versuche hat man, falls man sich bei der Code-Eingabe versehentlich vertippt ? Beachten Sie: Der Port P5 kann nur als ganzes Byte gelesen und geschrieben werden! Code: void main ( void ) { bit _sw1; bit _sw2; char a = 1; char b = 1; P5 |= 0x0F; // P5 &= ~0xF0; // _sw1 = P5 & 0x01; // _sw2 = P5 & 0x02; // while(1) // { if ( !(P5 & 0x01) && (_sw1 == 1) ) a++; // _sw1 = P5 & 0x01; // if ( !(P5 & 0x02) && (_sw2 == 1) ) b++; // _sw2 = P5 & 0x02; // delay(1000); // einen kurzen Moment warten if (a == 2 && b == a+2) P5 |= 0x80; // } }
Der Keil C51 kennt Bitvariablen. Knut schrieb: > _sw1 = P5 & 0x01; Sollte funktionieren. Knut schrieb: > _sw2 = P5 & 0x02; Das könnte compilerabhängig sein bzw. sollte eine Warnung erzeugen. Um sicher zu sein, schreibt man besser: _sw2 = !!(P5 & 0x02);
Peter Dannegger schrieb: > Das könnte compilerabhängig sein Nicht nur, das hängt auch ganz wesentlich vom Prozessor ab. Angefangen damit, was ein Input-Befehl eigentlich liest: den Zustand am Pin, ein Inputregister oder ein Outputregister. Besonders der Original-8051 erszugte hübsche Nebenwirkungen mit seinen OC-Ausgängen, bei denen Output-Befehle die Inputdaten beeinflussen und das noch abhängig von der Beschaltung. Dafür kann der Compiler aber nix. Georg
Egal was vom Port gelesen wird, der 8 Bit Ergebnistyp wird dem 1 Bit bool zugewiesen. Das ist nicht gut, gar nicht gut, ...
Knut schrieb: > _sw1 = P5 & 0x01; > _sw2 = P5 & 0x02; wenn der Compiler Bitadressen unterstützt dann würde man eher _sw1 = P5.0; _sw2 = P5.1; schreiben. MfG
einer schrieb: > wenn der Compiler Bitadressen unterstützt dann würde man eher > > _sw1 = P5.0; > _sw2 = P5.1; Das geht so nicht, weil: Knut schrieb: > Beachten Sie: Der Port P5 kann nur als ganzes Byte gelesen und > geschrieben D.h: P5 ist nicht bit-addressierbar.
Hallo Knut, die Ports der 51er sind natürlich bitadressierbar! >_sw1 = P5 & 0x01; >_sw2 = P5 & 0x02; >Steht in _sw2 eine 1 oder eine 0? Im Codeschnipsel ist zu erkennen, dass der Zustand von Portbit P5.0 nach _sw1, und der Zustand von Portbit P5.1 nach _sw2 kopiert wird. Ob nun eine "1" oder eine "0" kopiert wird, hängt von den Zuständen am Port 5 ab. Allerdings ist es nicht wirklich schöner Programmierstil. Als kleine Anmerkung: Bei MCS51 Kontrollern sind alle SFR (Special Funktion Register (Adressbereich 80h-F0h)), deren Adresse ganzzahlig durch 8 teilbar sind, bitadressierbar. Also Alle mit den Adressen x0h und x8h (Bitadressen 80h-FFh). Im direkt adressierbaren Speicher sind die Speicherbyte 20h-2Fh bitadressierbar (Bitadressen 00h-7Fh). Die Ports der 51er liegen alle auf bitadressierbaren SFR-Adressen. Gruß. Tom
Nachtrag Der schönere Schreibstil wäre gewesen: _sw1 = P5_0; _sw2 = P5_1; Ich hoffe das bringt dich etwas weiter. Gruß. Tom
TomA schrieb: > Die Ports der 51er liegen alle auf bitadressierbaren SFR-Adressen. Das trifft aber nur für die Ports 0 bis 3 zu. Beim 8051F020 liegen P4 bis P7 auf den nicht Bit-adressierbaren Adressen 84, 85, 86 und 96.
Hallo Dieter Werner, danke für den Hinweis. Bei den ursprünglichen 51ern mit mehr Ports (80535...) ist es auch so. Mit den Silabs hatte ich noch nicht gearbeitet. In dem Fall wäre die Schreibweise des angegebenen Programms richtig, es funktioniert dann auch mit den erweiterten Ports. Allen einen guten Rutsch ins neue Jahr. Und denkt daran, nicht mehr trinken, als mit Gewalt runter geht, sonst ist es unbekömmlich. :P Gruß. Tom
Ein Frohes Neues Jahr und auch in 2015 kann man 8 Bit nicht auf 1 Bit schrumpfen. Wenn schon, dann so
1 | _sw1 = (P5 & 0x01) != 0; |
2 | ...
|
3 | usw. |
TomA schrieb: > Bei den ursprünglichen 51ern mit mehr Ports (80535...) ist es auch so. Da sagt mein Datasheet aber was anderes. MfG
sbit schrieb: > auch in 2015 kann man 8 Bit nicht auf 1 Bit schrumpfen. Nuhr! (alternativ ist das Handbuch zum Keil C-Compiler zu empfehlen)
Ein frohes Neues Jahr und vielen Dank für die zahlreichen Antworten, die mir leider nicht weiter helfen konnten :( Vielleicht habt ihr mein Problem nicht verstanden: ich möchte nur wissen, was der Compiler (Keil) aus der bit-Variablen macht, wenn man der Variablen was anderes als 0 oder 1 zuweist. Beispiel: bit _sw2; _sw2 = 2; Ist _sw2 jetzt FALSE, weil 2 nicht 1 ist, oder ist _sw2 TRUE, weil 2 nicht 0 ist? Das Handbuch schweigt sich dazu aus, und selber ausprobieren kann ich es momentan leider nicht.
Knut schrieb: > aus der bit-Variablen macht, wenn man > der Variablen was anderes als 0 oder 1 zuweist. Bit Variable kennen nur die Werte 0 = falsch = nicht gesetzt und "nicht 0" = wahr = gesetzt. COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE test.c BROWSE DEBUG OBJECTEXTEND CODE TABS(2) line level source 1 #include <stdio.h> 2 3 4 bit led_is_on; 5 6 void main (void) { 7 1 8 1 while (1) { 9 2 led_is_on = 0; 10 2 led_is_on = 1; 11 2 led_is_on = 2; 12 2 } 13 1 } C51 COMPILER V9.51 TEST 01/01/2015 11:40:14 PAGE 2 ASSEMBLY LISTING OF GENERATED OBJECT CODE ; FUNCTION main (BEGIN) ; SOURCE LINE # 6 0000 ?C0001: ; SOURCE LINE # 8 ; SOURCE LINE # 9 0000 C200 R CLR led_is_on ; SOURCE LINE # 10 0002 D200 R SETB led_is_on ; SOURCE LINE # 11 0004 D200 R SETB led_is_on ; SOURCE LINE # 12 0006 80F8 SJMP ?C0001 ; FUNCTION main (END) MODULE INFORMATION: STATIC OVERLAYABLE CODE SIZE = 8 ---- CONSTANT SIZE = ---- ---- XDATA SIZE = ---- ---- PDATA SIZE = ---- ---- DATA SIZE = ---- ---- IDATA SIZE = ---- ---- BIT SIZE = 1 ---- END OF MODULE INFORMATION. C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
> Bit Variable kennen nur die Werte 0 = falsch = nicht gesetzt und "nicht > 0" = wahr = gesetzt. Alles klar, danke!
Knut schrieb: >> Bit Variable kennen nur die Werte 0 = falsch = nicht gesetzt und "nicht >> 0" = wahr = gesetzt. > > Alles klar, danke! Das ist aber ein ganz schlechter Programmierstil. Du kannst dich auch nur bei diesem Compiler (und dieser Version) darauf verlassen. Es ist implementierungsabhängig. Auch Keil kann das morgen ändern. ;-)
sbit schrieb: > Auch Keil kann das morgen ändern. Bei Keil ist das seit etwa 30 Jahren so implementiert. Es ist unwahrscheinlich, dass es in Zukunft anders wird. Über Programmierstil kann man herrlich und lange streiten. Nimm den Datentyp "Bit" als Boolsche Variable. Die hat nun mal nur zwei Zustände und wird mit einem einzigen Bit hervorragend platzsparend dargestellt. Imho ist es übersichtlicher als die "packed arrays". Und schneller ist es allemal.
Georg G. schrieb: > Es ist > unwahrscheinlich aber nicht ausgeschlossen. ;-) Georg G. schrieb: > Nimm den > Datentyp "Bit" als Boolsche Variable. ??? Genau das schreibe ich hier dauernd. :-( Nur wird hier versucht ein 8 Bit Wert einem 1 Bit Wert zu zuweisen. Und das ist sch.....lecht. sbit schrieb: > Wenn schon, dann so_sw1 = (P5 & 0x01) != 0; > ... > usw.
sbit schrieb: > Nur wird hier versucht ein 8 Bit Wert einem 1 Bit Wert zu zuweisen. Und > das ist sch.....lecht. Genau das passiert in C++ bei: bool s = (port & 0x40);
sbit schrieb: > Nur wird hier versucht ein 8 Bit Wert einem 1 Bit Wert zu zuweisen. Lies dich doch bitte mal in die Grundlagen der Boolschen Arithmetik ein. "if (a)" ergibt wahr oder falsch, Null oder Eins, egal, welchen Datentyp a hat. Du versuchst, Dinge in die Sprache hinein zu interpretieren, die nicht vorgesehen sind.
Georg G. schrieb: > Lies dich doch bitte mal in die Grundlagen der Boolschen Arithmetik ein. A. K. schrieb: > Da dieser Datentyp im offiziellen C nicht vorkommt ist einzig das > Handbuch des Compilers die Referenz. Georg G. schrieb: > Du versuchst, Dinge in die Sprache hinein zu interpretieren, die > nicht vorgesehen sind. Ne, genau das machst du gerade. Denn, es geht um den Datentyp "bit" !!!
Der Datentyp BIT ist bei jedem 8x51 Compiler, den ich kenne, auch unterstützt. Wo ist da das Problem ? Sollte dies nicht der Fall sein, so gehört der Compiler schnellstens entsorgt :-)
Bernd N schrieb: > Wo ist da das Problem ? Machen alle 8051 Compiler, die du kennst, das garantiert ganz genauso wie Keil? Es geht darum den Programmierstil zu verbesseren und Programme portierbar zu gestalten. Es sind hier nicht nur Bastler unterwegs, die sich freuen, falls was funktioniert. Es gibt auch Leute, die wissen, was sie tun. ;-)
>> Machen alle 8051 Compiler, die du kennst, das garantiert ganz genauso >> wie Keil? Nein, muss auch nicht sein. Das man die Doku zum Compiler lesen kann setze ich vorraus. C portierbar von MC zu MC Familie halte ich für eine Illusion insbesondere wenn es um die GPIOs geht. Wenn du das durchhalten willst dann ist das ein ziemlicher Aufwand.
Bernd N schrieb: > C portierbar von MC zu MC Familie halte ich für eine > Illusion Oh, oh, dann mach das mal beruflich. Du wirst dich über jedes Modul freuen, dass du mitnehmen kannst. ;-) Bernd N schrieb: > insbesondere wenn es um die GPIOs geht Und wenn es kein Port, sondern eine Sammlung von Flags ist, oder ein Datenstrom, oder ...? :-[ Bei '&' ist und bleibt es eine bitweise Verknüpfung und das Ergebnis hat mehrere Bits. Du hoffst, dass der Compiler da noch ein '!= 0' anhängt. Warum schreibst du es nicht einfach hin und bist dir damit sicher? Bei sauberer Programmierung gäbe es diesen Thread nicht, dass ist der Grund, es ordenlich zu machen ;-)))
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.