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?
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
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
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 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:>> 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 ;-)))