Hallo Leute, ich habe in mein Quelltext folgende Berechnung für mein ATMEGA16 eingeügt und bekomme Warnungen: Division by Zero Ich weiß aber nicht warum, ich dividiere doch gar nicht durch 0... MFG Muecke
Sorry, ei wenig durcheinander. Hier natürlich noch der Quelltext:
1 | if(CONFIG.FREQ <= 100 && CONFIG.FREQ != 0) |
2 | OCR1A = ((1/CONFIG.FREQ) / (1/(4000000/64))) / 2; |
3 | |
4 | else if(CONFIG.FREQ > 100 && CONFIG.FREQ <= 255) |
5 | OCR1A = ((1/CONFIG.FREQ) / (1/(4000000/8))) / 2; |
6 | |
7 | else if(CONFIG.FREQ < 255) |
8 | OCR1A = ((1/CONFIG.FREQ) / (1/4000000)) / 2; |
Ich glaube schon: 1/(4000000/64) müsste eigentlich eine Integeroperation sein, da kommt also Null raus. Probier es mal mit: ((1.0/CONFIG.FREQ) / (1.0/(4000000.0/64.0))) / 2.0 CONFIG.FREQ muss ein Float sein.
Ich hab jetzt mal keine Ahnung, was CONFIG.FREQ ist, vermute aber eine Gleitkommavariable dahinter. Fehler liegt z.B. hier: 1/(4000000/64) Du dividierst 1 durch einen ziemlich großen Wert. Beides sind Ganzzahlen, das Ergebnis ist eine Ganzzahl und wird abgerundet, also auf 0. Warum invertierst du die Zahl, um dann dadurch zu dividieren? Lass das 1/ und mach aus dem / davor ein *.
Die letzte Zeile kann erreicht werden wenn CONFIG.FREQ==0 und dann hast Du eine Division by Zero
OK Danke. ich habe überall ein ".0" angefügt und CONFIG.FREQ gecastet... Funktioniert nun
Der Sinn der letzten else if Anweisung erschliesst sich mir aber auch nicht. Wofür soll die sein?
Anmerkung nebenbei... Wäre es für deine Anwendung ungünstig, die Formel ((1/CONFIG.FREQ) / (1/(4000000/64))) / 2; umzustellen als (4000000/64) 2 CONFIG.FREQ; ? Ich denke das ist eher das, was du meinst, und die Konstanten am Anfang kann ein vernünftiger Compiler auch besser zusammenfassen. Beschreibe doch mal, was CONFIG.FREQ ist (Ganzzahl, Fließkommazahl, in welchem Wertebereich).
Es müsste doch reichen, die 4Mio. als "long" zu kennzeichnen ("L" anhängen), oder? (besser als zu 'riskieren', dass die Float-Berechnung nicht wegoptimiert wird) hth. Jörg
CONFIG.FREQ ist definiert als uint16_t. Also eine 16bit-Zahl. Hiermit sollen die Frequenzen erzeugt werden mit Timer1 und es funktioniert jetzt soweit. Mit dem Umstellen werde ich mal probieren... Danke...
Immer an Mathe denken: A/(1/B)==A*B Das erste geht hier durch die Integerarithmetik schief, also warum die linke Seite verwenden, wenn die rechte besser geht? Denn die Spezialitäten der Integerarithmetik willst du ja eigentlich gar nicht. Und die if-Abfragen würde ich noch einmal überarbeiten. Besonders das < in der letzten Abfrage sollte ein > sein.
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.