Timerfrequenz Tiny2313

Gast #2703837
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) { }
}
Gast
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
Gast
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?
Gast
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?
Gast
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?
Gast
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?
Gast
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 ;)
Gast
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...
Gast
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.