Forum: Mikrocontroller und Digitale Elektronik Frage zu Takt und Timer-Prescaler ATTiny25


von Timerfrage (Gast)


Lesenswert?

Hi, ich habe eine Frage zu Timer-Prescaler.

Bei dem ATTiny25 ist der CLKDIV8 standardmäßig aktiviert.

Wenn ich den deaktiviere und F_CPU=8000000UL setze, läuft der Controller 
mit 8 MHz.

Wenn ich ihn aktiviert lassen und F_CPU auf 1000000UL setze, läuft der 
dann mit 1 MHz oder mit 8 MHz?

Das wäre wichtig für die Auswahl meines Prescalers.

Sorry wenn die Anfängerfrage ein wenig dumm erscheint.

von Andreas B. (bitverdreher)


Lesenswert?

Hi,
F_CPU informiert den Compiler lediglich, daß Du den MC auf die 
angegebene Frequenz gestellt hast.

Gruß
Andreas

von Einer K. (Gast)


Lesenswert?

Timerfrage schrieb:
> Das wäre wichtig für die Auswahl meines Prescalers.
Wieso...?
Ich glaube, da unterliegst du einem Irrtum.


Wie CLKDIV8 steht, kann dir doch völlig wurscht egal sein, wenn du den 
Prescaler selber setzt.

F_CPU solltest du dann allerdings auf den korrekten Wert einstellen.

von Timerfrage (Gast)


Lesenswert?

Ok Danke.
Ich hab den CLKDIV8 deaktiviert und F_CPU auf 8 MHz gesetzt. Zum Testen 
hab ich jetzt ein ATTiny841 genommen, um mir per UART die Timerwerte 
ausgeben zu lassen. Ich bin ein wenig verwirrt weil:

Ich speise an den INT0 ein Rechtecksignal mit 10 HZ und reagiere auf die 
fallende Flanke. ich messe am INT0 von fallender Flanke zur fallenden 
Flanke. Die Zeit muss 100ms betragen. mit einem Prescaler von 1024, 
beträgt meine Timerfrequenz noch 7812,5 kHz, demnach müsste der Timer 
doch alle 128us eins höher zählen. Bei 100ms also 781 Inkremente. Der 
Timerwert solle dann doch bei 16 sein und der Overflow bei 3. Ich 
bekomme allerdings einen Timerwert von 213 und einen Overflow von 1.

Was genau habe ich nicht verstanden?

von Thomas E. (thomase)


Lesenswert?

Mach das nicht so kompliziert.

Lass eine LED an einem beliebigen Port mit einem Delay, ja mit Delay, 
von einer Sekunde blinken. Dann erkennt jeder mit blossem Auge, ob die 
LED mit 125ms, 1s oder 8s blinkt. Je nachdem, ob du alles richtig 
eingestellt hast oder ein Irrtum in der einen anderen Richtung vorliegt.

von c-hater (Gast)


Lesenswert?

Timerfrage schrieb:

> Wenn ich den deaktiviere und F_CPU=8000000UL setze, läuft der Controller
> mit 8 MHz.

In etwa. Und es ist unwichtig, was du in F_CPU angibst, der Controller 
interessiert sich für diesen Scheiss exakt garnicht, er erfährt davon 
nämlich auch rein garnix.

Allerdings ist es für deinen Compiler relativ sinnvoll, dass du den 
korrekten Takt in F-CPU angibst, denn viele der von dir raubkopierten 
C-Fragmente verlassen sich darauf, dass diese Angabe der Realität 
entspricht.

Blöd nur, wenn du zur Laufzeit den Takt wechselt, was beim Tiny841 (und 
nicht nur bei dem) ja ziemlich problemlos möglich und garnicht so selten 
auch sinnvoll ist. Dann fällt diese ganze C-Gülle einfach mal nur voll 
auf die Nase, denn dann gibt es keinen programmweit gültigen Wert für 
F_CPU mehr...

> Ich speise an den INT0 ein Rechtecksignal mit 10 HZ und reagiere auf die
> fallende Flanke. ich messe am INT0 von fallender Flanke zur fallenden
> Flanke. Die Zeit muss 100ms betragen. mit einem Prescaler von 1024,
> beträgt meine Timerfrequenz noch 7812,5 kHz, demnach müsste der Timer
> doch alle 128us eins höher zählen.

Jepp. Genauso ist das.

> Bei 100ms also 781 Inkremente.

Fast. Genau 781,25. Er wird also mal 781 und mal 782 Incremente zählen. 
Im Mittel werden diese Fälle im Verhältnis 4:1 auftreten.

> Der
> Timerwert solle dann doch bei 16 sein und der Overflow bei 3.

Wie kommst du denn darauf? Wenn man mal einen 8Bit-Timer annimmt (und 
die impliziert, dass der bei 0 startet) würde er 3 mal überlaufen (das 
stimmt) und der Zählerstand sollte 13 oder 14 sein (nicht 16).

> Ich
> bekomme allerdings einen Timerwert von 213 und einen Overflow von 1.

Dann stimmt sicher irgendwas in deiner Software nicht. Der beobachtete 
Wert weisst allerdings nicht direkt auf einen typischen Fehler hin. 
Deswegen kann man in Ermangelung von Code nichtmal raten, was du falsch 
gemacht hast. Da musst du schon deinen Code posten.

von Timerfrage (Gast)


Lesenswert?

Thomas E. schrieb:
> Mach das nicht so kompliziert.
>
> Lass eine LED an einem beliebigen Port mit einem Delay, ja mit Delay,
> von einer Sekunde blinken. Dann erkennt jeder mit blossem Auge, ob die
> LED mit 125ms, 1s oder 8s blinkt. Je nachdem, ob du alles richtig
> eingestellt hast oder ein Irrtum in der einen anderen Richtung vorliegt.

Das hilft mir nicht wirklich weiter. Bei 1000ms Delay blinkt die LED im 
Sekundentakt, soweit alles gut.

c-hater schrieb:
>> Bei 100ms also 781 Inkremente.
>
> Fast. Genau 781,25. Er wird also mal 781 und mal 782 Incremente zählen.
> Im Mittel werden diese Fälle im Verhältnis 4:1 auftreten.
>
>> Der
>> Timerwert solle dann doch bei 16 sein und der Overflow bei 3.
>
> Wie kommst du denn darauf? Wenn man mal einen 8Bit-Timer annimmt (und
> die impliziert, dass der bei 0 startet) würde er 3 mal überlaufen (das
> stimmt) und der Zählerstand sollte 13 oder 14 sein (nicht 16).
Stimmt natürlich ;)


Hier der Code:
1
#define F_CPU 8000000UL
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include <avr/interrupt.h>
5
6
#define BAUD 9600UL
7
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
8
9
volatile uint8_t iOverflow = 0;
10
volatile uint8_t active = 0;
11
12
void UART_init(void)
13
{
14
  UBRR0 = UBRR_VAL;
15
16
  UCSR0C = (1<<UCSZ00) | (1<<UCSZ01);
17
  UCSR0B |= (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
18
  REMAP |= (1 << U0MAP);
19
}
20
21
void Start_Timer()
22
{
23
  //TCCR0B =  (1<<CS02); // Prescaler 256
24
  TCCR0B |= (1<< CS00) | (1<<CS02); // Prescaler 1024
25
  TIMSK0 |= (1<<TOIE0);
26
}
27
28
ISR(INT0_vect)
29
{
30
  if (active == 0)
31
  {
32
    Start_Timer();
33
    active = 1;
34
  }
35
36
  UDR0 = TCNT0;
37
  UDR0 = iOverflow;
38
  iOverflow = 0;
39
  TCNT0 = 0;
40
}
41
42
ISR (TIMER0_OVF_vect)
43
{
44
  iOverflow++;
45
}
46
47
int main(void)
48
{
49
  DDRA =  0b00100000;
50
  PORTA = 0b00000000;
51
52
  UART_init();
53
  sei();
54
55
  MCUCR |= (1<<ISC01);
56
  GIMSK |= (1<<INT0);  
57
58
  while(1)
59
  {  
60
    //PORTA |= (1<<PINA5);
61
    //_delay_ms(1000);
62
    //PORTA &= ~(1<<PINA5);
63
    //_delay_ms(1000);
64
  }
65
}

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
Noch kein Account? Hier anmelden.