Hallo,
Ich brauch mal einen Gedankenanstoss,
(Es muss Timer0 benutzt werden, so Aufgabenstellung.)
Undzwar soll alle 460,33ms ein Interrupt ausgelöst werden.
Mein Vorgehen:
Da der PIC mit 48 Mhz getaktet ist, wird der Timer0 mit einem Viertel
unseres Taktes getaktet.
So die maximale Zählhöhe des Timer0 ist 2^16.
So also würden folgende Einstellungen des Timer0 lauten:
-16bit Counter
-Internal instruction cycle clock(Fosc/4)
-Prescaler: den müssen wir jetzt in abhängigkeit unseres Zählwertes etc
einstellen.
Zählhöhe: 65535
Jetzt müssen wir ausrechnen wie lange ein Zählschritt brauchen muss
damit wir bei einer Zählhöhe von 65535 eine Zeit von 460,33ms brauchen.
460,33 ms / 65535 = 7,02*10^(-6)
Also brauch er 7,02*10^(-6) pro Zähleinheit.
Ich weiss jetzt nicht so richtig weiter, bitte um Hilfe,
Vielen dank, Gruss
New D. schrieb:> Jetzt müssen wir ausrechnen wie lange ein Zählschritt brauchen muss> damit wir bei einer Zählhöhe von 65535 eine Zeit von 460,33ms brauchen.> 460,33 ms / 65535 = 7,02*10^(-6)> Also brauch er 7,02*10^(-6) pro Zähleinheit.
Man kanns so rechnen. Ist aber meiner Meinung nach umständlich.
So ein µC hat ja nicht unendlich viele mögliche Prescaler.
Probier einen nach dem anderen durch, mit einer Zählweite von 65536. Bei
welcher Zeit landest du dann jeweils?
Da das ganze nach Hausaufgabe aussieht und die angestrebte Zeit derart
krumm ist, bin ich mir ziemlich sicher, dass sich die Rechnerei bei
irgendeinem der verfügbaren Vorteiler genau ausgeht.
Das ganze ist auf dem Schweirigkeitsgrad von:
vom Baum fällt alle 5 Sekunden 1 Apfel.
Wenn ich mit dieser Fallrate 2 Stunden abstoppen müsste, wie viele Äpfel
müssen dann runter fallen? Wenn ich mit den runterfallenden Äpfel 12
Apfelkisten voll machen will, wieviele Äpfel müssen dann in jeweils 1
Kiste?
Recht viel mehr steckt bei diesen ganzen Timerbetrachtungen nicht
dahinter. Du klebst zu sehr an den Formeln ohne dir zu überlegen, was du
eigentlich ausrechnest und warum.
New D. schrieb:> Jetzt müssen wir ausrechnen wie lange ein Zählschritt brauchen muss> damit wir bei einer Zählhöhe von 65535 eine Zeit von 460,33ms brauchen.> 460,33 ms / 65535 = 7,02*10^(-6)> Also brauch er 7,02*10^(-6) pro Zähleinheit.
schön.
Bei einem Prescaler von 1 und dieser Einstellung ...
> Da der PIC mit 48 Mhz getaktet ist, wird der Timer0 mit> einem Viertel unseres Taktes getaktet.> So die maximale Zählhöhe des Timer0 ist 2^16.> So also würden folgende Einstellungen des Timer0 lauten:> -16bit Counter> -Internal instruction cycle clock(Fosc/4)
... würde er wie lange für 1 Zählschritt brauchen?
Jetzt wissen wir, wie lange (bei einem Prescaler von 1) ein Zählschritt
dauern würde. Wir wissen auch, wie lange er dauern soll. Daraus kann man
jetzt ausrechnen um welchen Faktor runtergeteilt werden muss, damit aus
dem 'Ist' das 'Soll' wird.
Aber man hat hier ekelhafte kleine Zahlen. Ich finde die Umkehrung
einfacher zu rechnen: wie schnell wird der Timer getaktet. Durch welchen
Prescaler wird geteilt? Wie weit wird damit gezählt? Das dauert daher
wie lange?
Und das probier ich für die 4 oder 8 Prescaler, die es gibt durch. Beim
ersten Prescaler (1) sieht man ohnehin, ob man mit dem Ergebnis weit
daneben ist. Ein höherer Prescaler (zum Beispiel 8) verlängert die Zeit
auf genau das x fache des Prescaler Wertes (also zum Beispiel das
8-fache). Hab ich den ersten Wert bei einem Prescaler von 1, dann kann
man mal im Kopf überschlagen, welcher Prescaler Wert wohl am nächsten
drann ist. Kommt bei der Rechnung mit einem Prescaler von 1 ein Wert von
1ms raus, und will ich eine Zeit von 64ms, dann wird ein Prescler von 64
(falls verfügbar) genau das leisten.
Ist der notwendige Prescaler nicht verfügbar, dann nimmt man den nächst
größeren verfügbaren und rechnet damit zurück, bis wie weit der Timer
damit zählen muss, damit man die gewünschte Zeit kriegt. Wenn das
bisherige sitzt, dann solltest du damit keine Schwierigkeiten haben, dir
den Rechengang dazu selbst herzuleiten.
New D. schrieb:> -Internal instruction cycle clock(Fosc/4)> -Prescaler: den müssen wir jetzt in abhängigkeit unseres Zählwertes etc> einstellen.
Richtiger Ansatz.
Falsche Ausführung.
Wenn Du mit 48 MHz taktest und einen FOSC/4 hast kommt am Zähler 12MHz
an.
640,33ms / 0,0833us = 76.839.600. Das ist sehr viel Größer als 65535.
Also musst Du den Vorteiler so einstellen dass damit ein Wert <65535
herauskommt.
Da bietet sich ein Vorteiler von 2048 an (oder was auch immer der PIC
hat). Damit kommst Du dann auf einen Zählerwert von 37519,.... Damit
hast Du dann den Vorteiler udn den Zähler bestimmt. Der Interrupt kommt
dann genau nach (2049*37519)/12 us = 6403242,67us
rgds
Du berechnest einfach den Prescaler bei einem Timerwert von 65536.
Dann nimmst Du den nächst höheren erlaubten Prescalerwert (vermutlich
128) und errechnest damit den passenden Timerwert.
Wow ich danke für die tolle Hilfe! Habe jetzt die möglichen
Kombinationen durchgerchnet.
Maximaler prescaler beim pic18 timer0 ist 256.
Also nochmal:
1/12Mhz = 8,33 *10^(-8) s
Der Timer0 brauch 8,33*10^(-8) s pro Zählschritt.
Ein Overflow soll nach 460,33mS kommen.
Also hab ich mir folgendes überlegt:
8,33*10^(-8)s Prescaler Zählhöhe = 460,33mS
460,33ms/(8,33*10^(-8) s) = 5526170,468
Prescaler*Zählhöhe= 5526170,468
5526170,468 / 256(prescaler) = 21586,60339 Zählhöhe
=> Scheidet aus, zu niedrig
5526170,468 /128 = 43173,20 Zählhöhe
=> Scheidet aus, zu niedrig
5526170,468 / 64 = 86346,41 Zählhöhe
=> Scheidet aus, zu hoch
5526170,468 / 65536 = 84,32 Prescaler
=> Scheidet aus, gibts nicht.
Gehe ich das einfach komplett falsch an oder wieso komme ich nicht
drauf?
Ich finde keinen passenden Prescaler
New D. schrieb:> Gehe ich das einfach komplett falsch an oder wieso komme ich nicht> drauf?> Ich finde keinen passenden Prescaler
Das kann natürlich sein, dass es sich mit keinem Prescaler ausgeht.
Der andere Wert, an dem du drehen kannst, dass sind die 65536. Dann darf
halt der Timer nicht durchlaufen, sondern muss bereits bei einem
Zählerstand vorher den Interrupt auslösen und wieder bei 0 anfangen.
Dieser ominöse Zählerstand kann logischerweise nur kleiner als 65535
sein. Also nimmst du einen Prescaler, bei dem du knapp über der Zielzeit
bist und rechnest zurück, wie weit der Timer bei diesem Prescaler zählen
darf, damit du die Zielzeit erhälst. Wenn der Timer nicht so weit zählt,
wird dieser 'Endwert' etwas schneller erreicht - die Zeit dafür sinkt
also ein wenig.
Aber mein Timer0 darf doch nur bis entweder 255 oder 65535 zählen. Also
kann ich doch gar nicht einen beliebigen Zählwert ausrechnen, denn der
löst den Interrupt doch nur bei entweder +255 oder + 65535 aus. ?
New D. schrieb:> Ein Overflow soll nach 460,33mS kommen.
Korrekt solltest Du sagen:
Ein Interrupt soll nach 460,33mms kommen, der Timer muss dazu noch nicht
am Ende sein. Er kann prinzipiell auch bereits bei der Hälfte oder jedem
anderen Wert einen Interrupt erzeugen oder Überrollen (auf 0
zurückgesetzt werden).
rgds
New D. schrieb:> 460,33ms/(8,33*10^(-8) s) = 5526170,468
Genau gesagt: 460330*12 = 5523960
6a66 schrieb:> 640,33ms / 0,0833us = 76.839.600
Da habe ich mich gründlich verrechnet.
So und jetzt suchts Du den Prescalerwert mit demm du auf einen Wert
kommst bei dem der Timer nach 640,33ms noch kleiner 0xffff ist.
rgds
New D. schrieb:> Aber mein Timer0 darf doch nur bis entweder 255 oder 65535 zählen. Also> kann ich doch gar nicht einen beliebigen Zählwert ausrechnen, denn der> löst den Interrupt doch nur bei entweder +255 oder + 65535 aus. ?
Nein, nein. :-) Mit einem gewissen Vorbehalt, denn ich kenne die PICs
nicht gut, kann man einen Interrupt bei einem beliebigen Zählerstand
auslösen lassen. Da ist nochmal Datenblattstudium angesagt,
Abgesehen dvon.
rechne nicht so viel rum. Du handelst dir da eine Menge Rundungsfehler
ein.
Wenn ich rechne:
1
12000000 * 0.46033 / 128 = 43155
dann lande ich bei einem Vorteiler von 128 dabei, dass ich den Timer bis
43155 laufen lassen möchte. Bei 12Mhz Timertakt.
Du hingegen kriegst mit deinen vielen Umrechnungen in Zeiten raus
1
5526170,468 /128 = 43173,20 Zählhöhe
zwischen 43173 und 43155 ist dann schon ein kleiner Unterschied.
(Ursache ist, dass 1/12 eben nicht 8,33 *10^(-8) s ist, sondern du da
ein paar Kommastellen unterschlagen hast. Mal angenommen die 12Mhz sind
absolut genau, dann würdest du bei 43173 eine Zeit von 460.512ms
erhalten und nicht 460.33ms. Abgesehen davon tippt sich 12000000 viel
leichter in den Taschenrechner als dieses ganze Potenzzeugs
1
12000000 / 128 / 43155 = 2.17irgendwas. Davon der Kehrwert = 0.46032 Sekunden)
Ich glaube hier ist ein Missverständnis.
Mit Timer2 kann man nach einem beliebigen Wert einen Interrupt auslösen,
aber nicht bei TIMER0. Da gibt es kein Compare Wert
New D. schrieb:> Ich glaube hier ist ein Missverständnis.> Mit Timer2 kann man nach einem beliebigen Wert einen Interrupt auslösen,> aber nicht bei TIMER0. Da gibt es kein Compare Wert
Dann hätte ich doch gerne mal den präzisen Aufgabentext und den Typ des
PICs gewusst.
Möglich ist es, aber dann hat entweder der Lehrer keine Ahnung oder der,
der dieses Bildchen gemacht hat oder irgendeiner lockt Euch in eine
kleine Falle.
Du kannst aber TMR0 setzen, sodass er weniger lange bis zum Overflow
braucht. Und das machst du jedes Mal wenn der Interrupt ausgelöst wird.
Somit lässt du ihn nur von (65535-x) bis 65535 laufen.
Ausserdem hast Du die ganze Zeit was einem maximalen Zählerstand von
2^16 erzählt. Wo kam denn diese Zahl her. (Abgesehen davon, dass sie
2^16 - 1 wäre).
@ Karl Heinz (kbuchegg) (Moderator)
>Wenn ich rechne:>12000000 * 0.46033 / 128 = 43155
Und ich behaupte mal wieder, dass kein zurechnungsfähiger Mensch
explizit einen Timerinterrupt alle 460,33ms haben will. "Bestenfalls"
ergibt sich so eine Takt aus ungünstigem Quarztakt und Teilern.
Falk B. schrieb:> @ Karl Heinz (kbuchegg) (Moderator)>>>Wenn ich rechne:>>>12000000 * 0.46033 / 128 = 43155>> Und ich behaupte mal wieder, dass kein zurechnungsfähiger Mensch> explizit einen Timerinterrupt alle 460,33ms haben will.
Ich denke, es handelt sich um eine Schulaufgabe
Falk B. schrieb:> @ Karl Heinz (kbuchegg) (Moderator)>>>Wenn ich rechne:>>>12000000 * 0.46033 / 128 = 43155>> Und ich behaupte mal wieder, dass kein zurechnungsfähiger Mensch> explizit ...
Guck mal in Wikipedia. Du wirst weder unter "Lehrer" was von
Zurechnungsfähigkeit noch unter "Zurechnungsfähigkeit" was von Lehrern
lesen. :-)
@ Karl Heinz (kbuchegg) (Moderator)
>> Und ich behaupte mal wieder, dass kein zurechnungsfähiger Mensch>> explizit einen Timerinterrupt alle 460,33ms haben will.>Ich denke, es handelt sich um eine Schulaufgabe
Nicht für das Leben, nein, für die Schule lernen wir . . .
foo schrieb:> Du kannst aber TMR0 setzen, sodass er weniger lange bis zum> Overflow> braucht. Und das machst du jedes Mal wenn der Interrupt ausgelöst wird.> Somit lässt du ihn nur von (65535-x) bis 65535 laufen.
Wie meinst du das?
New D. schrieb:> Wie meinst du das?
Du setzt am Anfang TMR0 auf (65535-x). Dann lässt du ihn laufen.
x Timerzyklen später wird es einen Overflow geben und dein Interrupt
wird ausgelöst. Im Handler setzt du TMR0 wieder auf (65535-x) und machst
dann den Rest (was auch immer alle 460,xx ms passieren soll).
Es dauert nun wieder x Timerzyklen bis zum nächsten Overflow... und so
weiter.
Wenn du eben auf Timer0 festgelegt bist und dieser kein Compare Register
hat, muss man sich das eben zusammenbasteln.
Das ist natürlich auch eine Möglichkeit. Allerdings nicht trivial, denn
die Interrupt-Frequenz ist nicht in Faktoren zerlegbar, die einem der
Prescaler entspricht. Dann wäre noch die Frage, ob das das durch die
Zyklen für die Befehle im Interrupt und das Neuladen des Timers etc.
irgendwie gerade hinkommt oder wie genau die 460,33ms sein sollen.
Aber das sollte ja im Aufgabentext stehen.
Klaus schrieb:> Das ist natürlich auch eine Möglichkeit. Allerdings nicht trivial,> denn> die Interrupt-Frequenz ist nicht in Faktoren zerlegbar, die einem der> Prescaler entspricht.
Korrekt. Demnach ist die Aufgabe streng genommen unlösbar. Es gibt einen
Prescaler, aber die Zahl der Takte bis zum nächsten Reset hat über 16
Bit. Man könnte zwar alle 460,33ms bestimmten Code ausführen (man zählt
im Handler auch die Zahl der Overflows mit) aber der Timer würde
Interrupts häufiger als alle 460,33ms feuern -> Aufgabe verfehlt.
> wie genau die 460,33ms sein sollen.>> Aber das sollte ja im Aufgabentext stehen.
Ich wage zu behaupten, dass es nicht drin steht. Zumindestens kenne ich
solche Aufgaben mit krummen Zahlen, die "rein zufällig" zu einem runden
Ergebnis führen, nicht anders. Ich würde in die Antwort mit
reinschreiben, dass es einen vernachlässigbar kleinen Fehler von 0.67
Mikrosekunden gibt, der aber unvermeidbar ist, weil kein kleinerer
Prescaler gewählt werden kann.
Irgendwie komisch. Normalerweise, d.h. bei "zurechnungsfähigen Lehrern"
(TM) hat das einen Grund, wenn eine Aufgabe nicht trivial zu lösen ist.
Didaktisch fängt man doch mit einfachen Aufgaben an und wenn die gelöst
werden können, lehrt man weitere Gesichtspunkte und fügt den Aufgaben
diese hinzu. Entweder, dass die einfachen Aufgaben genauer betrachtet
nicht exakt gelöst wurden oder die Vorgaben so gemacht wurden, dass die
einfachen Lösungen auch exakt waren.
Ich war dann doch mal fleissig und habe das in den Taschenrechner
eingetippt und komme darauf, dass selbst wenn der Timer 16 Bit hätte,
noch ein Fehler von rund 1us bleibt. Praktisch oft nicht relevant, aber
unsere Videobastler hier die mit einem AVR ein FBas-Signal erzeugen,
würden vielleicht die Hände über dem Kopf zusammenschlagen.
Die Frage stellt sich also an welchem Punkt im Unterricht diese Aufgabe
gestellt wurde. Wenn der TO nun so fragt, wie er es tat, hat er nicht
mal mit einfachen Fällen Erfahrung. Geschweige denn mit der Einbeziehung
der Zykluszeiten für das Timer-Reload etcpp.
Das ist mysteriös und lässt als plausible Vermutung zu, dass dem
Aufgabensteller die Zahl auf dem Klo eingefallen ist.
New D. schrieb:> Hallo,>> Ich brauch mal einen Gedankenanstoss,>> (Es muss Timer0 benutzt werden, so Aufgabenstellung.)> Undzwar soll alle 460,33ms ein Interrupt ausgelöst werden.
Die "besseren PICs" z.B.18F2450 haben 2 TMR0-Modes:
· 8Bit bzw. 16Bit umschaltbar im Register T0CON.
· Interrupt wird ausgelöst durch TMR0-overflow
· Der Prescaler ist auf max. 256 beschränkt.
Damit wäre das Problem so zu lösen:
fosc/4 = 48.000.000Hz : 4 = 12.000.000Hz (->Arbeitszyklen)
Interrupt-Intervall 460,33ms = 460330 Arbeitszyklen
TMR0 Zählbereich 0-2^16 = 0-65535 = 65536 clocks
Prescaler(1) = 460330 : 65536 = 8 (aufgerundet)
Prescaler(2) = 12.000.000 : 460330 = 27 (aufgerundet)
Prescaler = 27*8 = 216
nächster größerer verfügbarer Wert = 256
;----------------------------------------
12.000.000Hz : 256 = 46875 TMR0-clocks (passt in Zählbereich)
Preset TMR0 65536-46875 = 18661 = 48E5h
1. Timer0 Clock Source Select - fosc/4 aktivieren
2. TMR0-overflow Interrupt aktivieren (INTCON,TMR0IE=1)
3. Preset in der Interrupt-Service-Routine (ISR) ausführen.
zum Beispiel TMR0-Preset in MPLAB-Assembler:
movlw 0x48
movwf TMR0H ;H-Byte
movlw 0xE5
movwf TMR0L ;LByte
Ab sofort, wenn TMR0 überläuft, wird automatisch das Flag INTCON,T0IF
gesetzt und ein Interrupt ausgelöst. In der ISR wird TMR0 stets auf den
richtigen Presetwert gesetzt.
mfG Ottmar
Ottmar K. schrieb:> 12.000.000Hz : 256 = 46875 TMR0-clocks (passt in Zählbereich)
Yep, damit zählt er genau 1 Sekunde ... aber was ist mit den 460,33 mS ?
12MHz/256 * 460,33ms = 21577,969 also für den geringsten Fehler 21578.
Wenn der auch 128 als Prescaler haben sollte, nimmt man den und rechnet
ähnlich.
Wenn mans ganz genau haben will, rechnet man vorher noch die Takte
runter, die man braucht, um TMR0 neu zu schreiben, aber da müsste ein
PIC-Assemblerprofi ran.
foo schrieb:> Wenn mans ganz genau haben will, rechnet man vorher noch die Takte> runter, die man braucht, um TMR0 neu zu schreiben, aber da müsste ein> PIC-Assemblerprofi ran.
Wenn ich die Aufgabe wörtlich nehme, soll der Interrupt (und damit die
ISR) alle 460,33 mS ausgelöst werden - egal, wie lange die ISR etc
dauert. Aufgabe ist das exakte Intervall des Auslösers, nicht die
Abarbeitung ...
Also einmal einstellen und dann bis St. Nimmerlein laufen lassen.
Das geht bei dem krummen Wert mit dem angegebenen Takt nicht genau.
Entweder man rundet leicht (wie Karl-Heinz) oder man passt den Takt an.
Falls nun der Timer keinen Autoreload- oder Clear_on_Compare-Mode hat,
kann man den Timer einfach in SW neu setzen.
Z.B. im Überlaufinterrupt setzt man ihn auf -43156.
Dazu hat man den Prescaler lang Zeit, d.h. 128 Zyklen.
Ist also bequem in C zu schaffen, Assembler ist unnötig.
Dieter F. schrieb:> Wenn ich die Aufgabe wörtlich nehme, soll der Interrupt (und damit die> ISR) alle 460,33 mS ausgelöst werden - egal, wie lange die ISR etc> dauert. Aufgabe ist das exakte Intervall des Auslösers, nicht die> Abarbeitung ...
Das kriegste schon exakt hin, wenn TMR0 neu setzen das erste ist, was du
in der ISR machst. Wie lange der Rest der ISR braucht, ist dann egal -
der Timer zählt währenddessen schonmal weiter
Man muss dazu sagen, dass ein anderer Interrupt aktiv sein könnte,
während der Overflow-Interrupt kommt, d.h. TMR0 wird verspätet
überschrieben - damit dauerts dann aber auch länger bis zum nächsten
Overflow. Dem kann man vorbeugen, indem man den Wert zu TMR0 dazuaddiert
statt ihn zu ersetzen.
> Also einmal einstellen und dann bis St. Nimmerlein laufen lassen.
Mir wäre das auch deutlich lieber, aber Timer0 hat nun mal keinen
Compare Interrupt, wenn ich das richtig sehe. Die anderen Timer schon.
Aber die sollen laut Aufgabe eben nicht verwendet werden.
Ich würde wetten, dass das deshalb Vorgabe ist, damit man eben diese
(oder eine andere) Bastellösung verwenden muss. Mit Compare Register
wäre es ja nun wirklich zu einfach.
P.S.:
Hab grad das Bildchen gesehen, der Timer ist ja nur 8 Bit.
Ist aber kein Beinbruch, dann zerlegen wir einfach weiter:
1
5523960/256+0,5=21578
2
21578=84*256+74
D.h. wir nehmen noch ne Variable, die bis 84 zählt und nur dann wird der
Timer auf -74 geladen, die Variable auf 0 gesetzt und das 460,33ms Ding
gemacht.
Dieter F. schrieb:> Ottmar K. schrieb:>> 12.000.000Hz : 256 = 46875 TMR0-clocks (passt in Zählbereich)>> Yep, damit zählt er genau 1 Sekunde ... aber was ist mit den 460,33 mS ?
Habe gerade noch mal in den Thread reingeschaut:
OK- hab mich wohl beim Schreiben selbst überholt :-) und dabei den
wichtigsten Punkt versäumt:
Da so der Preset für 1 Sekunde ISR-Intervall feststeht, braucht nur noch
durch den Kehrwert der Intervallzeit in Sekunden (ergibt Hz), geteilt zu
werden und man erhält den Presetwert für 0,46033s ISR-Intervall so:
46875 clocks / (1 / 0,46033s) = 21577 clocks (da abgerundet!)
Gegenprobe: (1/0.46033s) 256 21577 = 1199461Hz
Die fehlenden 539 clocks müssten dann durch eine genau bemessene
Schleife
in der ISR hinzugefügt werden (inklusive des dort vorzunehmenden Setzen
des Presetwertes)
Fazit:
Als Formel ergibt sich die Anzahl der für das ISR-Intervall
erforderlichen TMR0-Clocks so:
Arbeitszyklen / (1/t) / Prescaler = TMR0-Clocks
fosc/4 t(s) 2....256
Der Presetwert für TMR0 (16Bit) = 2^16 - TMR0-Clocks
im vorliegenden Falle wäre Preset dann:
65536 - 21577 = 43959 = ABB7h
@Dieter F- Danke für den Hinweis auf meine Leichtfertigkeit!
mfG Ottmar
P.S.: Selbst vor die Aufgabe gestellt, würde auch ich den
Compare-Interrupt der vorgenannten aufwendigeren Lösung vorziehen.
Hallo,
Ich danke euch allen, die Lösung war, wie verschiedene schon angedeutet
hatten, dem Timer0 in der Interrupt Service Routine einen festen
Startwert zu übergeben.
Gruss
New D. schrieb:> Ich danke euch allen, die Lösung war, wie verschiedene schon angedeutet> hatten, dem Timer0 in der Interrupt Service Routine einen festen> Startwert zu übergeben.
Welcher Startwert war es denn? Und kommt man damit genau auf die
geforderten 460,33 mS?
New D. schrieb:> War ein Startwert von 43870 ;)
Das ist nicht richtig.
Du hast ja schon wieder vorzeitig duchdividiert und dabei Kommastellen
verloren!
Dein benutzter Vorteiler war offenbar 256
1
12000000 / 256 = 46875
so weit würde der Timer in 1 Sekunde zählen.
Wir brauchen aber nur 0.46033s. Daher
1
46875 * 0.46033 = 21577
Der Timer muss also 21577 Zählschritte machen, danach sind 0.46033
Sekunden vergangen.
Damit der Timer 21577 Zählschritte macht, bis er bei 65536 angelangt ist
(und damit den Overflow auslöst), muss er bei
1
65536 - 21577 = 43959
gestartet werden.
Vergiss endlich dieses Rumrechnen mit 'wie lange dauert ein Zählzyklus'.
Edit:
Die 21577 könnte man auch als 21578 ansehen, dann das Rechenergebnis ist
21577.9.
Aber auch das rettet deine Abweichung vom Ergebnis nicht mehr. 43870 ist
weit von 43959 entfernt. Da geht es nicht mehr um einen Fehler +- 1