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 ;)
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