Hallo
und obwohl bei deinem Verständnis was anders rauskommt als bei deiner 1.
Lösung ist der Compiler schuldig ???
__Son´s B. schrieb:> Obwohl nach meine Verständnis folgender Ersatz raus kommen sollte;
#define BATT_ON (AUSGANG_SET_HIGH((PORTA,PA4)))
__Son´s B. schrieb:> #define BATT_ON (AUSGANG_SET_HIGH(PORTA,PA4))
zähl doch einfach mal die Anzahl der Klammern nach ...
mfg
DerDan
Tom schrieb:> Was man nicht alles tun muss, um die bösen performance-mordenden> Funktionen zu vermeiden...
Deine Bemerkung kann ich gut nachvollziehen.
Versuche aktuell alle Grundparameter, Ports und Pins in einem
Makro-Block zu hinterlegen. Die PORT/PIN-Zuweisung ist der letzte
Schritt.
Tom schrieb:> Was man nicht alles tun muss, um die bösen performance-mordenden> Funktionen zu vermeiden...
Niemand muß sowas, es gibt bessere Möglichkeiten, z.B.:
1. Portpins als Bitvariablen definieren
2. Inline-Funktionen
__Son´s B. schrieb:> Compiler meckert!
Gehts bitte noch ungenauer?
Copy&Paste den genauen Fehlertext!
Hänge den Quelltext als Anhang an, dann kann man sogar die Zeilennummer
in der Meldung zuordnen.
Peter D. schrieb:> Copy&Paste den genauen Fehlertext!> Hänge den Quelltext als Anhang an, dann kann man sogar die Zeilennummer> in der Meldung zuordnen.
siehe Anhang.
nicht der Fehler aber damit wirst Du dir ins Knie schießen:
#define LED_OFF (AUSGANG_SET_LOW(PORTA,PA5));
(AUSGANG_SET_LOW(PORTA,PA6)); (AUSGANG_SET_LOW(PORTA,PA7)) // alle LEDs
werden gelöscht
was kommt da raus wenn du
if ( quark )
LED_OFF;
schreibst?
Walter S. schrieb:> nicht der Fehler aber damit wirst Du dir ins Knie schießen:
Warum?
Alle 3 LEDs liegen auf low.
Funktioniert tatsächlich einwandfrei!
__Son´s B. schrieb:> Alle 3 LEDs liegen auf low.> Funktioniert tatsächlich einwandfrei!
nee,
die erste geht auf LOW wenn quark true ist
die beiden anderen gehen IMMER auf LOW
__Son´s B. schrieb:> Warum?
Du solltest dir hin und wieder mal ansehen, was aus dem Präprozessor
so hinten „herausfällt“. (avr-gcc ... -E) Dann würde dir vielleicht
auffallen, dass der Präprozessor von C keine Ahnung hat sondern stur
Texte ersetzt, und vielleicht entdeckst du dann auch mal das unsinnige
Semikolon im Zeichenstrom. ;)
Ansonsten funktioniert das, was du machen willst, zweistufig.
Ich hatte meine Lösung schon mal gepostet, auch wenn sie „W.S.“ nicht
gefiel. ;-)
1
#define GLUE(a, b) a##b
2
3
/* single-bit macros, used for control bits */
4
#define SET_(what, p, m) GLUE(what, p) |= (1 << (m))
5
#define CLR_(what, p, m) GLUE(what, p) &= ~(1 << (m))
Walter S. schrieb:> die beiden anderen gehen IMMER auf LOW
Schau dir die beiden darüber liegenden Makros an - da geht nichts nach
der ersten Anweisung IMMER auf LOW!
Da diese Anweisung einwandfrei funktioniert, konzentriere ich mich
lieber auf das was nicht klappt;
__Son´s B. schrieb:> solch eine Parametrierung machen;> #define AUSGANG_SET_HIGH(port,mask) ((port) |= (1<<mask))> #define PORT_BATT_OUT(PORTA,PA4)> #define BATT_ON (AUSGANG_SET_HIGH(PORT_BATT_OUT))> Compiler meckert!
__Son´s B. schrieb:> Schau dir die beiden darüber liegenden Makros an - da geht nichts nach> der ersten Anweisung IMMER auf LOW!
Doch. Dicker Fehler, den Du nur noch nicht verstanden hast.
Ich vereinfache mal, dann wird es klarer:
1
#define A() a();b();c();
2
...
3
if(x)
4
A()
Was macht der Preprocessor draus?
1
if(x)
2
a();b();c();
Das kann man ohne Code-Änderung umschreiben in:
1
if(x)
2
a();
3
b();
4
c();
Da ohne geschweiften Klammern nur a() im if-Block steckt, werden b() und
c() IMMER ausgeführt, egal, ob man es nebeneinander oder untereinander
schreibt.
Merke: Wenn Du sagst: "Es funktioniert aber", dann heisst das lediglich,
dass Du es nur im falschen Kontext getestet/überdacht hast - hier
nämlich für x != 0.
__Son´s B. schrieb:> Ob mit oder ohne Leerzeichen verändert nichts!
Aber die Bedeutung der Zeile ist mit und ohne Leerzeichen drastisch
anders. Du hast eben mehr als nur einen Fehler drin.
Frank M. schrieb:> Da ohne geschweiften Klammern nur a() im if-Block steckt, werden b() und> c() IMMER ausgeführt,
Klar, passt doch!
Aber nicht, wie Walter S schrieb; "IMMER auf LOW".
Bsp: Folgend sollen alle 3 Befehle nacheinander ausgeführt werden;
...
#define LED_LOW (AUSGANG_SET_LOW(PORTA,PA5));
(AUSGANG_SET_LOW(PORTA,PA6)); (AUSGANG_SET_HIGH(PORTA,PA7))
...
LED_LOW;
...
Somit LED_high aus, LED_mid aus, LED_low ein.
Funktioniert auch Live nach dem 1000-sten mal.
Oder meinst du, dass es eine "unsaubere" Syntax ist?
__Son´s B. schrieb:> Oder meinst du, dass es eine "unsaubere" Syntax ist?
Ja, ist es. Er schrieb ja auch, warum. Wenn du schreibst:
1
if(some_event)
2
LED_LOW();
… dann erwartest du vermutlich, dass die LEDs nur dann alle geschaltet
werden, wenn „some_event“ eintrifft, und nicht nur der Ausgang auf PA5
von der Bedingung abhängt.
__Son´s B. schrieb:> Klar, passt doch!> Aber nicht, wie Walter S schrieb; "IMMER auf LOW".
dann lies das noch Mal:
Walter S. schrieb:> nicht der Fehler aber damit wirst Du dir ins Knie schießen:>> #define LED_OFF (AUSGANG_SET_LOW(PORTA,PA5));> (AUSGANG_SET_LOW(PORTA,PA6)); (AUSGANG_SET_LOW(PORTA,PA7)) // alle LEDs> werden gelöscht>> was kommt da raus wenn du>> if ( quark )> LED_OFF;>> schreibst?
das wird zu:
if ( quark )
LED1 low;
LED2 low;
LED3 low;
2 und 3 werden also IMMER low
Walter S. schrieb:> 2 und 3 werden also IMMER low
in dem Fall soll das auch so sein!
Da bei mir if-Anweisungen in {} stehen, ist die Problematik noch nicht
aufgefallen.
Lösungsvorschlag von Jörg Wunsch liest sich (als Anfänger) äusserst
aufwendig.
__Son´s B. schrieb:> Lösungsvorschlag von Jörg Wunsch liest sich (als Anfänger) äusserst> aufwendig.
ja, ist aber leider so
Aber warum nimmst du nicht inline-Funktionen, du ersparst dir vieles und
die Laufzeit wirst du normalerweise nicht merken
Walter S. schrieb:> Aber warum nimmst du nicht inline-Funktionen
Mag blöd klingen, aber ich finde blockartige Makros im Header einfacher,
transparenter und schneller zu erfassen...
__Son´s B. schrieb:> Mag blöd klingen, aber ich finde blockartige Makros im Header einfacher,> transparenter und schneller zu erfassen...
Geil,
du bist selbt der beste Gegenbeweis, dass dem nicht so ist. Du siehst
bei deinem relativ einfachen Code selber nicht schon durch und auch kein
anderer kann die wirklich helfen, finden aber Fehler, die du nicht
siehst.
Vieeeeeeel transparenter.
__Son´s B. schrieb:> Lösungsvorschlag von Jörg Wunsch liest sich (als Anfänger) äusserst> aufwendig.
Den Aufwand hatte aber nur ich damit, mir das auszudenken. ;-)
Du kannst den Kram einfach in einen Header packen und benutzen.
Der wesentliche Trick ist die doppelte Verschachtelung, also ein
FOO(), welches dann ein FOO_() aufruft. Der weitere Aufwand, den
ich getrieben habe, dient dann nur dazu, die AVR-Eigenheit der
heiligen Registerdreifaltigkeit (PORTx, PINx, DDRx) so abzubilden,
dass man das „x“ nur an genau einer Stelle im Headerfile schreiben
muss.