Timerfrequenz Tiny2313

Gast #2703837
Lesenswert?

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 #2703861
Lesenswert?

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 #2703951
Lesenswert?

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?
#2704022
Lesenswert?

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 #2704024
Lesenswert?

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 #2704041
Lesenswert?

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 #2704057
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren