Guten Tag zusammen
Ich verwende ein Programm wo PORTD als Outreg diffiniert ist. Jetzt
plane ich die USART Port Pins PD0(TXD) und PD1(RXD) als Schnittstelle zu
verwenden. Die Idee ist jetzt 'PORTD' so anzupassen um PD0 und PD1 z.B.
durch PC0 und PC1 zu ersetzen.
Gibt es eine Möglichkeit den Outreg 'PORTD', bestehend aus
PD7...PD2,PD1,PD0 so anzupassen, dass daraus PD7...PD2,PC1,PC0 wird?
NEIN!
Wenn die serielle Schnittstelle aktiviert wird, werden die
Pins D0 und D1 automatisch umkonfiguriert.
Portadressen lassen sich NICHT mischen.
Die entsprechende Pin-Adressierung kann über
ein passendes Unterprogramm/bedingte Compilierung/ Assemblierung
erfolgen.
Es werden aber immer ZWEI Ausgaben nötig sein,
die an PortD und die an PortC!
Firebird schrieb:> Ich hatte an so etwas gedacht:> #define MixPins>> MixPins = (1 << PC0) | (1 << PC1) | (1 << PD2) ... | (1 << PD7)outreg =
(((uint16_t)MixPins) << 8) | ((uint16_t)PORTB);PORTB = outreg;
> MixPins = (outreg >> 8);> Danke und Gruss> Firebird
Das geht natürlich nicht!
Ich denke ich habs jetzt verstanden, PORTC und PORTD haben je ein 8 Bit
register; die einzelnen Pins der jeweiligen Ports kann man nicht
kombinieren.
Ok, jetzt weiss ich nicht weiter ... leider bin ich Anfänger.
Im Anhang ist ein Code den ich ändern möchte. Vielleicht hat jemand eine
Lösung oder kann mir ein Beispiel aufzeigen.
Danke und Gruss
Firebird
Würde das funktionieren oder müsste man PORTC und PORTD mit OR
verknüpfen?
Ich weiss, ich bin Anfänger und habe wenig Ahnung ... aber ich versuchs
;-)
Danke und Gruss
Firebird
> Deine neue Belegung sieht so aus>> 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0> +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+> | | | | | | | | | | | | | | | | |> +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+> PD7 PD6 PD5 PD4 PD3 PD2 PC1 PC0 PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0> | PORTD | PORTC | PORTB |>> Und dafür musst du dir jetzt eine neue Veschiebesequenz suchen.> Ist doch nicht so schwer.
Wurde unterbrochen :-)
Wie geht das?
Kümmern wir uns erst mal nur um die oberen 8 Bit.
Wie entstehen die?
Da sind erst mal die 8 Bits vom PORTD
PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0
und dann noch die 8 Bits vom PORTC
PC7 PC6 PC5 PC4 PC3 PC2 PC1 PC0
und die sollen jetzt so 'zusammengemischt' werden, dass sich ein 8 Bit
Wert ergibt, der aus
PD7 PD6 PD5 PD4 PD3 PD2 PC1 PC0
besteht.
Die Strategie sieht so aus. Wir würden gerne 2 geeignet aufbereitete
Werte zusammenodern. Damit aber zb der Wert von PC6 das Endergebnis
nicht beeinflusst, wird dieses Bit gezielt auf 0 gesetzt. Denn das
Ergebnis von 0 oder irgendeinem_anderen_Bit hängt dann nur noch von
irgendeinem_anderen_Bit ab. Die 0 ist bei einer Oder Operation für das
Ergebnis nicht relevant.
Wir wollen also 2 Werte haben, deren Bits so aussehen
PD7 PD6 PD5 PD4 PD3 PD2 0 0 <- vom PORTD
0 0 0 0 0 0 PC1 PC0 <- vom PORTC
denn wenn diese beiden Werte zusammengeodert werden, dann enstehen genau
die 8 Bit deren Werte wie gewünscht von den Port Werten abhängen.
Also erhebt sich die Zwischenfrage: Wie erreicht man zb
PD7 PD6 PD5 PD4 PD3 PD2 0 0
Das wiederrum ist einfach. Mit einer Und Operation können Bits gezielt
auf 0 gesetzt werden. Alle Bits die übrig bleiben sollen, werden in
einer Maske auf 1 gesetzt, alle Bits die gezielt auf 0 gesetzt werden
sollen, werden in der Maske auf 0 gesetzt. Verundet man also
PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0
und 1 1 1 1 1 1 0 0
---------------------------------------
dann erhält man
PD7 PD6 PD5 PD4 PD3 PD2 0 0
genau so wie wir es brauchen.
Dasselbe nochmal mit den Bits vom PORTC
PC7 PC6 PC5 PC4 PC3 PC2 PC1 PC0
und 0 0 0 0 0 0 1 1
-----------------------------------------
0 0 0 0 0 0 PC1 PC0
damit können wir die 8 Bits generieren, die die oberen 8 Bits des 16 Bit
Ergebnisses ausmachen.
In C Schreibweise
( PORTD & 0xFC ) | ( PORTC & 0x03 )
Diese 8 Bit werden um 8 Stellen nach links geschoben, damit die unteren
8 Bit frei werden, um darin dann denn Inhalt vom PORTB noch
hineinzuodern (einzumischen).
Also lautet die Operation in Summe: (der Übersichtlichkeit halber in
mehrere Anweisungen aufgeteilt)
1
outreg=(PORTD&0xFC)|(PORTC&0x03);
2
outreg=outreg<<8;
3
outreg=outreg|PORTB;
Oder wenns denn sein muss, alles in einem
1
outreg=(((PORTD&0xFC)|(PORTC&0x03))<<8)|PORTB;
Jetzt bist du drann um die Umkehrung zu codieren. Aus dem 16 Bit Wert,
die entsprechenden Bits zu extrahieren und an die entsprechenden Ports
zu schreiben.
>> Jetzt müsste es nach meinem Kenntnisstand stimmen.> Mache ich ein Durcheinander?
Kurze Zwischenfrage:
Wie genau geht denn jetzt bei dir der Wert von outreg in das ein, was
auf PORTD bzw PORTC ausgegeben wird?
Wie auch immer dann die Zuweisung an PORTD aussieht, eines ist 100%
sicher: die Variable outreg muss da drinn irgendwie vorkommen.
Und was du auch bedenken musst:
Mit einem Oder | kann man immer nur Bits von 0 auf 1 bringen. Niemals
umgekehrt von 1 auf 0
Nicht raten, sondern dieselbe Technik wie weiter oben anwenden:
Papier und Bleistift nehmen:
Wie muss das Ergebnis aussehen? Wo kommen die einzelnen Bits her
(welches ist die jeweilige Quelle)? Wie muss daher die Quelle
aufbereitet werden, damit dann die Zwischenergebnisse zusammengeodert
werden können?
Es ist immer das gleiche Spielchen.
Ok, schön der Reihe nach. Die Verteilung sieht wie folgt aus:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
PD7 PD6 PD5 PD4 PD3 PD2 PC1 PC0 PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0
| PORTD | PORTC | PORTB |
Ich weise nun die Werte der unteren 8 Bits PORTB zu:
PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0 -> zu PORTB
Daraus folgt:
PORTB = outreg
Danach nehme ich die oberen 8 Bits und verschiebe sie um 8 Stellen nach
rechts:
outreg = outreg >> 8
Jetzt haben wir diese 8 Bits und wollen nur Bits 0 und 1 an PORTC
ausgeben. Dazu werden die Werte von Bits 0 und 1 mit UND Funktion
herausgelöst:
PD7 PD6 PD5 PD4 PD3 PD2 PC1 PC0 <- von outreg
und 0 0 0 0 0 0 1 1
-----------------------------------------
0 0 0 0 0 0 PC1 PC0
Daraus folgt:
PORTC = (outreg & 0x03)
Für PORTD erfolgt die gleiche Überlegung:
PD7 PD6 PD5 PD4 PD3 PD2 PC1 PC0 <- von outreg
und 1 1 1 1 1 1 0 0
-----------------------------------------
PD7 PD6 PD5 PD4 PD3 PD2 0 0
Daraus ergibt:
PORTD = (outreg & 0xFC)
Das Ganze sieht dann so aus:
1
PORTB=outreg
2
outreg=outreg>>8
3
PORTC=(outreg&0x03)
4
PORTD=(outreg&0xFC)
Karl Heinz Buchegger schrieb:> Papier und Bleistift nehmen:> Wie muss das Ergebnis aussehen? Wo kommen die einzelnen Bits her> (welches ist die jeweilige Quelle)? Wie muss daher die Quelle> aufbereitet werden, damit dann die Zwischenergebnisse zusammengeodert> werden können?
Ich weiss jetzt nicht was zusammengeodert werden soll.
Gruss
Firebird
Firebird schrieb:> Ich weiss jetzt nicht was zusammengeodert werden soll.
Was ist die "Zielvariable"
Das ist zb PORTC
Wie sieht das konkret aus
PC7 PC6 PC5 PC4 PC3 PC2 PC1 PC0
welche Bits kommen woher?
PC7 PC6 PC5 PC4 PC3 PC2
sollen sich nicht verändern, müssen also aus dem PORTC selber kommen
PC1 PC0
kommen aus dem outreg
Du hast also
PORTC outreg
| |
v v
PC7 - PC2 PC1, PC0
sollen übrig bleiben sollen übrig bleiben
| |
+-------> zusammenodern <------+
|
|
v
PORTC
In dem Fall ist eben PORTC einer der Ausgangspunkte und gleichzeitig
Endpunkt der Operation.
Der Teil "sollen übrig bleiben" ist eine Maskierung, so dass die nicht
gebrauchten Bits 0 werden. Das ist immer eine & Operation mit
wechselnden Masken.
Dasselbe für PORTD. Dort sollen PD0 und PD1 vom PORTD erhalten bleiben.
Prinzipiell. Denn da es sich dabei um die UART Pins handelt, hat dir die
UART sowieso die Kontrolle über die Pins entzogen. Aber grundsätzlich
ist es genau das gleiche Spielchen.
Wann immer 2 Werte (Register, Variablen) bitweise zusammengemischt
werden, dann geht das nach dem Schema
Wert 1 Wert 2
| |
Bits ev. entsprechend Bits eventuell entsprechend
zurechtschieben zurechtschieben
| |
nicht gebrauchte Bits nicht gebrauchte Bits
auf 0 auf 0
| |
+-----> verodern <------------+
|
Ergebnis
wobei in den meisten Fällen es so ist, dass die beiden Teilstücke "nicht
gebrauchte Bits auf 0" komplementär sind. Die Bits die in dem einen Pfad
übrig bleiben sind genau die Bits, die im anderen Pfad auf 0 gesetzt
werden und umgekehrt.
In deinem Fall hier entfallen die Teilstücke "Bits zurechtschieben",
weil die Bits schon auf den jeweils richtigen Positionen sind. Aber wenn
du zb vom Outreg die Bits 0 und 1 am PORTC auf den Bits 5 und 6 haben
willst, dann muss man die eben zurechtschieben.
Jetzt habe ich's verstanden; aus den Teilstücken von PORTC und outreg,
bzw. PORTD und outreg muss ein Ganzes entstehen durch zusammenodern.
Vielen Dank für die Unterstützung. Guter lerneffekt wenn man bei der
Lösungssuche mitdenken muss ;-)
Ich möchte eine neue LED Struct bestehend aus 12 LEDs mit 12 Kanal PWM ansteuern. Dazu muss ich den aktuellen Zustand der PORTS, bzw. den verwendenten Pins einlesen.
4
5
Mir ist unklar ob die bisher angewandte Methode (für 16 LEDs) auch für 12 Pins funktionieren würde. Mein Testaufbau läufte nicht wie es sollte. Ich vermute ich mache Fehler in der Umkehrung weiter unten.