Timer-Interrupt ohne Funktion ?

Gast #368038
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
Gast #368041
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
Gast #368043
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...
Gast #368047
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...
Gast #368049
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...
Gast #368052
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren