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?
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.
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 | }
|
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 | }
|
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
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
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
> 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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.