- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 10 von 19

Thema: Timer1 ISRs Genauigkeit

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Aber der Ausdruck wird/sollte doch vom Compiler als Konstante gesehen werden und auch so gehändelt werden. Wird aber offensichtlich nicht.
    Doch, wird er, aber auch diese Konstante muss ja erst vom Compiler berechnet werden. Und diese Berechnung geschieht natürlich nach den C-Regeln, damit das gleiche dabei rauskommt, wie wenn die Berechnung erst zur Laufzeit passieren würde. Im Gegensatz zur Berechnung zur Laufzeit kann der Compiler hier aber direkt sehen, dass es zu einem Überlauf kommt, und dich warnen.


    Des im Ausdruck mit uint16_t gerechnet wird, ist ebenfalls klar.
    Ne, ist nicht klar, und auch falsch. Der Teil in der Klammer wird in int gerechnet (und da passiert auch gleich der Überlauf). Das (bereits falsche) Zwischenergebnis wird dann nach long promotet, und der Rest in long weiter gerechnet (außer natürlich dein F_CPU ist ungewöhnlich klein).


    Die Wirkung von 2UL * habe ich zwar verstanden, die Hintergründe aber nicht wirklich.
    Und auch in deinem Fall hier würde ein UL (oder auch nur L) hinter einer der Zahlen in der Klammer weiterhelfen. Dadurch, dass du einen der Operanden in einen größeren Typ zwingst, erzwingst du, dass die Rechnung in der Klammer insgesamt in einem größeren Typ stattfindet.
    MfG
    Stefan

  2. #2
    Hallo Stefan,

    ich habe mich jetzt versucht mal schlau zu machen. Habe aber noch nicht alles verstanden.

    Zitat Zitat von sternst Beitrag anzeigen
    Ne, ist nicht klar, und auch falsch. Der Teil in der Klammer wird in int gerechnet (und da passiert auch gleich der Überlauf). Das (bereits falsche) Zwischenergebnis wird dann nach long promotet, und der Rest in long weiter gerechnet (außer natürlich dein F_CPU ist ungewöhnlich klein).
    Nach Deinen Hinweis ist die Sache zumindest einigermaßen klar, habe einen Fehler in den Berechnungen per Taschenrechner gemacht. (2 * 1024 * 5) wird vom Compiler als uint_16 berechnet, da die längste Zahl in diesem Ausdruck uint_16 ist. Das Ergebniss dieser Multiplikation sprengt aber uint_16. Anstelle des richtigen Ergebniss 102.400 wird mit 36.864 weitergerechnet. Die dann folgende Division F_CPU / 36.864 ist dann natürlich auch fehlerhaft. In meinem Fall ergibt sich dann 7372800 / 36.864, also 200. -1 dann, also 199. Stelle ich mir das so richtig vor? Bin mir nicht sicher, weil ich mit meiner nicht funktionieren Formel ca. 14hz gemessen habe, bei 199 müsste sich aber 18hz messen lassen. Kann aber auch an meinem Messgerät liegen. Im unteren Frequenzberich sind die Abweichungen manchmal größer.


    Zitat Zitat von sternst Beitrag anzeigen
    Und auch in deinem Fall hier würde ein UL (oder auch nur L) hinter einer der Zahlen in der Klammer weiterhelfen. Dadurch, dass du einen der Operanden in einen größeren Typ zwingst, erzwingst du, dass die Rechnung in der Klammer insgesamt in einem größeren Typ stattfindet.
    Okay. L zwingt man einer Zahl einen Datentyp auf. Mit L eine uint_32, mit UL eine uint_64? Richtig so? Weil ich leider nicht viel darüber gefunden habe. Ist das so wie eine CAST-Operator zu verstehen? Welche anderen Typkennzeichen gibt es denn noch? Oder hättest Du einen Tip, wo ich mich da schlau machen könnte?

    Code:
        #define        ocr_Wert        ((F_CPU / (1024 * 2 * 50L)) - 1)
    Was aber am wichtigsten ist, der Code funktioniert jetzt!

    Vielen Dank für Deine Tips.

    mfg

    Uwe
    Legasteniker on Board!
    gefundene Rechtschreibfehler dienen der Belustigung des Lesers und dürfen von diesem behalten werden.

  3. #3
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    (2 * 1024 * 5) wird vom Compiler als uint_16 berechnet
    Nein, als int (int16_t).


    Anstelle des richtigen Ergebniss 102.400 wird mit 36.864 weitergerechnet.
    Nein, mit -28672.
    Für die weitere Rechnung wird das nach uint32_t promotet, was 4294938624 ist. Das Ergebnis der Division ist damit 0. Und 0 - 1 in uint32_t ist 4294967295. Das wird dann nach uint8_t gecastet, und wir landen schlussendlich bei 255.


    Mit L eine uint_32, mit UL eine uint_64? Richtig so?
    Nein, L steht für long (int32_t), und UL für unsigned long (uint32_t).


    Ist das so wie eine CAST-Operator zu verstehen?
    Ja.


    Oder hättest Du einen Tip, wo ich mich da schlau machen könnte?
    In jedem halbwegs brauchbaren C-Buch.
    MfG
    Stefan

Ähnliche Themen

  1. Positionierung Genauigkeit <1mm
    Von thomas0906 im Forum Sensoren / Sensorik
    Antworten: 17
    Letzter Beitrag: 08.06.2009, 20:39
  2. Timer 1 Genauigkeit
    Von asunn im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 27.06.2008, 22:51
  3. GPS-Kompass - Genauigkeit?
    Von Jon im Forum Elektronik
    Antworten: 13
    Letzter Beitrag: 10.04.2008, 23:13
  4. Genauigkeit der Int RC Oszialtoren
    Von The Man im Forum Assembler-Programmierung
    Antworten: 7
    Letzter Beitrag: 10.04.2008, 21:22
  5. Genauigkeit von Profilen...
    Von sonic im Forum Konstruktion/CAD/3D-Druck/Sketchup und Platinenlayout Eagle & Fritzing u.a.
    Antworten: 13
    Letzter Beitrag: 25.06.2004, 12:15

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests