Forum: Mikrocontroller und Digitale Elektronik Anfängerfrage mit Timern


von RambusZambus (Gast)


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?

von Rahul (Gast)


Lesenswert?

0,5s*57596,75Hz ist der Wert, bei dem der Timer ein Interrupts uaslösen
soll. Entweder 65536-diesem Wert für ein Overflow-Interrupt oder diesen
Wert in OCR im CTC-Modus schreiben.

von RambusZambus (Gast)


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
  }

von RambusZambus (Gast)


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
}

von Dietmar (Gast)


Lesenswert?

Welcher der 10000 am Markt befindlichen Controller spielt denn hier?

Das ganze ist doch sehr hardwareabhängig, um einen Zusammenhang zu
bekommen, oder?

Gruß

Dietmar

von Dietmar (Gast)


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

von RambusZambus (Gast)


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

von Karl H. (kbuchegg)


Lesenswert?

> Aber wo der Fehler oben im
> zweiten Code steckt, da rätsele ich immer noch herum

Das faengt schon mal damit an, dass man in C innerhalb
einer Funktion keine weitere Funktion definieren kann.
Genau das versuchst Du aber mit Deinen ISR Funktionen.

von RambusZambus (Gast)


Lesenswert?

Aah, danke das wars. Jetzt steht die ISR außerhalb der main-Funktion und
erhöht eine Zählvariable. Nun klappt es superb =).

Danke!

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.