Forum: Mikrocontroller und Digitale Elektronik Atmega7 Timer0 löst keinen Interrupt aus


von Ransap (Gast)


Lesenswert?

Guten tag, ich versuche gerade den Timer0 so zu programmieren, das er 
immer im 100uS Takt auslöst. Ich habe einen Quarz von 4Mhz. Mit dem 
Avr-Timer-calculator habe ich die bei einen 8Bit Timer den Reloadwert 56 
rausbekommen.
Aber der Timer wird nicht ausgelöst.

Hier mein Code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
ISR(TIMER0_OVF_vect)
5
{
6
  PORTB ^= (1<<PB1);
7
}
8
9
int main(void)
10
{
11
  PORTB |= (1<<PB1);
12
  TCCR0 |= (1<<CS01); //Prescaler 8,
13
  TIMSK |= (1<<TOIE0); //Interrupt Enable
14
  TCNT0 = 0;
15
  sei();
16
    while(1)
17
    {
18
    }
19
}

Ich komm irgendwie nicht weiter, wie ich da jetzt den Reloadwert von 56 
eintragen soll.

von Hubert G. (hubertg)


Lesenswert?

Woher weisst du das die ISR nicht ausgelöst wird?

von g457 (Gast)


Lesenswert?

> das er immer im 100uS Takt auslöst

Dafür nimmst Du einfacher den Timer1 oder Timer2, die haben CTC.

> Aber der Timer wird nicht ausgelöst.

Woher weisst Du das? Lass mich raten: Die nicht genannte LED blinkt 
nicht. Wenn ich den Code nicht falsch überflogen hab wird sie das auch 
nicht - Du toggelst nur den Pullup-Widerstand.

> Ich komm irgendwie nicht weiter, wie ich da jetzt den Reloadwert von 56
> eintragen soll.

Adäquat(tm) in TCNT0 oder - besser - OCR1A/ICR1/OCR2.

HTH

von Ransap (Gast)


Lesenswert?

g457 schrieb:
>> das er immer im 100uS Takt auslöst
>
> Dafür nimmst Du einfacher den Timer1 oder Timer2, die haben CTC.
>
>> Aber der Timer wird nicht ausgelöst.
>
> Woher weisst Du das? Lass mich raten: Die nicht genannte LED blinkt
> nicht. Wenn ich den Code nicht falsch überflogen hab wird sie das auch
> nicht - Du toggelst nur den Pullup-Widerstand.
>


Wer sagt denn was von ner LED. Warum verbindet ihr ein Timer immer mit 
einer LED. Es würde sowieso nichts bringen eine LED im 100uS Takt 
blinken zu lassen, da man das wahrscheinlich garnicht merkt ;)

von g457 (Gast)


Lesenswert?

> Wer sagt denn was von ner LED.

Keiner. Du auch nicht. Und Du sagst uns trotzdem nicht woher Du weisst, 
dass die ISR nicht angesprungen wird. DAS wär viel wichtiger.

> Es würde sowieso nichts bringen eine LED im 100uS Takt
> blinken zu lassen, da man das wahrscheinlich garnicht merkt ;)

Doch, tut man. Einfach mal ausprobieren. Aber jetzt erst mal zurück zum 
eigentlichen Thema - wir hören..

von Uwe (de0508)


Lesenswert?

Guten Tag,

es sei noch angemerkt, dass eine LED nur dann blinken wird, wenn der 
zugehörige PortB auch als Ausgang geschaltet wurde.

Dazu müsste man das zugehörige Bit in DDRB setzen.

von g457 (Gast)


Lesenswert?

> es sei noch angemerkt, dass eine LED nur dann blinken wird, wenn der
> zugehörige PortB auch als Ausgang geschaltet wurde

Der TO will doch gar keine LED blinken lassen, er will nur den Pullup 
toggeln :-/ Und er merkts auch nicht ∗daran∗, dass die ISR nicht 
angesprugen wird, sondern an was anderem (woran, das hat er noch nicht 
gesagt).

von Martin K. (maart)


Lesenswert?

Ransap schrieb:
> Ich komm irgendwie nicht weiter, wie ich da jetzt den Reloadwert von 56
> eintragen soll.

Z.B. so:
1
ISR(TIMER0_OVF_vect)
2
{
3
  TCNT0 = 208;
4
  PORTB ^= (1<<PB1);
5
  
6
}

So wird der Pull-Up alle 100µS ein- und ausgeschaltet.

von Ransap (Gast)


Lesenswert?

Okay ich habe jetzt den Ausgang aktiviert und mal als beispiel ne LED 
dran gehängt, wie es ja viele gesagt haben, aber es geht immer noch 
nicht ?
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
ISR(TIMER0_OVF_vect)
5
{
6
  TCNT0 = 208;
7
  PORTB ^= (1<<PB1);
8
  
9
}
10
11
int main(void)
12
{
13
  PORTB &= ~(1<<PB1);
14
  TCCR0 |= (1<<CS01); //Prescaler 8,
15
  TIMSK |= (1<<TOIE0); //Interrupt Enable
16
  
17
  sei();
18
    while(1)
19
    {
20
        //TODO:: Please write your application code 
21
    }
22
}

von Ransap (Gast)


Lesenswert?

Martin Kreiner schrieb:
> Ransap schrieb:
>> Ich komm irgendwie nicht weiter, wie ich da jetzt den Reloadwert von 56
>> eintragen soll.
>
> Z.B. so:ISR(TIMER0_OVF_vect)
> {
>   TCNT0 = 208;
>   PORTB ^= (1<<PB1);
>
> }
> So wird der Pull-Up alle 100µS ein- und ausgeschaltet.

Wie kommst du auf den Wert ?
Wenn ich in meinem AVR-Timer-Calculator meine Frequenz 400000Hz und in 
uS 100 eingebe, kommt der Wert 56 mit einem Prescaler 8

von Ransap (Gast)


Lesenswert?

100uS sind 0,1 millisekunden, wie kann man da sehen, das das was blinkt 
? -höchstens ein Flimmern wird man da sehen...

von holger (Gast)


Lesenswert?

>Okay ich habe jetzt den Ausgang aktiviert

Wo hast du das gemacht?

  PORTB &= ~(1<<PB1);

Damit bestimmt nicht;)

von Hubert G. (hubertg)


Lesenswert?

Darum wäre es Interessant wie du feststellst das die ISR nicht 
funktioniert.
4000000 / 8 = 500000 und die darfst du nur mit 50 dividieren damit du 
auf 10000 kommst. Also darf der Timer nur mehr bis 50 zählen, oder in 
deinem Fall bis zum Overflow 256. Damit ist der Vorgabewert eben 206 
oder mit Korrekturfaktor eben 208.

Du hast auch recht, die Led siehst du nicht mal flimmern.

von Mr. X (Gast)


Lesenswert?

Ransap schrieb:
> 100uS sind 0,1 millisekunden, wie kann man da sehen, das das was blinkt
> ? -höchstens ein Flimmern wird man da sehen...

Sportlich, sportlich - da dürftest du einen Faktor 100 mit der 
Einschätzung deiner optischen Wahrnehmung daneben liegen.

Übrigens: Was schreibst du immer von Mikrosiemens?
http://de.wikipedia.org/wiki/Siemens_%28Einheit%29

von Martin K. (maart)


Lesenswert?

Ransap schrieb:
> Wie kommst du auf den Wert ?
> Wenn ich in meinem AVR-Timer-Calculator meine Frequenz 400000Hz und in
> uS 100 eingebe, kommt der Wert 56 mit einem Prescaler 8

Löse (x*8)/4 MHz = 100µs => x=50.

Es sind also 50 Timerschritte nötig. Der Timer kann maximal 256 Schritte 
zählen, also ergibt sich ein Wert von 256 - 50 = 206
Jetzt kommt ein Pferdefuß: Dein Timer läuft aber nicht "frei durch".
Du musst dir das so vorstellen:
- Der Timer läuft über, der Interrupt wird ausgelöst und in der ISR wird 
der neue Wert in TCNT0 geschrieben. Bis dahin sind allerdings schon 
einige Takte vergangen, in denen der Timer weitergezählt hat. Daher 
meine 208.

Da der PB1 bei dir als Eingang konfiguriert ist, bewirkt das hier
1
PORTB ^= (1<<PB1);
nur ein Ein- und Ausschalten des internen Pull-Ups.

von Ransap (Gast)


Lesenswert?

Okay das ist mir jetzt unendlich peinlich das ich DDRD mit PORTB |= 
(1<<PB1) vertauscht habe. Entschuldigung, jetzt funktioniert es.

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.