ISR: wird nicht aufgerufen?!

Gast #2434493
Lesenswert?

Hallo,

ich bin langsam am verzweifeln, versuche eine Uhr zu programmieren und 
die sekunden per uart im terminal auszugeben. Habe ein Atmega128 mit 2 
Quarzen. Ein RTC Uhrenquarz 32,768 KHz und ein 16 MHz Quarz.

Nun zum Problem:
Habe die Uart schon programmiert und getestet, funktioniert auch soweit.
Im Prinzip aktiviere ich in der main Funktion die globalen Interrupts 
und starte dann die Funktion Starten(). In der wird die Einstellung für 
den Timer 0 verarbeitet, meiner Meinung nach ist alles auch OK, 
zumindest mit dem Sekundentakt.

Wenn ich nun mir die Ausgabe auf dem Terminal angucke, bekomme ich jede 
Sekunde den Wert für a (Variable für die Sekundenzählung), doch sie ist 
immer 0. Ich vermute, dass die ISR nicht aufgerufen wird und somit a nie 
größer wird.

Werde daraus nicht weiter schlau, hoffe ihr könnt mir helfen.

Danke im voraus.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define FOSC 16000000  //Quarzfrequenz
#define BAUD 9600  //Baudrate
#define MYUBRR FOSC/16/BAUD-1  //Werte für UBRR Register

volatile uint8_t a;
char b[10];

void USART0_Init( unsigned int ubrr ) {
  //Baudrate setzen
  UBRR0H = (unsigned char)(ubrr>>8);
  UBRR0L = (unsigned char)ubrr;

  //Sender aktivieren
  UCSR0B = (1<<TXEN0)|(1<<RXEN0);

  //Frame Format setzen: 8data, 2stop bit */
  UCSR0C = (0<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00);
}

void USART0_Transmit( unsigned char data ) {
  //warten bis Sendepuffer leer
  while ( ! (UCSR0A & (1<<UDRE0)) );

  //Daten in Puffer und senden
  UDR0 = data;
}

/* puts ist unabhaengig vom Controllertyp */
void USART0_Transmit_string (char *s)
{
    while (*s)
    {   /* so lange *s != '\0' also ungleich dem 
"String-Endezeichen(Terminator)" */
        USART0_Transmit(*s);
        s++;
    }
}

ISR(TIMER0_OVF_vect) //overflow interrupt vector
{
  a++;
}

void starten(void)
  {
    TIMSK &=~((1<<TOIE0)|(1<<OCIE0));     //Disable TC0 interrupt
    ASSR |= (1<<AS0);           //set Timer/Counter0 to be asynchronous 
//from the CPU clock with a second external clock(32,768kHz)driving it.
    TCNT0 = 0x00;
    TCCR0 |= ((1<<CS02) | (1<<CS00));
    while(ASSR&0x07);           //Wait until TC0 is updated
    TIMSK |= (1<<TOIE0);
  }

int main( void )
{
  USART0_Init ( MYUBRR ); //USART initialisieren

  sei(); //Interrupts aktivieren

  starten();

  itoa( a, b, 10 );
  USART0_Transmit_string(b);

  while(1){
  }
  return 0;
}
#2434503
Lesenswert?

> Wenn ich nun mir die Ausgabe auf dem Terminal angucke,
> bekomme ich jede Sekunde den Wert für a


aber nicht mit dem Code. Das ist völlig unmöglich (es sei denn, dein µC 
wird ständig resettet und fängt das Programm jedes mal wieder von vorne 
an

> int main( void )
> {
>   USART0_Init ( MYUBRR ); //USART initialisieren
>
>   sei(); //Interrupts aktivieren
>
>   starten();
>
>   itoa( a, b, 10 );
>   USART0_Transmit_string(b);
>
>   while(1){
>   }
>   return 0;
> }

Du lässt dir EINMAL den Wert für a ausgeben und danach passiert in der 
Hauptschleife nix mehr. Wie willst du denn da beobachten, wie sich a 
verändert?
1
int main( void )
2
{
3
  USART0_Init ( MYUBRR ); //USART initialisieren
4

5
  sei(); //Interrupts aktivieren
6

7
  starten();
8

9
  while(1){
10
    itoa( a, b, 10 );
11
    USART0_Transmit_string(b);
12
  }
13
  return 0;
14
}
#2434507
Lesenswert?

> void starten(void)
>   {
>     TIMSK &=~((1<<TOIE0)|(1<<OCIE0));     //Disable TC0 interrupt
>     ASSR |= (1<<AS0);           //set Timer/Counter0 to be asynchronous
> //from the CPU clock with a second external clock(32,768kHz)driving it.
>     TCNT0 = 0x00;
>     TCCR0 |= ((1<<CS02) | (1<<CS00));
>     while(ASSR&0x07);           //Wait until TC0 is updated
>     TIMSK |= (1<<TOIE0);
>   }

Machs doch für deine ersten Gehversuche nicht komplizierter als 
notwendig
1
void starten(void)
2
{
3
  TCCR0 = ((1<<CS02) | (1<<CS00));
4
  TIMSK = (1<<TOIE0);
5
}
#2434509
Lesenswert?

Ehrlich gesagt wundert mich, dass Du überhaupt mehr als eine Zeile 
Ausgabe bekommst, denn für meine Begriffe wird da nur einmal was 
ausgegeben (und das sollte 0 sein).

Ich vermute daher, dass dein Controller jede Sekunde resetted, 
möglicherweise ist da irgendwo der falsche Interrupt aktiviert (ich hab 
das jetzt nicht geprüft, nur ne Idee, wo man weitersuchen könnte)
#2434519
Lesenswert?

Cihan schrieb:
> Wenn ich nun mir die Ausgabe auf dem Terminal angucke, bekomme ich jede
> Sekunde den Wert für a (Variable für die Sekundenzählung), doch sie ist
> immer 0.

3 Möglichkeiten für dieses Verhalten (Reset jede Sekunde) bei obigen 
Source-Code:
1) M103C Fuse ist gesetzt.
2) Code wurde für falschen Controller kompiliert/gelinkt.
3) Die ELF-Datei wurde auf den Chip geladen.
Gast #2434521
Lesenswert?

Dann mal anderherum beschrieben. Versuche eine einfache uhr zu 
programmieren. lese schon seit 2 - 3 Tagen mir die Threads zu 
Uhrenprogrammierung durch und habe auch schon die Tutorien durch.

Habe es so verstanden, dass ich mit den Uhrenquarz jede Sekunde einen 
interrupt werfen muss, sodass dadurch die variable a sich verändert.

Verstehe ich da etwas falsch ?
Gast #2434523
Lesenswert?

Stefan Ernst schrieb:
> Cihan schrieb:
>> Wenn ich nun mir die Ausgabe auf dem Terminal angucke, bekomme ich jede
>> Sekunde den Wert für a (Variable für die Sekundenzählung), doch sie ist
>> immer 0.
>
> 3 Möglichkeiten für dieses Verhalten (Reset jede Sekunde) bei obigen
> Source-Code:
> 1) M103C Fuse ist gesetzt.
> 2) Code wurde für falschen Controller kompiliert/gelinkt.
> 3) Die ELF-Datei wurde auf den Chip geladen.

zu 1) ist nicht gesetzt, habe einen Bootloader per ISP raufgeladen und 
habe nur Bootrst oder so gesetzt gehabt

zu 2 und 3 bräuchte ich nähere informationen was du evtl. meinst.

Danke aber für die schnellen antworten.
#2434531
Lesenswert?

Cihan schrieb:
> zu 1) ist nicht gesetzt, habe einen Bootloader per ISP raufgeladen und
> habe nur Bootrst oder so gesetzt gehabt

Dann kommt noch dazu:
4) Bootloader benutzt Interrupts, und Vectoren wurden nicht wieder in 
den App-Bereich verschoben.

Cihan schrieb:
> zu 2 und 3 bräuchte ich nähere informationen was du evtl. meinst.

Zeige einfach mal, wie du die Datei generierst, die dann auf den Chip 
geladen wird.
Gast #2434546
Lesenswert?

Stefan Ernst schrieb:
> Cihan schrieb:
>> zu 1) ist nicht gesetzt, habe einen Bootloader per ISP raufgeladen und
>> habe nur Bootrst oder so gesetzt gehabt
>
> Dann kommt noch dazu:
> 4) Bootloader benutzt Interrupts, und Vectoren wurden nicht wieder in
> den App-Bereich verschoben.
>
> Cihan schrieb:
>> zu 2 und 3 bräuchte ich nähere informationen was du evtl. meinst.
>
> Zeige einfach mal, wie du die Datei generierst, die dann auf den Chip
> geladen wird.

Im Prinzip habe bei mit AVR Studio den Controller ausgewählt, in die 
Linker Options -Ttext=0x1800 eingefügt, laut Infoblatt Hersteller.

Anschließend Compeliere ich die ganze Sache und lade die hex file über 
ein externes Programm (vom Hersteller) auf den flash rauf.

Ich muss nebenbei vielleicht mal erwähnen was ich vor habe, mein 
aktuelles Projekt beinhaltet grad die Kommunikation zwischen einem 
Gsm-Modem und dem µC. Das habe ich schon fertig und funktioniert auch. 
Weiter habe ich noch einen LCD zu programmieren, bei dem auch alles 
fertig ist und funktioniert.

Der nächste schritt ist es ebend die RTC Funktion zu nutzen, ebend eine 
Uhr letztendlich daraus zu erstellen.

Hier nochmal das was ich besitze:
http://shop.chip45.com/epages/es10644620.sf/de_DE/?ObjectPath=/Shops/es10644620/Products/Crumb128-5.0/SubProducts/crumb128-5.0-14

Weiterhin nutze ich bei der Konfigruation unter AVR Studio unter Custom 
Options die avr-gcc und make vom Winavr.

Hoffe das hilft weiter...
Gast #2434596
Lesenswert?

Stefan Ernst schrieb:
> Cihan schrieb:
>> in die
>> Linker Options -Ttext=0x1800 eingefügt, laut Infoblatt Hersteller.
>
> Wenn der Hersteller nicht ganz besondere Vorkehrungen getroffen hat,
> kann so auch kein Interrupt funktionieren. Wozu soll das gut sein?

das ist eine gute frage und auch berechtigt. Ich weiss nicht warum ich 
dies in die linker optionen mit rein genommen habe, finde es jetzt auf 
anhieb auch nicht mehr, aber ohne dieses funktioniert es, die sekunden 
zählen hoch.

Allerdings muss ich die Ausgabe in der ISR machen.

Nun stellt sich die Frage für mich wie mein Programm weiter ablaufen 
wird. Möchte ja dass er mir die Uhrfunktionermöglicht, also jede sekunde 
ein interrupt, möchte aber zugleich alle anderen funktionen nutzen, mit 
anderen worten bspw. kommunikation zwischen Gsm und µc und auch 
LC-Display.

Das sollte doch ohne weiteres alles möglich sein.?

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