guten abend,
ich habe ein kleines logisches Problem.
Ich möchte den Pin (AVR) anhand einer variable setzen.
Dies habe ich bisher mittels einer if-Bedingung
1
if(1==ledOn)
2
{
3
DDRD|=(1<<PIND3);
4
}
5
else
6
{
7
DDRD&=~(1<<PIND3);
8
}
gibt es da auch einen eleganteren weg, wo ich direkt den wert der
Variable benutzen kann?
Dominik schrieb:> gibt es da auch einen eleganteren weg, wo ich direkt den wert der> Variable benutzen kann?
Jain. Man kann es über eine Tabelle machen. Wo liegt denn dein Problem?
In der Ästhetik?
HildeK schrieb:> wenn ledOn nur die Werte 0 und 1 annimmt.
Idealer- und ästhetischerweise nutzt man dafür einen bool, dann ist das
automatisch gegeben.
Rolf M. schrieb:> Idealer- und ästhetischerweise nutzt man dafür einen bool, dann ist das> automatisch gegeben.
Nö, ist es AFAIK nicht - und kann einem bei -Os oder -O3 auf die Füße
fallen.
Der Optimizer darf das in einem ganzen Register belassen, damit sind
auch Werte <0 oder >1 möglich.
Dominik schrieb:> gibt es da auch einen eleganteren weg,
digitalWrite(3,ledOn); aus der Arduino-Bibliothek.
Aber das setzt nicht das Datenrichtungsregister DDRD sondern das
Ausgaberegister PORTD, und es nutzt nicht die Eingangspinbitnummer
PIND3, sondern PD3.
Die Frage ist also, was du eigentlich wolltest und warum das alles.
Dominik schrieb:> gibt es da auch einen eleganteren weg, wo ich direkt den wert der> Variable benutzen kann?
Man kann den Code hinter einem Makro verbergen:
Aber wirklich eleganter ist das auch nicht. Ich habe früher zu viele
solcher Makros verwendet. Sie verschleiern, was wirklich passiert.
Dadurch provozieren sie falsche Verwendung und machen Fehlermeldungen
schwerer verständlich.
Eine ganz normale C Funktion ist gut lesbar und produziert in der Regel
genau den gleichen Maschinencode, ist also nicht ineffizient:
1
voidsetze_status_led(boolein)
2
{
3
if(ein)
4
{
5
DDRD|=(1<<PIND3);
6
}
7
else
8
{
9
DDRD&=~(1<<PIND3);
10
}
11
}
12
13
setze_status_led(ledOn);
Wobei man auch aufpassen muss, wie man die Variable nennt. "ledOn" kann
die LED nämlich auch aus schalten. Gute passende Namen sind wichtig,
falls es kein Wegwerf-Projekt ist.
Jim M. schrieb:> Rolf M. schrieb:>> Idealer- und ästhetischerweise nutzt man dafür einen bool, dann ist das>> automatisch gegeben.>> Nö, ist es AFAIK nicht - und kann einem bei -Os oder -O3 auf die Füße> fallen.
Nein.
> Der Optimizer darf das in einem ganzen Register belassen, damit sind> auch Werte <0 oder >1 möglich.
Der interne Wert, den der Compiler für einen bool nutzt, kann dir aber
egal sein. Wenn man ihn in einen Integer konvertiert, kommt immer 0 für
false und 1 für true raus. Das garantiert der Standard.
> Die Frage ist also, was du eigentlich wolltest und warum das alles.
Das Problem ist doch gerade, jeder Programmiere wählt die Lösung, die
ihm persönlich am besten gefällt.
Dominiks ursprüngliches Beispiel ergibt ewig langen Programmcode. Nach
dem runter scrollen hat man schon wieder vergessen, was oben stand.
Arduinos digitalWrite() ist zwar kompakt, hat sich aber außerhalb der
Arduino Welt nicht durchgesetzt.
Jeder bastelt da irgend etwas anderes. Der Code lässt sich nicht
wiederverwenden. Nachvollziehen, was die Macros, Wrapper und Frameworks
machen, wird aufwendiger als komplett neu entwickeln.
Nimm als Beispiel die Normen aus Maschinenbau oder Bauwesen. Alle
Ingenieure benutzen die selben Symbole und die selben Bezeichnungen.
Jeder sieht auf den ersten Blick, was der Kollege konstruiert hat.
Wieso können wir uns nicht auf einen einheitlichen Weg einigen?
EAF schrieb:> Und das zugehörige Kompilat:
Das der Compiler so etwas gut optimieren kann, brauchst du nicht zu
beweisen. Das Thema hatten wir schon oft genug. Auch eine ganz normale
Funktion erzeugt in der Regel den selben optimalen Maschinencode.
Die Frage nach der "Ästhetik" finde ich viel wichtiger.
Eine Anmerkung schrieb:> Arduinos digitalWrite() ist zwar kompakt, hat sich aber außerhalb der> Arduino Welt nicht durchgesetzt.
Der Maschinencode der dabei heraus kommt ist aber alles andere als
Kompakt. Wenn man sich mal den Quelltext der Funktion anschaut, wundert
mich das auch nicht. Da passiert ja noch einiges mehr, als nur den
einzelnen PIN auf HIGH oder LOW zu setzen. Womit wir wieder beim
"verschleiern" sind. Die Funktion macht mehr, als ihr Name suggeriert,
was ich nicht gut finde. Andererseits ist sie trotz der Verschleierung
halbwegs deppensicher, das muss man auch mal würdigen.
Stefan F. schrieb:> Das Thema hatten wir schon oft genug
Und doch gibt es hier weiterhin eine "Arduino Basher" und "C++ auf µC
ist ineffektiv/unsinnig" Fraktion.
Erinnere dich!
Hi
>Und doch gibt es hier weiterhin eine "Arduino Basher" und "C++ auf µC>ist ineffektiv/unsinnig" Fraktion.
Immer noch die gleichen Phrasen, die du schon als 'Arduino Fanboy' von
dir gegeben hast.
MfG Spess
Einen µC-Pin in Abhängigkeit von einer Variablen schalten...
Zu schwer?
Warum nicht Ikebana?
Da gibt es sehr schöne VHS-Kurse, die dich hoffentlich nicht so
schnell überfordern...
>> gibt es da auch einen eleganteren weg, wo ich direkt den wert der> Variable benutzen kann?
Meinst Du wirklich DDRD? Oder sollte es eher PORTD sein? Kennst Du den
Unterschied?
Dominik schrieb:> guten abend,> ich habe ein kleines logisches Problem.>> Ich möchte den Pin (AVR) anhand einer variable setzen.> Dies habe ich bisher mittels einer if-Bedingung>
1
>if(1==ledOn)
2
>{
3
>DDRD|=(1<<PIND3);
4
>}
5
>else
6
>{
7
>DDRD&=~(1<<PIND3);
8
>}
9
>
>> gibt es da auch einen eleganteren weg, wo ich direkt den wert der> Variable benutzen kann?
DDRD setzt aber nur die Datenrichtung des angegebenen Pins, nicht seinen
logischen Zustand. Was du wohl eher möchtest ist
1
if(1==ledOn)
2
{
3
PORTD|=(1<<PD3);
4
}
5
else
6
{
7
PORT&=~(1<<PD3);
8
}
Wenn ledOn nur den Zustand 0 oder 1 annehmen kann, dann kann man das
verkürzt schreiben mit:
1
PORTD=PORTD&~(1<<PD3)|(ledOn<<PD3);
Das ist aber IMHO etwas schwerer zu lesen, die If-Bedingung ist meiner
Ansicht nach für den Menschen übersichtlicher/einfacher zu
lesen/verstehen und der Compiler wirds eh passend optimieren.
EAF schrieb:> Wilhelm M. schrieb:>> dann sollte man das auch richtig>> machen ;-)>> Dann mache doch mal eine Vorführung.
Ok, schicke Dir einen Link zum nä. Konzert ;-)
Du weißt was das Monostate-Pattern ist?
HildeK schrieb:> LED = ledOn;> wenn ledOn nur die Werte 0 und 1 annimmt.
Das ist egal, LED verlangt ein Bool, da Bitvariable. Bei Bedarf erfolgt
eine automatische Umwandlung.
Peter D. schrieb:> Das ist egal, LED verlangt ein Bool, da Bitvariable. Bei Bedarf erfolgt> eine automatische Umwandlung.
Nicht ganz, aber mein Durchblick bei sbit.h ist nicht so der Renner 😀.
Im Simulator sieht es zumindest so aus, als ob der Wert nur mit der
Maske 0x01 behandelt wird. Heißt:
LED = 1; // on
LED = 2; // off
LED = 3; // on - und so weiter.
Das ist für mich keine automatische Umwandlung in Bool, denn es ist
nicht das selbe wie: alles, was ungleich 0 (false) ist, ist dann 1
(true).
Deshalb war mein Hinweis nicht ganz unberechtigt.
Eine Anmerkung schrieb:> Jeder bastelt da irgend etwas anderes. Der Code lässt sich nicht> wiederverwenden. Nachvollziehen, was die Macros, Wrapper und Frameworks> machen, wird aufwendiger als komplett neu entwickeln.>> Nimm als Beispiel die Normen aus Maschinenbau oder Bauwesen. Alle> Ingenieure benutzen die selben Symbole und die selben Bezeichnungen.> Jeder sieht auf den ersten Blick, was der Kollege konstruiert hat.>> Wieso können wir uns nicht auf einen einheitlichen Weg einigen?
Als Mädchen mit entsprechenden Erfahrungen sage ich es so: Jeder will
den Größten haben...
Einheitlicher Weg würde ja bedeuten, dass niemand mehr "Java ist
besser!", "Nein C ist besser!", "Nein Rust ist besser!" sagen dürfte,
sondern dass sich alle einigen müssten auf ein gemeinsames Ziel. Aber
das geht doch nicht! Nicht unter Jungs jedenfalls ^^
Eine Anmerkung schrieb:> Wieso können wir uns nicht auf einen einheitlichen Weg einigen?
Ich nochmal... Mir kommt das so vor als ob es darum geht, ob
Programmieren Kunst oder Handwerk ist. Manche wollen Geld damit
verdienen, und manche wollen Applaus ^^
Dominik schrieb:> guten abend,> ich habe ein kleines logisches Problem.>> Ich möchte den Pin (AVR) anhand einer variable setzen.> Dies habe ich bisher mittels einer if-Bedingung>
1
>if(1==ledOn)
2
>{
3
>DDRD|=(1<<PIND3);
4
>}
5
>else
6
>{
7
>DDRD&=~(1<<PIND3);
8
>}
9
>
>> gibt es da auch einen eleganteren weg, wo ich direkt den wert der> Variable benutzen kann?
Der Code ist grundsätzlich scheiße.
Warum? Weil ihn niemand versteht, der nicht C-Experte ist so wie du.
Wenn ledOn bool ist, dann ist die if-clause schon falsch. Und zweitens
gehört (1 << PIND3) in eine eigene Funktion verpackt, weil "don't repeat
yourself".
HildeK schrieb:> Peter D. schrieb:>> Das ist egal, LED verlangt ein Bool, da Bitvariable. Bei Bedarf erfolgt>> eine automatische Umwandlung.>> Nicht ganz, aber mein Durchblick bei sbit.h ist nicht so der Renner 😀.>> Im Simulator sieht es zumindest so aus, als ob der Wert nur mit der> Maske 0x01 behandelt wird. Heißt:> LED = 1; // on> LED = 2; // off> LED = 3; // on - und so weiter.> Das ist für mich keine automatische Umwandlung in Bool,
Anders herum wird ein Schuh draus. Auf der rechten Seite der Zuweisung
muss ein bool stehen, und dann kommt in LED eine 0 an, wenn der false
ist und eine 1, wenn er true ist. Eine 2 oder 3 gibt es dann gar nicht.
Es ging doch darum:
HildeK schrieb:> #include "sbit.h"> .> .> .> LED = ledOn;
und um meinen Hinweis, ledOn dann als bool zu definieren.
Rolf M. schrieb:> Anders herum wird ein Schuh draus. Auf der rechten Seite der Zuweisung> muss ein bool stehen, und dann kommt in LED eine 0 an, wenn der false> ist und eine 1, wenn er true ist. Eine 2 oder 3 gibt es dann gar nicht.
Ja, richtig! Welcher Typ die Variable 'ledOn' beim TO jedoch hatte, ist
unbekannt. Deshalb schrieb ich dazu:
HildeK schrieb:> wenn ledOn nur die Werte 0 und 1 annimmt.
also auf den boolschen Zahlenraum beschränkt ist.
Du hast sinnvollerweise ergänzt, dass man für ledOn gleich eine
Boolvariable nehmen sollte. Zumindest wäre einen Cast auf bool nötigt.
Nur Peter D. hatte gemeint:
Peter D. schrieb:> Bei Bedarf erfolgt eine automatische Umwandlung.
Diese Umwandlung sehe ich nicht. Deshalb hab ich das mal getestet.