Forum: Mikrocontroller und Digitale Elektronik Pins am Port in einem Durchgang modifizieren


von Max K. (achulio)


Lesenswert?

Hallo Experten,
ich habe folgendes Problem: PortC sieht folgendermaßen beschaltet aus:

PORT PIN:     0   1   2   3   4   5   6   7
Beschaltung: in  out out out out  -   -   -

wobei: in = Eingang, out = Ausgang, - = nicht genutzt

Ich möchte nun möglichst zügig ohne viel zwischenspeichern von 
Statusvariablen den Zustand der Pins 1-4 ändern, bsp. von 1101 zu 1011. 
Wie kann ich diese Zuweisung in C schnell durchführen? Meine Versuche 
wie zB:
1
PORTC |=  0b00011110 & ~(1<<PORTC);
schlagen leider fehl. Ich möchte den Zustand der Pins 0 und 5-7 nicht 
verändern, aber die Pins 1-4 gezielt modifizieren. Klappt das OHNE ein 
Zwischenspeichern des Port-Zustands und dann wiederzuweisen und OHNE 2x 
auf den Port zuzugreifen (um einmal die Pins auf 1 zu setzen und dann 
die Pins auf 0 zu setzen)?
Danke!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wenn du den Wert des Ports nur setzen willst, was spricht gegen:
1
set_portc(uint8_t data)
2
{
3
   PORTC = (data & 0x0F) << 1;
4
}

?

Das Ausgangsregister zum Eingangspin wird auf 0 gesetzt, die
unbenutzten Pins ebenfalls.

von Karl H. (kbuchegg)


Lesenswert?

Max K. schrieb:

> schlagen leider fehl. Ich möchte den Zustand der Pins 0 und 5-7 nicht
> verändern, aber die Pins 1-4 gezielt modifizieren. Klappt das OHNE ein
> Zwischenspeichern des Port-Zustands und dann wiederzuweisen und OHNE 2x
> auf den Port zuzugreifen

Nein.

Benutz ruhig eine Zwischenvariable anstelle zu versuchen alles in eine 
einzige Anweisung zu packen. Schreib das so, wie es für dich am besten 
zu lesen und zu verstehen ist und überlasse es dem Compiler das schnell 
zu machen (Die Zwischenvariable wird der Optimizer wieder 
rausschmeissen)

von Max K. (achulio)


Lesenswert?

Hallo Jörg,
Danke für deinen Vorschlag. Lass mich etwas detaillierter werden: auf 
PIN0 läuft mein ADC, hat es einen Einfluss auf den ADC wenn mit 
"Ausgangsregister zum Eingangspin wird auf 0 gesetzt" hier etwas gesetzt 
wird, das ich eigentlich nicht beeinflussen will? Zumal ich gerne den 
Zustand der Pins 5,6,7 nicht verändern möchte. (was läuft eigentlich 
beim ATMega8 auf PORTC5-7?)
Danke!

von Max K. (achulio)


Lesenswert?

Hi Karl-Heinz; danke, klare Antwort! Dann werde ich es so machen...

von Michael M. (technikus)


Lesenswert?

Max K. schrieb:
>
1
PORTC |=  0b00011110 & ~(1<<PORTC);

Dir ist klar, daß es 0bXXXXXX in der C-Syntax nicht gibt?

Servus
Michael

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Max K. schrieb:
> Hallo Jörg,
> Danke für deinen Vorschlag. Lass mich etwas detaillierter werden: auf
> PIN0 läuft mein ADC, hat es einen Einfluss auf den ADC wenn mit
> "Ausgangsregister zum Eingangspin wird auf 0 gesetzt" hier etwas gesetzt
> wird, das ich eigentlich nicht beeinflussen will?

Ja, wenn du PC0 auf 1 setzen würdest (ich gehe mal von einem
AVR aus, du hast es nicht genannt, was es ist), dann würdest du
den Pullup-Widerstand an den Eingang schalten und damit dort
zusätzlichen Strom einspeisen.

> Zumal ich gerne den
> Zustand der Pins 5,6,7 nicht verändern möchte.

Der bleibt bei meinem Vorschlag, genauso wie C0, konstant auf 0,
da du ja geschrieben hast, dass du an diesen Pins nichts hast.
Damit musst du dich aber auch nicht drum kümmern, umständlich
irgendwas zurück zu lesen.

> (was läuft eigentlich
> beim ATMega8 auf PORTC5-7?)

PC5 wäre SCL des I²C-Interfaces, PC6 ist eine Alternativfunktion
von /RESET (du müsstest dann aber die /RESET-Funktion explizit per
Fuse abschalten; danach geht kein ISP mehr!), PC7 existiert nicht.

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.