Jetzt bin ich zum zweitenmal über das Problem gestolpert, was bisher keins war. Normalerweise ist das kein Problem, manchmal sind die Dinge aber auch etwas komplexer. Aktuelles Beispiel: Temperatur wird mit einem NTC gemessen, Ziel ist es, ab einer bestimmten Temperatur einen Grenzwert für eine PWM zu berechnen. Bei steigender Temperatur soll die PWM immer weiter zurückgenommen werden, irgendwann ganz abgeschaltet werden. Kunde ist noch am experimentieren, ändert sich täglich. Also im Idealfall als Eingabe: #define PWM_Absenkung_Temperatur_Start 60 //°C #define PWM_Absenkung_Temperatur_Ende 85 //°C #define PWM_Absenkung 55 //auf 55% bei 85° Den ganzen Rest würde ich gerne dem Compiler überlassen. Also aus der Temperatur über die NTC-Kennlinie und Vorwiderstand die entsprechenden A2D-Werte berechnen, daraus die Steigung, Offset und letztendlich einen aktuellen Maximalwert für die PWM. Lange Rede, kurzer Sinn: da kommen etliche Berechnungen zustande und ich würde gerne sehen, welche (Zwischen)Werte der Compiler berechnet hat, habe gerade eine Stunde verdaddelt, weil ich einen Vorzeichenfehler drin hatte. Ebenso sind leicht Rundungsfehler und/oder Zahlenbereichsüberschreitungen möglich. Weder im Assembler noch im listing sehe ich die Werte. Gibts da einen Weg?
Du kannst den GNU C Preprocessor drüberlaufenlassen, wenn du den gcc installiert hast. cpp header.h
Der Präprozessor rechnet nur an exakt einer Stelle: in der Bedingung von #if. Sonst nirgends. So gehts also nicht.
H.joachim Seifert schrieb: > Gibts da einen Weg? Kannst du versuchen, das etwas verständlicher auszudrücken? Dass man Zwischenergebnisse von Berechnungen irgendwo ausgeben kann brauche ich dir ziemlich sicher nicht zu erzählen, drum verstehe ich das Problem nicht. Und was das nun mit #define zu tun hat auch nicht, denn dem Compiler ist es schnurz, ob man mit #define arbeitet, mit oder ohne Formeln darin, oder ob man es direkt hinschreibt.
H.joachim Seifert schrieb: > Den ganzen Rest würde ich gerne dem Compiler überlassen. Also aus der > Temperatur über die NTC-Kennlinie und Vorwiderstand die entsprechenden > A2D-Werte berechnen, daraus die Steigung, Offset und letztendlich einen > aktuellen Maximalwert für die PWM. > > Lange Rede, kurzer Sinn: da kommen etliche Berechnungen zustande und ich > würde gerne sehen, welche (Zwischen)Werte der Compiler berechnet hat, ??? Sobald Laufzeitwerte im Spiel sind, hilft nur noch ein Debugger. Irgendwelche Konstanten verknüpft der Preprocessor. Die Vereinfachung sieht man im Assembler Listing.
Im konkreten Fall: Ich will zur Compilezeit 2 Temperaturwerte eingeben und einen Reduktionsfaktor einstellen können. -Aus den Temperaturwerten ergeben sich aus der Kennlinie des NTC 2 Werte, sagen wir 350 und 700 (diese würde ich gerne irgendwo sehen) -aus der PWM-Reduktion von 55% ergibt sich ein OCR-Wert von 140 bei 8bit-PWM -also DeltaX 350 (würde ich gerne sehen) -DeltaY 115 (würde ich gerne sehen) -aus den 350 A2D und 255 für 100% PWM und der Steigung 115/350 ergibt sich ein offset von -25 (würde ich gern sehen) Das eigentliche Programm läuft dann ganz primitiv mit y=ax+b, wobei a und b schon vom Compiler berechnet werden sollen. Da die Ermittelung von a und b in mehreren Stufen abläuft, sind da schon ein paar Fehlerquellen drin. Ich habe meinen Fehler damit gefunden, dass ich berechnete defines (wie Delta_X, Delta_Y u.a zu Testzwecken am Programmstart in Variable geladen habe und dann sehen konnte. Nicht besonders elegant, finde ich. Läuft jetzt ja, aber prinzipiell würde mich das schon interessieren
oder einfacher: #define A 499 #define B A/2 Ich möchte sehen, mit welchem Wert für B ab diesem Zeitpunkt gerechnet wird.
H.joachim Seifert schrieb: > Ich habe meinen Fehler damit gefunden, dass ich berechnete defines > (wie Delta_X, Delta_Y u.a zu Testzwecken am Programmstart in Variable > geladen habe und dann sehen konnte. > Nicht besonders elegant, finde ich. Anders gehts aber nicht. Der Preprozessor macht im Prinzip nur Textersetzung. Das Ausrechnen der konstanten Werte macht der Compiler bei der Optimierung. Wenn die Zwischenergebnisse nicht explizit in einer Variable gespeichert und ausgegeben werden, tauchen die nirgends aus.
H.joachim Seifert schrieb: > oder einfacher: > #define A 499 > #define B A/2 > > Ich möchte sehen, mit welchem Wert für B ab diesem Zeitpunkt gerechnet > wird. Wie wäre es mit printf("%d", B);
Setzt eine serielle Schnittstelle voraus (die ich in dem Fall auf dem Tiny25 nicht habe), erfordert Eingriffe in den Code, und printf() bekäme ich eh nicht rein... Tja, scheint wohl wirklich nicht direkt zu gehen. Wundert mich eigentlich, man sieht schon mal interessante Konstrukte bei #define. Fehler passieren immer wieder mal selbst bei den einfachsten Sachen, und die können durchaus überdeckt sein.
H.joachim Seifert schrieb: > Wundert mich eigentlich, man sieht schon mal interessante Konstrukte bei > #define. Fehler passieren immer wieder mal selbst bei den einfachsten > Sachen, und die können durchaus überdeckt sein. Anhand der #defines macht der C-Präprozessor nur strohdoofe Textersetzungen, rechnen tut der gar nicht. Erst der Compiler wertet das aus. Wenn du Zwischenergebnisse sehen willst, kannst du die als Konstante irgendwo zuweisen und dir das dann im erzeugten Code ansehen. Aber was hindert dich ansonsten daran, die Algorithmen auf etwas anderem als einem Tiny25 zu entwickeln?
WQas habt ihr alle mit "Zuweisen an eine Variable"? Er kann die "berechneten Werte" auch ganz einfach per #error anzeigen lassen.
Maximilian schrieb: > WQas habt ihr alle mit "Zuweisen an eine Variable"? > > Er kann die "berechneten Werte" auch ganz einfach per #error anzeigen > lassen. Nein, kann er nicht. Abgesehen davon, daß der Präprozessor - wie schon mehrfach erwähnt - den Wert NICHT sebst ausrechnet und das Ergebnis daher auch nicht ausgeben kann, ist #error egal, ob der ihm übergebene Text irgendwas enthält, das dem Namen eines Makros entspricht. Der wird einfach nur ausgegeben. Wolfgang schrieb: > Aber was hindert dich ansonsten daran, die Algorithmen auf etwas anderem > als einem Tiny25 zu entwickeln? Ja. Im einfachsten Fall schreibt man sich ein winziges C-Progrämmchen für den PC, in das man die #defines reinkopiert und das dann per printf das Ergebnis ausgibt.
Rolf Magnus schrieb: > Ja. Im einfachsten Fall schreibt man sich ein winziges C-Progrämmchen > für den PC, in das man die #defines reinkopiert und das dann per printf > das Ergebnis ausgibt. So mach ich das auch immer. Da reicht schon der Uralt-C Compiler von Borland (Turbo C 2.x), den es kostenlos und legal im Netz zum Download gibt. Der Vorteil: Auch für ein 16 Bit System, wie meine uC Zielhardware.
printf ist doch keien Lösung, bestenfalls fürs Hobby... H.joachim Seifert schrieb: > Setzt eine serielle Schnittstelle voraus (die ich in dem Fall auf dem > Tiny25 nicht habe), erfordert Eingriffe in den Code, und printf() bekäme > ich eh nicht rein... Falls die Konstanten vom vom Compiler gefaltet werden, sieht du das in Compiler-Dumps, z.B. in .optimized das mit -fdump-tree-optimized erstellt werden kann (GCC). Der Code ist C-ähnlich und direkt verständlich. Noch mehr Dumps bekommst du mit -fdump-tree-all.
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.