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?
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))
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
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()) ... |
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
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.
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
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.
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.