MSP430 - Port-Ausgänge zusammenfassen

OP #1636941
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!
#1636959
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?
OP #1636972
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
> 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
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?
#1637016
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.
Persönliche Seite #1637017
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
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
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

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.