Forum: Mikrocontroller und Digitale Elektronik ISR von Timer1 wird nur 1x ausgeführt (mega32)


von S. L. (slehner)


Lesenswert?

Hallo zusammen,

ich bin gerade dabei den Timer1 bei einem atmega32 zum laufen zu 
bringen.

Die ISR wird nach dem Start auch 1x ausgeführt. (Zu sehen an einer LED, 
die ich an PORTB angeschlossen habe. Dach dieser einen Ausführung leider 
sehe ich die LED nicht nochmal aufleuchten.

Einen Versuch das Problem im Simulator nachzuvollziehen habe ich schon 
hinter mir. Herausgekommen ist, dass im Simulator die ISR nach 
erstmaligem aufrufen nicht mehr verlassen wird. (PORTB wird 
erwartungsgemäss dabei ein und ausgeschaltet)

Der Code:
1
SIGNAL(SIG_OUTPUT_COMPARE1A)
2
{  
3
PORTB |= ((1 << PB0) | (1 << PB1) | (1 << PB2));
4
delayloop16(65000);
5
PORTB &= ~((1 << PB0) | (1 << PB1) | (1 << PB2));  
6
}
7
8
9
int main()
10
{
11
DDRB = (1 << DDB0) | (1 << DDB1) | (1 << DDB2);
12
13
TCCR1B |= (1<<WGM13) | (1<<WGM12);
14
OCR1A = 6500;
15
TCNT1=0;
16
TIMSK |= (1<<OCIE1A);
17
TCCR1B |= (1<<CS11)|(1<<CS10);
18
sei();
19
20
ENDLOSSCHLEIFE
21
}

Die Funktion delayloop16 funktioniert.

Ich kann mir das widersprüchliche Verhalten nicht erklären. Weiss jemand 
dazu vielleicht Genaueres?

VG Sebastian

von MarkusW (Gast)


Lesenswert?

Hallo!

Als erstes Mal kein Warten in der ISR (ISRs immer möglichst schnell 
wieder verlassen)!

Toggle die LEDs bei jedem Interrupt (kannst dir den Status ja merken).

Ich denke, dass dürfte es dann schon gewesen sein.

Gruß
Markus

von Sven P. (Gast)


Lesenswert?

Zeig mal den restlichen Code auch noch und schreib dazu, wie schnell der 
Controller wirklich läuft.

von S. L. (slehner)


Angehängte Dateien:

Lesenswert?

vielen Dank für die schnellen Antworten.

Den Rat von MarkusW habe ich befolgt und die Delay-Funktion, die ich 
eigentlich nur zum Testen eingefügt habe, durch ein Toggeln ersetzt. Im 
Simulator funktionert nun das Programm auch, wie es soll, inklusive der 
Zeitverzögerung, die durch den Timer erzeugt werden soll. Der Port wird 
auch wie erwartet getoggelt.

Leider funktioniert es in Hardware wieder nicht :-( Der Atmel läuft ohne 
externes Quarz und somit auf 1MHz.

Gibt es vielleicht sonst noch irgendwelche Fehler, die ich übersehen 
habe?

VG Sebastian

von Karl H. (kbuchegg)


Lesenswert?

Hmm.
Wenn du WGM13 und WGM12 setzt, dann läuft der Timer im CTC
Modus, wobei ICR1 die Obergrenze definiert.
Die spannende Frage ist jetzt: Welcher Wert steht in ICR1?
(Kann ich aus dem Stegreif nicht sagen, da du ICR1 in deinem
Code nicht setzt). Ich geh mal vom schlimmsten aus: ICR1 steht
auf 0xFFFF dh. 65535

Dein µC läuft mit 1Mhz
Vorteiler: 64
damit läuft der Timer mit 15625 Hz
Der Timer muss jedesmal bis ICR1 zählen, also bis 65535.
15625 / 65535 = 0.23 Hz

Das macht alle 4.2 Sekunden einen Aufruf der ISR. Dies deshalb,
weil es völlig unerheblich ist, worauf du OCR1A einstellst. Diese
Einstellung bestimmt lediglich wann genau deine ISR bei welchem
Timerstand aufgerufen wird. Aber von einem Aufruf zum nächsten
dauert es trotzdem 4.2 Sekunden. Denn solange braucht der Timer,
bis er einmal rum ist.

von Johannes M. (johnny-m)


Lesenswert?

@Karl heinz:
Ich denke eher, dass ICR1 auf dem Initialisierungswert von 0x0000 steht 
und deshalb der Compare-Wert, auf den der Interrupt kommen soll, gar 
nicht erreicht wird.

@S. Lehner:
Schmeiß das WGM13 raus. Du willst doch vermutlich CTC mit OCR1A als 
Spitzenwert (alles Andere macht wenig Sinn). Dazu darf aber nur WGM12 
gesetzt  sein.

Deine ISR lässt sich übrigens bequem in einer einzigen Zeile 
zusammenfassen:
1
ISR(TIMER1_COMPA_vect)
2
{
3
    PORTB ^= ((1 << PB0) | (1 << PB1) | (1 << PB2));
4
}
Und verwende besser nicht mehr SIGNAL. Das ist veraltet und als Anfänger 
sollte man sich möglichst gleich die zukunftsträchtige Schreibweise 
angewöhnen.

von S. L. (slehner)


Angehängte Dateien:

Lesenswert?

OK viiielen Dank an alle. Die zwei letzten Beträge habe ich wieder 
entfernt, da sie nichts zur Lösung des Problems beitragen. Gleichzeitig 
tut es mir leid diesen Mist gepostet zu haben.

Vielen Dank an Johannes M. und Karl heinz Buchegger, das Problem war die 
falsche Initialisierung von WGM12.

Für alle zukünftigen Leser des Betrages die den Timer 1 verwenden 
möchten poste ich nocheinmal den korrekten Code.

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.