Interrupt Problem mit ATMega128

OP #803681
Lesenswert?

Hallo,

ich habe mal wieder ein Problem mit meinem ATMega128 und den Interrupts.
Ich benutze die Timer0, Timer2 und einen Interrupt für die UART.
Solange nur die ISR für die beiden Timer im Programm waren, liefen diese 
noch.
Seitdem ich den UART-Empfang per Interrupt steuere, laufen die Timer 
scheinbar nicht mehr.

die entsprechenden Programmteile sind hier :

ISR( TIMER0_OVF_vect )
{
  teiler_abtastung++;
  speicher_zaehler ++;

  if( teiler_abtastung >= teiler_abtastrate)
  {
    teiler_abtastung = 0;
    PORTA ^= 0x08;
    speicher_zaehler = 0;
  }
}

ISR( TIMER2_OVF_vect )
{
  teiler_laufzeit++;
  if( teiler_laufzeit >= 3596)
  {
    teiler_laufzeit = 0;
    PORTA ^= 0x10;
  laufzeit_sekunden ++;

  if( laufzeit_sekunden >= 59)
      {
         laufzeit_sekunden = 0;
      laufzeit_minuten ++;
                PORTA ^= 0x20;
    }
  }
}

ISR( SIG_UART1_RECV )
{
  uart();
}

die Initialisierung in der main:

TCCR0 = ( 1 << CS01 );
TCCR2 = ( 1 << CS21 );
TIMSK = ( 1 << TOIE2 )|( 1 << TOIE0 );

und für die UART-Schnittstelle:

void USART_INIT(unsigned int baud)
{
  UBRR1H = (unsigned char)(baud>>8);
  UBRR1L = (unsigned char)baud;
  UCSR1B = (1<<RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
  UCSR1C = (1<<USBS1)|(1<<UCSZ11)|(1<<UCSZ10);
}

Ich hoffe mal, ihr könnt mir helfen.

mit freundlichen Grüßen
Gast #803704
Lesenswert?

Ich kann nur raten, aber schon mal an den watchdog gedacht? Hatte mal 
was Ähnliches. Bei mir lief der Watchdog in der UART Routine einfach 
über. Ein Deaktivieren der Interrupts in ISR( SIG_UART1_RECV ) könnte 
evtl ne Lösung sein.
Ist aber wirklich nur ne Vermutung...
Gast #803808
Lesenswert?

Hmm. Gute Frage. Soweit ich weiß, muss der µC den Watchdog immer wieder 
reseten. Sobald er sich aber in nem Interrupt befindet macht er das 
nicht mehr. Dauert dein Interrupt zu lange, was bei Uart leicht der Fall 
sein kann, läuft der Watchdog über und resetet den Controller.

So oder so ähnlich läuft das wohl ab :)
#803902
Lesenswert?

Was passiert in der Funktion Uart() ?

Beim UART Empfangsinterrupt gibt es eine Falle:
Du musst das Zeichen aus dem UDR1 Register auslesen.
Erst dieses Lesen setzt die Interrupt Anforderung zurück.
Wird aus UDR1 nicht gelesen, dann kommt der UART1_RECV
Interrupt gleich wieder und wieder und wieder.

Mit: "Ich häng mich da mal an den Interrupt dran um zu
sehen ob er ausgelöst wird, das Zeichen verarbeiten mach
ich dann später" ist also nichts.
OP #804374
Lesenswert?

Guten morgen,

Also hier mal meine uart();
Ist das Auslesen vom UDR1 Register da schon zu spät?

void uart (void)
{
  uint8_t i;
    char c;
    char* s;

   s=befehl;
    i=0;


    do
    {
      c=USART_Receive();
    if( c!='\r')
    {
        *s=c;
        s++;
        i++;
    }
  }
  while( c!='&' );
    *s=0;

  befehlspruefung();

  while (!(UCSR0A & (1<<UDRE0))) {}
}

und hier noch die Funktion für den Empfang:

uint8_t USART_Receive(void)
{
  while ( !(UCSR1A & (1<<RXC1)) );
  return UDR1;
}

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