Forum: Mikrocontroller und Digitale Elektronik Datentyp bit beim 8051


von Knut (Gast)


Lesenswert?

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?

von (prx) A. K. (prx)


Lesenswert?

Da dieser Datentyp im offiziellen C nicht vorkommt ist einzig das 
Handbuch des Compilers die Referenz.

von Georg (Gast)


Lesenswert?

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

von Georg G. (df2au)


Lesenswert?

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.

von sbit (Gast)


Lesenswert?

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?

von Knut (Gast)


Lesenswert?

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; //
 }
}

von Peter D. (peda)


Lesenswert?

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

von Georg (Gast)


Lesenswert?

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

von sbit (Gast)


Lesenswert?

Egal was vom Port gelesen wird, der 8 Bit Ergebnistyp wird dem 1 Bit 
bool zugewiesen. Das ist nicht gut, gar nicht gut, ...

von einer (Gast)


Lesenswert?

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

von Jim M. (turboj)


Lesenswert?

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.

von TomA (Gast)


Lesenswert?

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

von TomA (Gast)


Lesenswert?

Nachtrag

Der schönere Schreibstil wäre gewesen:

    _sw1 = P5_0;
    _sw2 = P5_1;

Ich hoffe das bringt dich etwas weiter.

Gruß. Tom

von Dieter W. (dds5)


Lesenswert?

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.

von TomA (Gast)


Lesenswert?

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

von sbit (Gast)


Lesenswert?

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.

von einer (Gast)


Lesenswert?

TomA schrieb:
> Bei den ursprünglichen 51ern mit mehr Ports (80535...) ist es auch so.

Da sagt mein Datasheet aber was anderes.

MfG

von Georg G. (df2au)


Lesenswert?

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)

von Knut (Gast)


Lesenswert?

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.

von Georg G. (df2au)


Lesenswert?

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)

von Knut (Gast)


Lesenswert?

> Bit Variable kennen nur die Werte 0 = falsch = nicht gesetzt und "nicht
> 0" = wahr = gesetzt.

Alles klar, danke!

von sbit (Gast)


Lesenswert?

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. ;-)

von Georg G. (df2au)


Lesenswert?

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.

von sbit (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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

von Georg G. (df2au)


Lesenswert?

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.

von sbit (Gast)


Lesenswert?

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" !!!

von Bernd N (Gast)


Lesenswert?

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

von sbit (Gast)


Lesenswert?

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. ;-)

von Bernd N (Gast)


Lesenswert?

>> 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.

von sbit (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.