Hi, ich habe eine Schaltung mit ATtiny2313 Controller, die mit einem Takt von 50Hz eine Berechnung anstellen soll. Ich verwende einen 3,2768MHz Quarz (Grundton) mit 2 27pF Kondensatoren gegen Masse, Fusebits sind auf "external crystal 3-8MHz" gesetzt. System Clock Prescaler ist 256, der Timer verwendet wiederum einen Vorteiler von 256 und Vergleichswert 0, was meiner Meinung nach alle 20ms einen Interrupt auslösen sollte... Meine Testschleife gibt einen 1ms Low-Impuls im Timer-Interrupt aus, Ergebnis ist eine Frequenz von sehr konstanten 31Hz... Ich komme rechnerisch einfach nicht darauf. die delayms ist auch alles andere, als genau. Jemand eine Idee? Hier der C Codeauszug: #define F_CPU 3276800 #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> SIGNAL (SIG_OUTPUT_COMPARE0A) { PORTD |= (1<<PD5); // Pin D5 low delayms(1); PORTD &= ~(1<<PD5); // Pin D5 high } int main (void) { CLKPR = (1<<CLKPS3); // system clock prescaler 256 (Table 12) [...] TCCR0A = (1<<WGM01); // CTC Mode (Table 40) TCCR0B = (1<<CS02); // Prescaler 256 (Table 41) TCNT0 = 0; OCR0A = 0; // OCR0A: 3276800Hz/256/256 = 50Hz TIMSK = (1<<OCIE0A); // Timer Output Compare Match A Interrupt sei(); // activate interrupts while (1) { } }
Hi
> CLKPR = (1<<CLKPS3); // system clock prescaler 256 (Table 12
Damit schaltest du aber den Prescaler nicht um. Dazu muss erst
CLKPR = (1<<CLKPCE);
geschrieben werden. Lies dir das Timing im Datenblatt durch.
MfG Spess
OK, danke erstmal. Habe die Zeile nun durch folgendes ersetzt: CLKPR = 0x80; // CLKPCE = 1 CLKPR = 0x08; // CLKPS3 = 1 Ergebnis ist ein Takt von etwa 1Hz... Klar, ich könnte den Prescaler per Fusebit auf 8 setzen und den Vergleichswert des Counters auf 31 erhöhen, was ebenfalls den gewünschten Effekt haben sollte und mir ggf. schnellere Bearbeitung der Main-Routine ermöglicht (macht ich vielleicht auch...), aber wieso funktioniert das so nicht?
Ach ja, mir ist noch aufgefallen, dass 27pf über dem empfohlenen Wert von 12-22 liegen. Sollte ich mal austauschen, aber kann das den Takt so weit runterziehen?
Ach ja, mir ist noch aufgefallen, dass 27pf Kondensatoren am Quarz über dem empfohlenen Wert von 12-22 liegen. Sollte ich mal austauschen, aber kann das den Takt so weit runterziehen?
Die Kondensatoren beim Quarz dienen normalerweise dazu, den Quarz anschwingen zu lassen. Die haben mit der Frequenz die da raus kommt nichts zu tun. (Es sei denn, du willst irgendwelche Oberwellen herausfiltern oder so..)
Gut, dann habe ich das schonmal richtig verstanden. Bleibt die Frage, warum ich mit Standard-Vorteiler 8 auf 31Hz, mit eingestellten 256 auf 1Hz komme, wo ist mein Denkfehler in der Rechnung?
Teiler ist 8 --> Frequenz ist 32Hz Teiler ist 256 --> Frequenz ist 1Hz Die beiden Seiten dieser "Gleichung" sollten sich antiproportional zueinander verhalten. Sprich, wenn ich den Teiler z.B. mit dem Faktor 32 multipliziere, muss ich die Frequenz durch diesen Faktor dividieren (was dazu führt, dass es kein Faktor mehr ist, spielt aber hier keine Rolle). Wie der Zufall es will, passt der Faktor 32 ganz gut zu den Werten, die du angegeben hast. Teiler * 32 --> Frequenz / 32 Bis jetzt passt irgendwie alles, oder irre ich mich auch?
OK, neuer Versuch: CLKPR = 0x80; // CLKPCE = 1 CLKPR = 0x00; // Prescaler 0 und beim Timer OCR0A = 255; Ergebnis: 50Hz ! Immerhin weiß ich jetzt, dass ich den Vorteiler wirklich verstellt habe und meine Rechnung nicht so falsch sein kann ;)
speedy schrieb: > CLKPR = 0x80; // CLKPCE = 1 > CLKPR = 0x00; // Prescaler 0 --> Wird hiermit die erste Zeile nicht wieder überschrieben??
Zitat aus dem Datenblatt: > The CLKPCE bit must be written to logic one to enable change of the CLKPS > bits. The CLKPCE bit is only updated when the other bits in CLKPR are > simultaneously written to zero. CLKPCE is cleared by hardware four cycles > after it is written or when CLKPS bits are written. Rewriting the CLKPCE > bit within this time-out period does neither extend the time-out period, > nor clear the CLKPCE bit. Heißt nach meinem Verständnis, CLKPCE muss einzeln geschrieben werden und innerhalb von 4 Zyklen müssen die CLKPS Bits gesetzt werden, was CLKPCE automatisch zurücknimmt. Eine Änderung von CLKPCE hat solange keine Auswirkung, also dürfte dessen Inhalt im zweiten Schreibzyklus ja egal sein. @Sven Deine Rechnung leuchtet ein und 32Hz kommen auch hin (sollte dem Multimeter weniger glauben und immer gleich das Scope nehmen). Nur wie komme ich von 3276800Hz auf 32Hz, wenn ich nur 256 und 8 zur Verfügung habe? Jetzt habe ich /1 (System Vorteiler), /256 (Timer Vorteiler), /256 (Vergleichswert Counter). Umgekehrt scheint es ja nicht so zu funktionieren, frage mich halt, wieso...
Hi >speedy schrieb: >> CLKPR = 0x80; // CLKPCE = 1 >> CLKPR = 0x00; // Prescaler 0 --> Wird hiermit die erste Zeile nicht >wieder überschrieben?? Um den Vorteiler umzustellen muss erst mit CLKPE das Umstellen erlaubt werden. Innerhalb von, ich glaube, 4 Takten müssen dann die CLKPS-Bits gesetzt werden (ohne CLKPE). MfG Spess
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.