Resultierend aus einer Idee, um die ATtinys mit interner PLL auf 20 MHz Taktfrequenz zu bringen, hier ein kleines Stückchen Assembler-Code. Als Referenz wird die werkskalibrierte Frequenz des RC-Oszillators benutzt, gemessen wird mit dem Watchdog-Timer. Da relativ zum Basistakt kalibriert wird, ist die Absolutgenauigkeit des Watchdog-Timers nicht relevant (ich bin davon ausgegangen, daß die Kurzzeitstabilität ausreichend ist). Die Genauigkeit der Ziel-Taktfrequenz wird natürlich nicht besser sein als die ab Werk kalibrierte Frequenz, also bitte nicht zuviel erwarten. Das Verfahren ist nicht auf ATtinys mit PLL beschränkt, sondern sollte eigentlich auf allen AVR-Controllern mit OSCCAL-Register und Watchdog-Interrupt funktionieren.
Horst M. schrieb: > Da relativ zum Basistakt > kalibriert wird, ist die Absolutgenauigkeit des Watchdog-Timers nicht > relevant Ja, und die Kinder bringen die Störche. > Die Genauigkeit der Ziel-Taktfrequenz wird natürlich nicht besser sein > als die ab Werk kalibrierte Frequenz, also bitte nicht zuviel erwarten. Sie wird bei statistischer Betrachtung mit hinreichende Sample-Basis im Mittel natürlich sogar weit schlechter sein. Man braucht sich nichtmal den Code anzuschauen, um das heraus zu bekommen, sondern nur deine Beschreibung des Verfahrens zu lesen und die Genauigkeit des Watchdog-Timers nachzuschlagen... Mein Gott, hast du niemals die Grundweisheit gelernt: Messen heisst Vergleichen? Du kannst nix ohne Referenz kalibrieren. Und du kannst nix genauer kalibrieren als die Referenz ist. Ob dir das nun gefällt oder nicht: die böse Physik unseres Universums gibt das als unabänderliches Gesetz vor. Wenn du nachweislich einen Weg darum herum gefunden hättest, wärst du der einsame Kandidat für den nächsten Nobelpreis. Du hast wahrscheinlich überhaupt kein Vorstellng davon, was das alles zum Rutschen bringen würde... Aber: Du wirst keinen Nobelpreis ernten und die Physik wird sich weiter mit der Auflösung der gravierenden Widersprüche beschäftigen, die sie derzeit hat. Da sind aber nur zwei, jweisl sehr gut abgesicherte Säulen der Erkenntnis miteinander im Widerspruch. Dein Ding würde aber beide komplett aushebeln...
c-hater schrieb: > Und du kannst nix > genauer kalibrieren als die Referenz ist. und genau das hat er ja geschrieben: Horst M. schrieb: > Die Genauigkeit der Ziel-Taktfrequenz wird natürlich nicht besser sein > als die ab Werk kalibrierte Frequenz, also entspann dich mal. Wenn Du wirklich einen Fehler entdeckst dann schreib das in in ein paar Zeilen hin anstatt dich seitenweise aufzuspielen
> .org WDTaddr > pop r0 ;remove the interrupt return address from stack > pop r0 > reti ;return to calling point of subroutine "measure" Was zur Hölle? Warum funktioniert das überhaupt?
org schrieb: >> .org WDTaddr >> pop r0 ;remove the interrupt return address from stack >> pop r0 >> reti ;return to calling point of subroutine "measure" > > > Was zur Hölle? Warum funktioniert das überhaupt? Weil's folgendermaßen läuft:
1 | ... |
2 | rcall measure |
3 | ;hier soll's nach dem Watchdog-Interrupt weitergehen |
4 | ... |
5 | |
6 | measure: |
7 | clr r24 |
8 | clr r25 |
9 | wdr |
10 | delay: ldi r18,LOW(int(bclock*16)) |
11 | delay1: dec r18 |
12 | brne delay1 |
13 | adiw r25:r24,1 |
14 | rjmp delay |
Die "measure"-Subroutine ist im Prinzip erstmal eine Endlosschleife, aus der es regulär kein Entkommen gibt. Der Watchdog-Timer ist auf 2048 Watchdog-Oszillator-Takte eingestellt und wird unmittelbar, bevor die Schleife losläuft, zurückgesetzt. Wenn der Watchdog-Interrupt zuschlägt, wird die Return-Adresse auf den Stack gelegt. Ein Rückkehr aus dem Watchdog-Interrupt in die Endlosschleife macht natürlich keinen Sinn, deshalb wird diese Return-Adresse mit zweimal POP verworfen und stattdessen die zuvor gespeicherte Return-Adresse des "RCALL measure"-Aufrufs verwendet. Hier wird auch das Meßverfahren erkennbar. Zunächst wird mit dem originalen 16 MHz-Controller-Takt (werkskalibrierter RC-Oszillator, PLL ein) gemessen. Nach dem Watchdog-Interrupt wird R25:R24 irgendeinen Wert enthalten, die absolute Zahl ist dabei nicht entscheidend, deswegen ist die genaue Frequenz des Watchdog-Oszillators nicht relevant (wie erwähnt gehe ich davon aus, daß die Stabilität der Watchdog-Frequenz für die paar hundert Millisekunden der Gesamtlaufzeit des Progrämmchens ausreichend ist). Mittels des soeben gemessenen Referenzwerts wird der Zielwert errechnet (eine simple Multiplikation mit dem Verhältnis Zielfrequenz/Originalfrequenz; um von 16 MHz auf 20 MHz zu kommen, also mit 1.25). Über sukzessive Approximation wird dann der Controller-Takt so eingestellt, daß der Messwert so nah wie möglich an dem errechneten Zielwert zu liegen kommt - fertig.
Horst M. schrieb: > Die "measure"-Subroutine ist im Prinzip erstmal eine Endlosschleife, aus > der es regulär kein Entkommen gibt. > Der Watchdog-Timer ist auf 2048 Watchdog-Oszillator-Takte eingestellt > und wird unmittelbar, bevor die Schleife losläuft, zurückgesetzt. > Wenn der Watchdog-Interrupt zuschlägt, wird die Return-Adresse auf den > Stack gelegt. Ein Rückkehr aus dem Watchdog-Interrupt in die > Endlosschleife macht natürlich keinen Sinn, deshalb wird diese > Return-Adresse mit zweimal POP verworfen und stattdessen die zuvor > gespeicherte Return-Adresse des "RCALL measure"-Aufrufs verwendet. Ach du meine Güte... Ja, funktionieren tut das wohl. Aber das wars auch schon. > Mittels des soeben gemessenen Referenzwerts wird der Zielwert errechnet > (eine simple Multiplikation mit dem Verhältnis > Zielfrequenz/Originalfrequenz; um von 16 MHz auf 20 MHz zu kommen, also > mit 1.25). Über sukzessive Approximation wird dann der Controller-Takt > so eingestellt, daß der Messwert so nah wie möglich an dem errechneten > Zielwert zu liegen kommt - fertig. Und warum nutzt du überhaupt den WDT? Warum multiplizierst du den per Werkseinstellung kalibrierten OSCAL-Wert nicht einfach mit 1.25 (oder was auch immer) und fertig?
org schrieb: > Und warum nutzt du überhaupt den WDT? Warum multiplizierst du den per > Werkseinstellung kalibrierten OSCAL-Wert nicht einfach mit 1.25 (oder > was auch immer) und fertig? Weil die RC-Oszillator-Frequenz nichtlinear vom OSCCAL-Wert abhängt (Figure 22-42. auf Seite 194 http://www.atmel.com/images/atmel-2586-avr-8-bit-microcontroller-attiny25-attiny45-attiny85_datasheet.pdf). Und letztlich ist die Abweichung zwischen "OSCCAL einfach mit einem Wert multipliziert" und der vorgestellten Methode womöglich entscheidend, ob ein UART noch läuft oder nicht.
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.