Anfängerfrage mit Timern

Gast #321619
Lesenswert?

Hallo! Stehe mit Timern noch ein wenig auf Kriegsfuß. Angenommen, mein
Takt ist 3686000 Hz und ich benutze einen Prescaler von 64.

Daraus folgt: Dieser Takt wäre dann nur noch 3686000/64 = 57593,75 Hz

Aber wenn ich z.B. jede halbe Sekunde, also mit 2 Hz eine Aktion
auslösen will, wie mach ich das? Dachte an 57593.75/(57593.75/2)=2

Oder ist das so falsch wie ich da herangehe?
Gast #321621
Lesenswert?

Aber im 8 Bit-Modus muss das ja auch gehen? CTC usw. gibts ja nur für
16-Bit timer laut Datenblatt.

Habe nun mal TIMSK mit TOIE0 genommen. Aber wo schreibe ich den Wert
dann überhaupt rein? Das fehlt und ich hab keine Ahnung wo das hin
soll?

Und wie ist Überlauf des Datenregisters gemeint? Wenn er über 255
kommt? oder muss ich ihm meinen Wert übergeben? Stehe da momentan echt
auf dem schlauch, verzeihung :(.

Hier mal der ganze code
1
int main(void)
2
{
3

4
DDRD = 0xFF;             // kompletter PORTD als Ausgang
5
PORTD = 0xFF;  
6

7
//Timer
8

9
TCCR0|= (1<<CS01)|(1<<CS00); //prescaler 64
10
sei();    //Setzt globales Interupt
11
TIMSK = (1<<TOIE0);
12

13

14
for(;;) {
15
  
16

17
        SIGNAL(SIG_OVERFLOW0) //Interrupt auslösen
18
{
19
        PORTD &= ~((1<<PD0));
20
}
21
  
22
   
23
     
24
}
25
  
26
  }
Gast #321622
Lesenswert?

So, hab jetzt doch den 16-Bit-Counter genommen, da gibts einfach mehr
funktionen (auch wenn das doch mit dem 8-Bitter auch gehen müsste)?

Wo ist jetzt noch der Fehler (s.u.), eigentlich müsste doch nach ca.
1,1 Sekunden der Port auf Low gezogen werden? Laut Tutorial passt das
so zusammen, wenn ich das so richtig verstanden habe:

Der Timer der mit CPU_CLK/64 läuft, und damit den TCNT1L bis 65535
hochzählt. Wenn er diesen Wert erreicht hat, löst TIMSK = (1<<TOIE1)
nen Timer1 Overflow Interrupt aus, der dann von der
ISR(TIMER1_OVF_vect) empfangen wird und dann ein interrupt event
ausgelöst wird (z.B. Port schalten etc).
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3

4

5
int main(void)
6
{
7

8
DDRD = 0xFF;             // kompletter PORTD als Ausgang
9
PORTD = 0xFF;  
10

11
  
12
  
13
//Timer
14

15
TCCR1B = (1<<CS11)|(1<<CS10); //prescaler64
16

17
TCNT1L; //16-Bit Aufwärtszähler
18

19
sei(); //Setzt globales Interupt
20

21
TIMSK = (1<<TOIE1); //WENN UEBRLAUF , dann interrupt
22
  
23

24

25

26

27

28

29

30
for(;;) 
31
  {
32

33

34

35
  ISR(TIMER1_OVF_vect) 
36
  
37
    {      
38
    PORTD &= ~((1<<PD0));
39
    }
40
     
41
  }
42
  
43
}
Gast #321624
Lesenswert?

Welcher Takt ist 3686000 Hz? Quarz???

Grundsätzlich geht das etwa so:

Timer Reload Wert = (Taktfrequenz / Prescaler) * Überlaufzeit in
Sekunden

Konkret für 1/2 Sekunde:

Timer Reload Wert = (3686000 / 64) * 0,5

Timer Reload Wert = 57593,75 * 0,5

Timer Reload Wert = 28796,875

runden:

Timer Reload Wert = 28797

Gruß

Dietmar
Gast #321625
Lesenswert?

Controller ist ein AT90s85815, der Quarz läuft mit 3686000 (SK500).

Okay, nun weiss ich wie man das macht. Aber wo der Fehler oben im
zweiten Code steckt, da rätsele ich immer noch herum (da hab ich
wiegesagt ohne Vergleichswert gearbeitet, der EInfachheit halber nur
einen Überlauf.

Danke

Gruß,

RZ

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