Hallo zusammen! Ich hoffe ich bin hier richtig? Meine IDE ist MPlab X mit dem XC8 Compiler (Free-Version). Controller: PIC16F1789 (was aber erst mal keine Rolle spielen dürfte) folgenden Code habe ich in einer Header-Datei: #define TMR_TEST 27.2 #define TMR_DEVIDER ((int)TMR_TEST) #if TMR_DEVIDER < 1 #define RTCC_DEVIDER RTCC_DIV_1 #define DV 0 #elif TMR_DEVIDER < 2 #define RTCC_DEVIDER RTCC_DIV_2 #define DV 1 #elif TMR_DEVIDER < 4 #define RTCC_DEVIDER RTCC_DIV_4 #define DV 2 #elif TMR_DEVIDER < 8 #define RTCC_DEVIDER RTCC_DIV_8 #define DV 3 #elif TMR_DEVIDER < 16 #define RTCC_DEVIDER RTCC_DIV_16 #define DV 4 #elif TMR_DEVIDER < 32 #define RTCC_DEVIDER RTCC_DIV_32 #define DV 5 #elif TMR_DEVIDER < 64 #define RTCC_DEVIDER RTCC_DIV_64 #define DV 6 #elif TMR_DEVIDER < 128 #define RTCC_DEVIDER RTCC_DIV_128 #define DV 7 #elif TMR_DEVIDER < 256 #define RTCC_DEVIDER RTCC_DIV_256 #define DV 8 #else #error #endif Ausgeführt wird hier der #error obwohl der CAST von 27.2 (float) nach int 27 ergibt. Eigentlich muss #elif TMR_DEVIDER < 32 ausgeführt werden. Ändere ich es wie folgt: #define TMR_TEST 27 #define TMR_DEVIDER TMR_TEST wird #elif TMR_DEVIDER < 32 ausgeführt. Kann mir das jemand erklären? Vielen Dank! Gruß Florian
Florian schrieb: > Ausgeführt wird hier der #error obwohl der CAST von 27.2 (float) nach > int 27 ergibt. Deine Macros werden vom Präprozessor interpretiert. Der weiß gar nicht, was float ist.
der Präprozessor kann nur int. Auch der Cast nach int kann er nicht. Das ist die Aufgabe vom Compiler
Danke für die schnellen Antworten! Wenn ich in der Main einen der defines in eine Variable schreiben lasse und diese dann über einen breakpoint anschaue, steht in der Variablen das erwartete Ergebnis. Ich lasse z.B. einen Wert berechnen wie: #define ZEIT. 127 #define WERT (1/(ZEIT/4000.0)) In der Main dann: float Test; While(1) { Test = WERT; } Dabei steht in Wert dann 35... Schreibe ich aber: #define WERT ((int)(1/(ZEIT/4000.0))) steht in Test 35.0. Der Cast nach int muss also funktioniert haben. .0 ist klar, weil Test ja Datentyp "float" ist. Ändere ich auch das auf int oder char steht in Test nur noch 35. Der Compiler bemängelt hier auch nichts. Wenn Test aber vom Typ int oder char ist und ich den Cast nach int beim define weglasse (also wieder 35.49 hinter WERT steht) bemängelt der Compiler eine unerwartete Zuweisung von float nach int (oder eben char). Wenn ich jetzt aber annehme, dass der Cast nach int beim define funktioniert, dann ist mir völlig unklar, warum dann die if / elif Anweisungen nicht zum logischen Ergebnis führen. Die Vermutung liegt aber nahe, dass es durchaus mit dem Cast zu tun hat, weil wenn ich #define WERT 35 schreibe stimmt auch das was beim if / elif passiert. Ich verstehe ganz einfach den Unterschied zwischen #define WERT 35 und #define WERT ((int)(1/(ZAHL/4000.0))) nicht, weil sowohl im einen, als auch im anderen Fall der Wert der Variablen Test 35 ist. Für das if / elif nach dem define ist aber offensichtlich ein Unterschied vorhanden. Und den würde ich gerne kennen... Vielen Dank Gruß Florian
Es muss natürlich #define ZEIT 127 heißen anstatt #Delfine ZEIT. 127
Florian schrieb: > Für das if / elif nach dem define ist aber > offensichtlich ein Unterschied vorhanden. Und den würde ich gerne > kennen... du musst zwischen Präprozessor und Compiler unterscheiden. cast macht nur der Compiler, das ifdef macht aber der Präprozessor. Damit sollte eigentlich klar sein, warum es nicht geht.
In diesem Fall ersetzt der Präprozessor nur den Text, rechnet aber nichts selbst.
Vielen Dank! Soweit verstehe ich das jetzt. Die ganze if Geschichte kann der Präprozessor also nicht sinnvoll ausführen, weil die Berechnungen der defines noch nicht gemacht sind zu diesem Zeitpunkt. Die einzige Lösung für den Fall wäre also, wenn ich die defines so lasse (mitsamt CAST) und die if Geschichte dann vom Controller einmalig am Anfang ausführen lasse. Z.B. in einer INIT-Funktion. Aber was ich immer noch nicht verstehe ist, warum es mit dem alten Compiler unter MPLAB 8 so funktioniert hat? Ist der Präprozessor/Compiler in dieser Hinsicht also "schlechter" oder "dümmer" geworden? Der Vorteil war eben, ohne RAM oder Flash zu verbrauchen den kompletten INIT für einen Timer zu haben (und nicht alles selbst rechnen zu müssen). Gruß Florian
kann man nicht eventuell RTCC_DEVIDER brechnen? Hinter dem define RTCC_DIV_256 stehen doch auch nur Zahlen.
Es dürfte genügen, das hier #define TMR_TEST 27.2 #define TMR_DEVIDER ((int)TMR_TEST) zu verkürzen und für TMR_TEST direkt einen ganzzahligen Wert zu verwenden, bzw. auf TMR_TEST zu verzichten und gleich den ganzzahligen TMR_DIVIDER* zu nutzen. Warum muss "TMR_TEST" ein nichtganzzahliger Float-Wert sein? *) Den Teiler schreibt man übrigens divider
Nochmal Danke für die Erklärungen und Ansätze! der Code aus meinem 1. Post dient als Beispiel was die defines Betrifft um mein Problem vereinfacht darstellen zu können. (Bitte nicht steinigen!!) Das ist die eigentliche Version: #define INT_FREQ (1/(Entprellzeit/4000.0)) #define INTER_CLOCK_CORR 35 #define CLK_EFF (OSC_CLK/4.0) #define CLK_PERINTERRUPT (CLK_EFF/INT_FREQ) #define TMR_DEVIDER ((int)(CLK_PERINTERRUPT/256)) #if TMR_DEVIDER < 1 #define RTCC_DEVIDER RTCC_DIV_1 #define DV 0 #elif TMR_DEVIDER < 2 #define RTCC_DEVIDER RTCC_DIV_2 #define DV 1 #elif TMR_DEVIDER < 4 #define RTCC_DEVIDER RTCC_DIV_4 #define DV 2 #elif TMR_DEVIDER < 8 #define RTCC_DEVIDER RTCC_DIV_8 #define DV 3 #elif TMR_DEVIDER < 16 #define RTCC_DEVIDER RTCC_DIV_16 #define DV 4 #elif TMR_DEVIDER < 32 #define RTCC_DEVIDER RTCC_DIV_32 #define DV 5 #elif TMR_DEVIDER < 64 #define RTCC_DEVIDER RTCC_DIV_64 #define DV 6 #elif TMR_DEVIDER < 128 #define RTCC_DEVIDER RTCC_DIV_128 #define DV 7 #elif TMR_DEVIDER < 256 #define RTCC_DEVIDER RTCC_DIV_256 #define DV 8 #else #error CPU-Clock zu gering #endif #define REST (((int)(CLK_PERINTERRUPT/(1<<DV))) % 256) #define RTCC_Preset (256- ( REST - (INTER_CLOCK_CORR/(1<<DV)))) Entprellzeit ist bei mir 127 (im Moment zum Probieren). Der Gedanke ist mit dem Programm den Timer entsprechend aufzuziehen, so dass dieser dann in der gewünschten Zeit die Taster / Schalter entprellt. Und schön ausprobieren / einstellen (man will ja auch nicht zu lange warten) kann man das dann wenn man nur die Entprellzeit von 1 bis 255 in ms angeben muss. Natürlich geht das auch wenn ich es einmalig den Controller berechnen lasse oder zumindest alles nach den defines den Controller machen lasse. Kostet aber halt wieder Flash und RAM. Und da das früher gut funktioniert hat, hätte ich halt gerne.... ;-) Das sind übrigens Teile von accurateinterrupt.h die man im Netz findet. Verwendet habe ich die damals mit einem HI-Tech Compiler unter MPlab 8. Danke für den Hinweis mit "DEVIDER" --> "DIVIDER". Ich habs schon 100x gelesen, mir ist es aber nie aufgefallen. Gruß Florian
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.