Forum: Mikrocontroller und Digitale Elektronik MSP430 - Port-Ausgänge zusammenfassen


von LuXXuS 9. (aichn)


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!

von Christian R. (supachris)


Lesenswert?

In einem Schritt geht das nicht. Dazu sind 2 extra Portzugriffe nötig. 
Nur die ganz neuen können 2 8-Bit Ports zu einem 16 Bit-Port zusammen 
passen, dann müsstest du aber immer noch die Bits erst mal sortieren.
Wer macht denn auch so eine dämliche Verbindung?

von LuXXuS 9. (aichn)


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

von Rufus Τ. F. (rufus) Benutzerseite


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.

von LuXXuS 9. (aichn)


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?

von Christian R. (supachris)


Lesenswert?

Nein, damit sagst du lediglich, dass die Bits 4...7 logisch mit 1 
und-verknüpft werden, also so bleiben, wie sie sind. Die Bits 0...3 
werden gelöscht. Den 2. Teil der Anweisung mit dem logisch oder musst du 
noch dran schreiben, sonst ist das untere Halbbyte 0000 nach deiner 
Operation.

von Rufus Τ. F. (rufus) Benutzerseite


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?

von Christian R. (supachris)


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?

von LuXXuS 9. (aichn)


Lesenswert?

SUPER!!! Vielen Dank! :-)

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Christian R. (supachris)


Lesenswert?

Stimmt natürlich, die müssen schon Null sein, hab ich vergessen.

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.