2017-10-13 6 views
0

Ich versuche herauszufinden, ob es eine einfache Möglichkeit gibt, mehrere Bits eines Ports 8051 gleichzeitig zu ändern.ändern Sie mehrere Bits auf einmal ohne Abrissoperation - 8051 Ports

Ich werde mein Dilemma konkreter Stil neu erklären.

Meine Anwendung hat Port 2 für zwei Funktionen geteilt. Nennen wir sie FA und FB.

FA setzt auf den Ausgangswert der niedrigen drei Bits, und FB stützt sich auf die verbleibenden 5 Bits, aber sie können E/A sein.

Da ein Bit im FB ein Ausgangsbit ist, das eine Uhr steuert, möchte ich keinen Teil des FBs ändern, wenn ich FA modifiziere und umgekehrt.

Die folgenden Arten von Befehlen nicht für mich arbeiten:

mov P2,#07h 
mov P2,#80h 

Dies liegt daran, solche Befehle, die Werte für beide Funktionen überschreibt möglicherweise eine Funktion zur falschen Zeit ausgelöst wird.

konnte ich mit so etwas wie das weg folgende:

setb P2.7 
setb P2.6 
clr P2.5 
clr P2.4 
setb P2.3 
setb P2.2 
clr P2.1 
clr P2.0 

Weil ich weiß, diese Befehle einer einzelnen Bits durch eine ohne die restlichen Bits zu beeinflussen einstellen können, aber ich möchte versuchen, mehr zu setzen als ein Bit nach dem anderen.

Ich lese über read-modify-write und das Internet sagt mir MOV unterscheidet sich von logischen Operationen auf Port-Pins, also werde ich versuchen, hier eine Vermutung zu treffen, um zu sehen, ob ich recht habe, basierend auf meinem Beispiel :

Say für FB Ich möchte alle logischen Höhen ausgeben und für FA Ich möchte alle logischen Tiefs außer dem niedrigsten Bit = 1 ausgeben. Ich möchte jeweils eine Funktion bearbeiten.

Ich weiß, das wird nicht funktionieren, da es alles auf einmal setzt:

mov P2, #0F9h 

Aber irgendwie Logik ich denke, mit an den Ports funktionieren könnte, aber ich möchte wissen, ob mein Denken richtig ist. Angenommen, in den beiden folgenden Fällen hat P2 den Wert # 0A1h über den Befehl mov und die Pins von P2 sind alle mit Masse verbunden.

Ist das richtig ?:

anl P2,#F8h ;value of P2 = #0A1h AND #F8h = #0A0h 
orl P2,#F9h ;value of P2 = #0A0h OR #F9h = #0F9h 
anl P2,#F0h ;value of P2 = #0F9h AND #F0h = #0F0h 

Oder ist das richtigere ?:

anl P2,#F8h ;value of P2 = #00h AND #F8h = #00h 
orl P2,#F9h ;value of P2 = #00h OR #F9h = #0F9h 
anl P2,#F0h ;value of P2 = #00h AND #F0h = #00h 

Im zweiten Beispiel, das ich die Gleichungen mit # 00h gestartet, da der Wert P2 das ist, wenn produzieren würde ich benutzte MOV A, P2 und dann den gewünschten Wert für A, aber ich bin mir nicht sicher, ob dieser Wert in den Berechnungen von anl und orl verwendet wird.

Also insgesamt, meine Frage ist, kann ich anl und orl nur bestimmte Bits eines Ports zu ändern, ohne den Rest der Bits zu stören? oder bin ich mit Bit Manipulation Befehle wie Setb und Clr fest?

Antwort

1

Zunächst möchte ich den folgenden Aspekt hinzufügen. Der Ansatz, der die Befehle SETB und CLR umfasst, erfordert mehr Maschinenzyklen zur Ausführung und kann in einigen Fällen (z. B. Taktgenerierung, Synchronisationsprobleme) nicht durchführbar sein.

Die 8051 Ports sind im Vergleich zu heutigen MCUs eher primitiv. Der 'Port' hat einen Latch, der den Pin-Zustand speichert und dieser Latch versucht, den Ausgang zu konditionieren. Dies bedeutet nicht notwendigerweise, dass der Port im gewünschten Zustand ist. Zum Beispiel, wenn es extern niedrig angesteuert wird, kann der Latch hoch sein, aber der Port wird niedrig sein. Genau so stellen wir einen Port als Eingabe ein.

Wenn wir Daten an einen Port MOVE, schreiben wir in den Latch, wenn wir MOVE von dem Port in ein Register, lesen wir den tatsächlichen Zustand unabhängig vom Zustand des Latch. Read-Modify-Write-Operationen sind eine Ausnahme, da sie den Latch spezifisch lesen, die gewünschte Operation ausführen und zum Latch zurückschreiben. Daher ist das unter "Ist das richtig?" Angegebene Szenario richtig.

Wenn wir stattdessen MOV A, P2 und dann ausführen, P2, # F8h "Oder ist das richtiger ?:" wäre richtig.

Als Ergebnis können wir Logikoperationen verwenden, um Ports für die in dieser Frage angegebenen Fälle zu ändern.

+0

Ich bin dann besser dran, diese Kodierung Ansatz zu verwenden, wenn ich meinen benutzerdefinierten Wert in R7 High-Nibble setzen und es als High-Nibble von Port 2 tatsächlichen Ausgang machen wollen, während das untere Nibble von Port 2 unverändert bleibt: 'MOV R7, # 70h MOV A, P2 ANL A, # 0Fh ORL A, R7 MOV P2, A'. Bin ich auf dem richtigen Weg? – Mike