MSP430 - Port-Ausgänge zusammenfassen

OP #1636941
Lesenswert?

Hallo zusammen!

Kann mir einer sagen, wie ich Ausgänge des MCUs zusammenfassen kann, 
sodass ich ein Byte oder ein Nibble direkt an die Ausgänge legen kann, 
obwohl ich keinen gemeinsamen Port benutze?

Wenn ich beispielsweise ein Byte an Port 1 ausgebe:

P1OUT = 0xAE (jetzt mal willkürlich gewählt) -> Dann ist das ja alles 
wunderbar - sagen wir nun jedoch, dass ich von mir aus ein HD44780 nicht 
komplett an einem Port habe, sondern an P1.0,2,5 und P2.0,2,5,6,7

Wie kann ich vorab z.B. ein #define setzen, an dass ich das Byte senden 
kann?



Vielen Dank im Voraus!
OP #1636972
Lesenswert?

Die Verbindung ist dämlich, keine Frage!!! Ging mir nur da drum, ob es 
geht.

Im Normalfall schließe ich es 4-bittig an und sende die zwei Nibbles. 
Nur auch da müssen die Ausgänge beisammen sein, also z.B. BIT0,1,2,3. 
Meistens kann man das ja auch realisieren, nur wenn eben mal nicht, weil 
die Pins andersweitig mit ihren Sonderfunktionen benutzt werden.

Nun gut, andere Sache aber noch...

Wenn der Anschluss folgendermaßen beschaltet ist:

P1.0 - LCD-Datenbit 4
P1.1 - LCD-Datenbit 5
P1.2 - LCD-Datenbit 6
P1.3 - LCD-Datenbit 7
P1.4 - LED oder ähnliches
P1.5 - LED oder ähnliches
P1.6 - LED oder ähnliches
P1.7 - LED oder ähnliches

Jetzt möchte ich das Nibble halt an P1.0-3 schicken. Was schreibe ich an 
den Ausgang, damit auch nur P1.0-3 angesprochen werden und P1.4-7 
unbeeinflusst bleiben.

Meistens habe ich das umgangen, indem ich die restlichen Pins als 
Eingänge benutzt habe, wodurch sie vom P1OUT = 0xXX nicht betroffen 
waren.

Was ich suche ist im Pseudocode: (P1OUT && (BIT0 bis 3)) = 0xXX
Persönliche Seite #1636983
Lesenswert?

> Was ich suche ist im Pseudocode: (P1OUT && (BIT0 bis 3)) = 0xXX

Da bist Du doch schon nah dran:
1
  P1OUT = (P1OUT & 0xF0) | wert_fuer_bit0_bis_3;

Statt der 0xF0 kannst Du natürlich auch den Bitschiebe-Kram schreiben, 
den hier manche Leute für lesbarer halten:
1
  P1OUT = (P1OUT & ((1 << BIT7) | (1 << BIT6) | (1 << BIT5) | (1 << BIT4)) | wert_fuer_bit0_bis_3;

Das setzt voraus, daß die Konstanten BIT7 .. BIT0 die Werte 7 .. 0 
haben, also die Nummern und nicht die Werte der korrespondierenden 
Bits.

Die Definitionen für Bitwerte in den von TI stammenden Headerdateien 
aber geben den Wert und nicht die Nummer der Bits an.

Daher sollte man nach meiner unmaßgeblichen Meinung auf einem MSP430 
diese Bitschiebe-Schreibweise nicht anwenden.
OP #1636996
Lesenswert?

Rufus t. Firefly schrieb:
> Da bist Du doch schon nah dran:
>   P1OUT = (P1OUT & 0xF0) | wert_fuer_bit0_bis_3;

Also allein durch das

(P1OUT & 0xF0)

sage ich dem Controller, dass ich BIT0 bis BIT3 haben will?

Nur zum Verständnis: 0xF0 ist ja 0b11110000 - ist das jetzt grad einfach 
falschherum, weil ich ja P1.0,1,2,3 haben will, oder versteh ich hier 
grad was nicht?
Persönliche Seite #1637017
Lesenswert?

Dennis E. schrieb:
> Rufus t. Firefly schrieb:
>> Da bist Du doch schon nah dran:
>>   P1OUT = (P1OUT & 0xF0) | wert_fuer_bit0_bis_3;
>
> Also allein durch das
>
> (P1OUT & 0xF0)
>
> sage ich dem Controller, dass ich BIT0 bis BIT3 haben will?

Nein. Dadurch nimmst Du das, was in P1OUT momentan steht und löscht 
gezielt die Bits 0..3.

Durch die OR-Verknüpfung setzt Du dann die Bits 0..3 auf den neuen 
gewünschten Wert, wobei Du aufpassen musst, daß "wert_fuer_bit0_bis_3" 
auch wirklich nur diese Bits beschreibt.


Um das sicherzustellen, kann man das hier machen:
1
   P1OUT = (P1OUT & 0xF0) | (wert_fuer_bit0_bis_3 & 0x0F);

Beispiel:

P1OUT sei 0xA3

Du möchtest die Bits 0..3 auf den Wert 5 ändern.

Erster Schritt:

Bestimmen des aktuellen Wertes und Löschen der Bits 0..3
1
   P1OUT = (P1OUT & 0xF0) | (wert_fuer_bit0_bis_3 & 0x0F);
2
           --------------

Das ist ein Lesezugriff auf P1OUT, der den Wert 0xA3 liefert.
Durch die AND-Verknüpfung mit 0xF0 wird daraus der Wert 0xA0.
Noch erfolgt keine Zuweisung, das ist nur ein Zwischenergebnis!

Zweiter Schritt:

Vorbereiten des Ausgabewerts
1
   P1OUT = (P1OUT & 0xF0) | (wert_fuer_bit0_bis_3 & 0x0F);
2
                            -----------------------------

Da der Wert in diesem Beispiel bereits 5 ist, hat die AND-Verknüpfung 
hier keine Auswirkung.
Das ist unser zweites Zwischenergebnis.


Dritter Schritt:

Setzen des neuen Wertes in Bits 0..3
1
   P1OUT = (P1OUT & 0xF0) | (wert_fuer_bit0_bis_3 & 0x0F);
2
                         ---

Durch die OR-Verknüpfung werden alle Bits, die in unserem /zweiten 
Zwischenergebnis/ gesetzt sind, auch in unserem ersten 
Zwischenergebnis gesetzt.

Das ist damit 0xA5, unser gewünschtes Resultat.

Vierter Schritt:

Ausgeben des Zwischenergebnisses an den Port:
1
   P1OUT = (P1OUT & 0xF0) | (wert_fuer_bit0_bis_3 & 0x0F);
2
   --------

Wirds klarer?
#1637022
Lesenswert?

Du kannst natürlich auch gleich

P1OUT |= 0x05

schreiben, dann werden nur die unteren Bits gesetzt. Musst allerdings 
sicherstellen, dass das obere Nibble 0 ist.

P1OUT |= (Value & 0x0F) wäre dann sicherer. Dann bleiben die oberen 4 
Bits unangetastet und Value wird auf die unteren 4 geschrieben.

Lernt denn niemand mehr Bool´sche Algebra heutzutage?
Persönliche Seite #1637024
Lesenswert?

Christian R. schrieb:
> Du kannst natürlich auch gleich
>
> P1OUT |= 0x05
>
> schreiben, dann werden nur die unteren Bits gesetzt. Musst allerdings
> sicherstellen, dass das obere Nibble 0 ist.


Das allerdings setzt voraus, daß vorher die unteren vier Bits von 
P1OUT Null sind. Sind sie das nicht, werden nur Bits gesetzt, die nicht 
schon vorher gesetzt waren und keines gelöscht.

> Lernt denn niemand mehr Bool´sche Algebra heutzutage?

Das frage ich mich gerade auch.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren