Forum: Mikrocontroller und Digitale Elektronik Variableüberlauf


von sebastian_83 (Gast)


Angehängte Dateien:

Lesenswert?

hallo Leute

ich habe das Programm für die Berechnung einer Frequenz mit dem Timer 
aus dem Forum entnommen  und für meine Zwecke angepasst.nun habe ich 
festgestellt wenn die Variable Ergebnis (als Double deklariert)über 
65536 ist dann habe ich nur noch falsche Ergebnisse,besonderes wenn der 
Motor sehr langsam sich dreht.kann mir jemand das erklären bzw. eine 
Lösung  vorschlagen?hiermal eine Abschnitt der zum PCS Gesendeten 
Frequenzen;
682.00
672.00
674.00
683.00
688.00
682.00
683.00
702.00
688.00
682.00
683.00
682.00
04.00  // 4 Hz entspricht F_CPU/64*4= 20000000/64*4=78125
666.00
666.00
660.00
649.00
651.00
649.00
639.00
636.00

von Peter (Gast)


Lesenswert?

> Ergebnis = (double)(Nrueberlaufe * 65536 ) ;
das schein ein problem zu sein. Denn (Nrueberlaufe * 65536) wird als int 
berechnet und da ist bei einem 16bit system bei 65536 schluss.

Bist du sicher das du double verwenden willst? Das ganze ist kann etwas 
langsam werden.

Teste erstmal mit:

> Ergebnis = (double)Nrueberlaufe * 65536.0;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Peter schrieb:
> Bist du sicher das du double verwenden willst? Das ganze ist kann etwas
> langsam werden.
Es kann auch sein, dass es einfach als single precision float 
realisiert wird...  :-o

von sebastian_83 (Gast)


Lesenswert?

danke Peter
ja ich möchte gern die Frequenz in nachkommastellen darstellen.
mit deinem Vorschlag tauchen die ausreißer weiter..sollte ich die 
anderen Variablen auch als Double deklarieren?

von Stefan E. (sternst)


Lesenswert?

sebastian_83 schrieb:

> mit deinem Vorschlag tauchen die ausreißer weiter..sollte ich die
> anderen Variablen auch als Double deklarieren?

Nein, du solltest gar kein double verwenden, und dich statt dessen über 
Festkomma-Arithmetik informieren.

von sebastian_83 (Gast)


Lesenswert?

also an double liegt bestimmt nicht.
ich habe die variablen als uint32_t definiert(stdint.h ist included)und 
mit ultoa() ausgegeben ,trotsdem bei 65536 ist schluss das kann doch 
nicht wahr sein!!!!!

von Stefan E. (sternst)


Lesenswert?

sebastian_83 schrieb:
> also an double liegt bestimmt nicht.

Das war jetzt nicht unbedingt auf dein konkretes Problem bezogen, 
sondern allgemein auf das, was du da machst.

> ich habe die variablen als uint32_t definiert(stdint.h ist included)und
> mit ultoa() ausgegeben ,trotsdem bei 65536 ist schluss das kann doch
> nicht wahr sein!!!!!

Und der Code zu diesem Problem sieht konkret wie aus?

Was sollen eigentlich die cli() und sei() in der Interrupt-Routine? Das 
cli() ist ohne Funktion und das sei() ist sogar gefährlich. Das Testen 
des TOV1-Flags ist z.B. völlig sinnlos, wenn direkt davor ein sei() 
steht. Was denkst du denn, was beim sei() passiert, wenn das Flag da 
gerade gesetzt ist?

Und diese Zeile ist auch äußerst fragwürdig:
>    Ergebnis += (double)(Endezeit)  - (double)(anfangszeit);
Ich bezweifle, dass da der Fall Endezeit<anfangszeit korrekt gehandhabt 
wird (wie es bei Unsigned-Integer-Arithmetik der Fall wäre).

von Lehrmann M. (ubimbo)


Lesenswert?

sebastian_83 schrieb:
> 04.00

nur so ein Tipp für einen vielleicht zukünftigen Fehler: das müsste 
eigentlich einen Fehler ergeben. Eine vorausgestellte Null ergibt in C 
die oktale Darstellung (0868 ist ungleich 868)!

von Stefan E. (sternst)


Lesenswert?

Lehrmann Michael schrieb:
> sebastian_83 schrieb:
>> 04.00
>
> nur so ein Tipp für einen vielleicht zukünftigen Fehler: das müsste
> eigentlich einen Fehler ergeben.

Warum soll es einen Fehler ergeben, wenn eine Zahl mit einer führenden 
Null ausgegeben wird?

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
Noch kein Account? Hier anmelden.