www.mikrocontroller.net

Forum: Compiler & IDEs Timer-Interrupt ohne Funktion ?


Autor: Franz Wudy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich bin gerade verzweifelt, weil mich ein Mega128 und WinAVR 20060125
bei einer simplen Timerinterrrupt-Routine ärgert.
Das folgende Beispielprogramm soll einfach auf dem USART den Wert der
globalen Variable dummy ausgeben. Diese wird vom Timer-ISR hochgezählt.
Also sollte am USART 0\n 0\n 0\n 0\n 2\n 2\n 2\n 2\n ....
ausgegeben werden. Klapppt aber nicht, ich komme nie bei der 2 an!
Ich habe den Eindruck, der Handler wird nie aufgerufen. Der Vector-Name
sollte stimmen, IRQ ist aktiviert, Controller funktioniert ansonsten
brav.

Bin ich blind oder warum funktioniert das nicht ?



#define MAXINTEXT 101

#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <stdlib.h> // für itoa, strtod
#include <string.h> // für strcat
#include <math.h>

#include "Mega128RS232.h"

// Strings für Input/Outputverwaltung und allgemeine Flags
char outtext[MAXINTEXT], string[21]; // für Ausgaben auf LCD und RS232
char usbintext[MAXINTEXT];
char ictext[MAXINTEXT];
unsigned char command_done;

// Variablen aus anderen C-Dateien
extern volatile unsigned char command_complete; // aus rs232.c
extern volatile unsigned char dataready; // aus rs232.c

volatile unsigned int dummy = 0;

int main(void)
{
   USART_Init(1);      // initialisiert die serielle Schnittstelle
   sei();

   TCCR3A = 0;
    TCCR3B = (1 << WGM32); // WGM32: Timermode Normal
   TCCR3B |= (1 << CS30) & ~(1 << CS32) & ~(1 << CS31); // Prescaler =
1
   OCR3A = 512; // gibt rund 60 µs
   TIMSK |= (1 << OCIE3A); // Interrupt für Timer einschalten
   while(1)
   {
      _delay_us(10);
      utoa(dummy, outtext, 10);
      strcat(outtext, "\n");
      USART1_Transmit_string(outtext); // an den PC rausschreiben
   }
   return(0); // :-)
}

ISR(TIMER3_COMPA_vect) // wird aufgerufen, wenn der Timer-IRQ auftritt
{
   dummy += 2;
}


Ciao -

Franz

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du globale Variablen, die in Interrupt Handlern verändert werden,
nicht als 'volatile' deklarierst, kann alles Mögliche passieren...

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, Blindheit... Ist ja tatsächlich volatile... Sorry, noch zu früh
am morgen

Autor: Franz Wudy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Johnny.m für deine Antwort,

jedoch: Wie in der letzten Zeile vor der main{...} zu ersehen ist, ist
die Variable dummy als volatile deklariert.
Daher kann ich deinen Einwand nicht verstehen!

Liebe Grüße -

Franz

Autor: Franz Wudy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das ging jetzt aber gleichzeitig! ;-)

anderer tip?

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  TCCR3B |= (1 << CS30) & ~(1 << CS32) & ~(1 << CS31);
Was ist das denn? Das kann so nicht wirklich funktionieren, zumindest
wahrscheinlich nicht so, wie Du Dir das vorstellst. Mit der Anweisung
setzt Du alle Bits in TCCR3B, bis auf CS32 und CS31. Ich glaube, das
ist nicht in Deinem Sinn...

Autor: Franz Wudy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was schlägst du dann vor den prescaler auf eins zu bekommen?

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ne, das stimmt ja auch. Sorry, bin echt noch nicht wach. Ich gebs auf...

Autor: Franz Wudy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
net aufgeben! G

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...Wobei, die &-Verknüpfungen bringen einfach nix. Lass sie der
Übersichtlichkeit halber einfach weg... Deshalb auch meine Verwirrnis.
Schreib einfach TCCR3B = (1 << WGM32) | (1 << CS30); Dann sind
automatisch alle Bits bis auf WGM32 und CS30 '0'.
Auch wenn das wahrscheinlich nicht der gesuchte Fehler ist. 'Falsch'
in dem Sinne ist es ja nicht...

Autor: Franz Wudy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur warum wird der Interrupt niemals ausgelöst, bzw. warum ändert sich
am Wert der dummy-Variable nichts?!

Ich verstehs nicht!

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mir ist da noch was aufgefallen (jetzt, wo ich langsam wach werde): Du
schreibst, der Wert soll alle 60 µs erhöht werden. Wie soll denn in
60µs der ganze Rest inkl. serieller Ausgabe funktionieren? Je nachdem,
mit welcher Baudrate Du arbeitest, sind das einige ms. Ich vermute mal
(ohne den Rest des Programms zu kennen) dass es da ein Timing-Problem
geben dürfte. Den Fehler an sich sehe ich aber immer noch nicht...

Autor: Franz Wudy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja... das rausschreiben wird ja auch gehörig verzögert, der interrupt
zum hochzählen sollte also schon mal ausgeführt werden, bzw. dummy
erhöht werden.

ich werd noch wahnsinnig!

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das OCIEA Bit ist in der extended Interrupt Mask

Also:

   ETIMSK |= (1 << OCIE3A); // Interrupt für Timer einschalten

Damit gehts zumindest im Simulator

Autor: Franz Wudy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wunderprächtig, da bin ich auch gerade drauf gekommen!

Herzlichen Dank trotzdem.

Da zieht man vom Interrupt1 auf den Dreier um und ersetzt einfach die
Ziffern, und schon gehts nimmer! Gemein!

Franz

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daher haben die neuen AVRs auch ein eigenes TIMSKx-Register für
jeden Timer.  Da sollte das dann offensichtlich sein.

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.