Forum: Mikrocontroller und Digitale Elektronik zustand vom Ausgang ermitteln


von Franz (Gast)


Lesenswert?

Hallo,
wenn ich bei einem AVR einen ausgang setzen möchte, mache ich es ja z.B. 
mit
PORTB |= (1<<PINB2)

kann ich auch einfach mit
status = 1<<PINB2
abfragen, ob der Ausgang high oder low ist? Oder kann ich da was kaputt 
machen?

von Cyblord -. (cyblord)


Lesenswert?

Franz schrieb:
> Hallo,
> wenn ich bei einem AVR einen ausgang setzen möchte, mache ich es ja z.B.
> mit
> PORTB |= (1<<PINB2)
>
> kann ich auch einfach mit
> status = 1<<PINB2
> abfragen, ob der Ausgang high oder low ist? Oder kann ich da was kaputt
> machen?

Ja geht. Nur nicht so
> status = 1<<PINB2

sondern so:

status = (PINB & (1<<PINB2))

von Adam P. (adamap)


Lesenswert?

Franz schrieb:
> kann ich auch einfach mit
> status = 1<<PINB2
> abfragen

Nein, so funktioniert das nicht.
PINB2 ist nichts anderes als ein define:
1
#define PINB2  2

Somit ist das setzen nichts anderes als:
1
PORTB |= (1<<2);

Abfragen könntest du so machen:
1
uint8_t status;
2
status = PINB;   // alle 8 Pins
3
status = (1<<PINB2); // nur Pin2

oder direkt so:
1
if (PINB & (1<<PINB2))
2
{
3
   // PINB2 ist gesetzt (high)
4
}

Siehe:
https://www.mikrocontroller.net/articles/Kategorie:AVR-GCC-Tutorial#Zugriff_auf_IO-Ports

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Adam P. schrieb:
> if (PINB & (1<<PINB2)) ...

Um den Code besser lesbar zu machen, kann es sehr hilfreich sein, solche 
Ausdrücke in Makros oder Funktionen zu verpacken. Der finale Code wird 
dadurch nicht größer.
1
#define START_BUTTON_PRESSED (PINB & (1<<PINB2))
2
3
if (START_BUTTON_PRESSED) ...

Oder
1
bool start_button_pressed()
2
{
3
    return (PINB & (1<<PINB2));
4
}
5
6
if (start_button_pressed()) ...

von Cyblord -. (cyblord)


Lesenswert?

Stefan ⛄ F. schrieb:
>
1
> #define START_BUTTON_PRESSED (PINB & (1<<PINB2))
2
> 
3
> if (START_BUTTON_PRESSED) ...
4
>

Es gibt echt noch Leute die denken, derartige Makro-Magic wäre sauberer 
Code.
Braucht man eine Funktion, schreibt man einfach eine Funktion. Kein 
MAKRO.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Cyblord -. schrieb:
> Es gibt echt noch Leute die denken, derartige Makro-Magic wäre sauberer
> Code.

Derart triviale Makros finde ich OK. Ich weiß aber was du meinst. Es 
gibt verschachtelte Makros, über die muss man erst mal ziemlich lange 
grübeln, um sie zu verstehen. Solche Makros führen schnell zu 
unverständlichen Fehlermeldungen oder zu Fehlfunktionen, die man nicht 
durchblickt.

Seit der Compiler Funktionen ebenso gut optimiert, gefallen mir 
Funktionen auch besser.

von Adam P. (adamap)


Lesenswert?

Cyblord -. schrieb:
> Braucht man eine Funktion, schreibt man einfach eine Funktion.

Stefan ⛄ F. schrieb:
> bool start_button_pressed()
> {
>     return (PINB & (1<<PINB2));
> }

Vllt. ist das jetzt zu penibel oder so... aber würdet ihr die Funktion 
dann nicht eher als inline definieren?
Einfach nur aus dem Gedanken:
Will ich ein richtigen Funktions-Call nur um ein Pin-Status abzufragen?
Aber wahrscheinlich wird es in diesem Fall eh wegoptimiert da es ja 
keine lokalen Varaiblen gibt (Stack) usw.

: Bearbeitet durch User
von Axel S. (a-za-z0-9)


Lesenswert?

Cyblord -. schrieb:
> Stefan ⛄ F. schrieb:
>>
1
>> #define START_BUTTON_PRESSED (PINB & (1<<PINB2))
2
>>
3
>> if (START_BUTTON_PRESSED) ...
4
>>
>
> Es gibt echt noch Leute die denken, derartige Makro-Magic wäre sauberer
> Code.

Es gibt echt noch Leute, die Makros nicht verstehen und darum ablehnen.

> Braucht man eine Funktion, schreibt man einfach eine Funktion. Kein
> MAKRO.

Tja. Nur braucht man halt dafür gar keine Funktion. Vor ein paar 
Jahren noch hätte man mit einer Funktion an dieser Stelle die 
Performance mal locker um Faktor 10 verschlechtert. Denn das Makro 
(genauso wie der Funktionsrumpf) wird auf einem AVR zu einem einzelnen 
Maschinenbefehl. Prolog und Epilog, den der Compiler für die Funktion 
generiert, sind deutlich größer. Und CALL/RET sind auch nicht kostenlos.

Erst seit C-Compiler solchen Funktionen inlinen können, ist die Variante 
mit Funktion genauso schnell. Wobei man sich da immer noch hypsch in den 
Fuß schießen kann. Wenn man diese Funktionen nämlich in ein extra .c 
File auslagert (HAL und Abstraktion, wissen schon) dann wird der 
Compiler die nicht mehr inlinen. Außer wenn man LTO eingeschaltet hat.

von Axel S. (a-za-z0-9)


Lesenswert?

Adam P. schrieb:
> Vllt. ist das jetzt zu penibel oder so... aber würdet ihr die Funktion
> dann nicht eher als inline definieren?

Kann man, muß man aber nicht. Das inline war immer schon mehr ein 
Hinweis an den Compiler als eine Anweisung. Vergleichbar mit der 
register Speicherklasse für Variablen. Der Compiler kann (und oft 
wird) das ignorieren und auf seine eigene Einschätzung vertrauen.

von Cyblord -. (cyblord)


Lesenswert?

Axel S. schrieb:
> Adam P. schrieb:
>> Vllt. ist das jetzt zu penibel oder so... aber würdet ihr die Funktion
>> dann nicht eher als inline definieren?
>
> Kann man, muß man aber nicht. Das inline war immer schon mehr ein
> Hinweis an den Compiler als eine Anweisung. Vergleichbar mit der
> register Speicherklasse für Variablen. Der Compiler kann (und oft
> wird) das ignorieren und auf seine eigene Einschätzung vertrauen.

Eben, und damit fällt der ach so große Performanceverlust weg.
Der Code hat aber trotzdem eine sauber definierte Funktion.

Es ist keine gute Idee solche einfachen Dinge von vorn herein auf das 
letzte bisschen Performance zu trimmen. Einfach mal straight forward 
schadet nicht. Gerade für Anfänger ist das einfach zu empfehlen.
Optimieren kann man dann immer noch. Meistens muss man es aber gar 
nicht.

von Stefan F. (Gast)


Lesenswert?

Adam P. schrieb:
> Vllt. ist das jetzt zu penibel oder so... aber würdet ihr die Funktion
> dann nicht eher als inline definieren?

Nicht (mehr) nötig, der Compiler optimiert das inzwischen zuverlässig 
optimal, sofern die Funktion in der selben Quelltext-Datei steht, wo sie 
benutzt wird.

von Axel S. (a-za-z0-9)


Lesenswert?

Cyblord -. schrieb:
> Axel S. schrieb:
>> Adam P. schrieb:
>>> Vllt. ist das jetzt zu penibel oder so... aber würdet ihr die Funktion
>>> dann nicht eher als inline definieren?
>>
>> Kann man, muß man aber nicht. Das inline war immer schon mehr ein
>> Hinweis an den Compiler als eine Anweisung. Vergleichbar mit der
>> register Speicherklasse für Variablen. Der Compiler kann (und oft
>> wird) das ignorieren und auf seine eigene Einschätzung vertrauen.
>
> Eben, und damit fällt der ach so große Performanceverlust weg.

Das hängt vom Compiler und den Einstellungen ab. Pauschal kann man da 
gar nichts sagen. Im Zweifel muß man in den generierten Code schauen.

> Der Code hat aber trotzdem eine sauber definierte Funktion.

Das Makro auch.

> Es ist keine gute Idee solche einfachen Dinge von vorn herein auf
> das letzte bisschen Performance zu trimmen.

Ich halte es umgekehrt für unsinnig, einen Einzeiler in eine eigene 
Funktion zu verfrachten.

> Optimieren kann man dann immer noch. Meistens muss man es aber
> gar nicht.

Oder man weiß es bloß nicht. Anfänger z.B. können so etwas weder von 
vornherein einschätzen noch wüßten sie, wie sie es finden sollten. Im 
Zweifelsfall nehmen die dann einen größeren µC. Tolle Wurst!

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.