AVR Timer 1 Interrupt und UART Interrupt stören sich?

#1131834
Lesenswert?

Hallo zusammen und guten Morgen,

nach nun einem Wochenende mit vergebenem Debuggen hier nochmal eine 
Frage zu UART per Interrupt und regelmäßigem Abarbeiten einer Funktion 
per Timer 1 im CTC Mode.

(Umgebung: ATMega32 8 MHz, AVR-GCC 4.3.2, AVR-Libc 1.6.4)

Folgende kleine Routine wird durch den Timer 1 aufgerufen:
1
ISR( TIMER1_COMPA_vect  )    // ISR triggered by Timer 1 to
2
{                                           // interact with the user via DARC.
3

4
  heart_beat();                        // Blink heartbeat LED.
5

6
  darc_get_command();           // Receive cmd via DARC channel. Will set
7
                                             // a flag if complete cmd received.
8
}

Die Funktion heart_beart() toggelt eine LED an Port B. In 
darc_get_command() wird geprüft, ob per UART (ebenso 
Interrupt-gesteuert) ein String empfangen wurde. Wenn ja, wird ein Flag 
gesetzt. Die Funktion nutzt die UART Lib von Peter Fleury. Sollte kein 
Zeichen anstehen, so springt die Routine sofort wieder zurück.

Die Routine wird ausgeführt - soviel verrät mit die Heartbeat LED.

In main() wird nun geprüft, ob das Flag gesetzt ist. Also 
"Standard-Vorgehen".
- Der ganze Code ist anbei ...

Ich habe auch einen Screenshot der Terminalausgabe beigefügt. Diese 
sieht so aus:
1
EVENT BOOT DEVICE=P1025A ID=801.
2
EVENT STATUS-CHANGE STATUS=BOOT.
3
OK.
4
HELLO, DEAR !
5
FAIL.
6
OK.
7
GOODBYE ...
8

9
EVENT BOOT DEVICE=P1025A ID=

Die Zeilen bis einschließlich "GOODBYE ..." zeigen den normalen Ablauf, 
wie ich ihn gerne hätte. Dies erreiche ich aber nur, wenn ich den Timer 
1 NICHT INITIALISIERE ...

Meine init_io_timer()-Funktion:
1
void init_io_timer ( void )
2
{
3
  double   nTickInterval;
4
  double   nDesiredTimerInterval;
5
  uint16_t nPrescalerValue;
6

7
  uint8_t  nTmpSREG = SREG;      // Save status 
8
 
9
  // We use timer 1 (16 bit Timer) in CTC mode. This timer shall 
10
  // generate an interrupt every PSU_IO_UPDATE_INTERVAL seconds.
11
  // Prescaler has to be set to 1 !
12

13
  cli();                         // Ensure atomic execution
14

15
  nTickInterval               = 0.0;   // [s]
16
  nDesiredTimerInterval = PSU_IO_UPDATE_INTERVAL;
17
  nPrescalerValue           = PSU_IO_TIMER_PRESCALER_VALUE;
18

19
  nTickInterval   = 1 / F_CPU * nPrescalerValue;
20
  nTimerLoadValue = nDesiredTimerInterval / nTickInterval - 1; 
21
    
22
  OCR1A  = nTimerLoadValue;      // Load the timer compare value
23
  
24
  TCNT1  = 0;                              // Reset counter value
25
  TCCR1A = 0;                             // No PWM
26
  TIMSK  |= _BV( OCIE1A );            // Output Compare A Interrupt: enable it
27
  TCCR1B |= _BV( WGM12 );          // Set CTC mode
28
  
29
  TCCR1B &= ~( _BV( CS12 ));        // Set prescaler to 1
30
  TCCR1B &= ~( _BV( CS11 ));        // and start timer.
31
  TCCR1B |= _BV( CS10 );         
32

33
  SREG = nTmpSREG;                   // Done - so interrupts ok now
34
}

Wie in der Ausgabe zu sehen ist, stoppt die Ausgabe nach "ID=". Danach 
kommt kein Zeichen mehr am Terminal an und ich kann auch kein Zeichen 
mehr per UART empfangen ...

Führe ich die Funktion darc_get_command() in der while-Schleife in 
main() aus, dann klappt die Sache wunderbar ...

Was ist mir hier mal wieder entgangen ???

Viele, vielen herzlichen Dank im Voraus !!!

Grüße,
   Frank
Angehängte Dateien:

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