mikrocontroller.net

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


Autor: S. Lehner (slehner)
Datum:

Bewertung
0 lesenswert
nicht 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:
SIGNAL(SIG_OUTPUT_COMPARE1A)
{  
PORTB |= ((1 << PB0) | (1 << PB1) | (1 << PB2));
delayloop16(65000);
PORTB &= ~((1 << PB0) | (1 << PB1) | (1 << PB2));  
}


int main()
{
DDRB = (1 << DDB0) | (1 << DDB1) | (1 << DDB2);

TCCR1B |= (1<<WGM13) | (1<<WGM12);
OCR1A = 6500;
TCNT1=0;
TIMSK |= (1<<OCIE1A);
TCCR1B |= (1<<CS11)|(1<<CS10);
sei();

ENDLOSSCHLEIFE
}

Die Funktion delayloop16 funktioniert.

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

VG Sebastian

Autor: MarkusW (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sven P. (haku) Benutzerseite
Datum:

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

Autor: S. Lehner (slehner)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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:
ISR(TIMER1_COMPA_vect)
{
    PORTB ^= ((1 << PB0) | (1 << PB1) | (1 << PB2));
}
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.

Autor: S. Lehner (slehner)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.