mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR Timer 1 Interrupt und UART Interrupt stören sich?


Autor: Frank Goenninger (dg1sbg)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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:
ISR( TIMER1_COMPA_vect  )    // ISR triggered by Timer 1 to
{                                           // interact with the user via DARC.

  heart_beat();                        // Blink heartbeat LED.

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

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:

EVENT BOOT DEVICE=P1025A ID=801.
EVENT STATUS-CHANGE STATUS=BOOT.
OK.
HELLO, DEAR !
FAIL.
OK.
GOODBYE ...

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:
void init_io_timer ( void )
{
  double   nTickInterval;
  double   nDesiredTimerInterval;
  uint16_t nPrescalerValue;

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

  cli();                         // Ensure atomic execution

  nTickInterval               = 0.0;   // [s]
  nDesiredTimerInterval = PSU_IO_UPDATE_INTERVAL;
  nPrescalerValue           = PSU_IO_TIMER_PRESCALER_VALUE;

  nTickInterval   = 1 / F_CPU * nPrescalerValue;
  nTimerLoadValue = nDesiredTimerInterval / nTickInterval - 1; 
    
  OCR1A  = nTimerLoadValue;      // Load the timer compare value
  
  TCNT1  = 0;                              // Reset counter value
  TCCR1A = 0;                             // No PWM
  TIMSK  |= _BV( OCIE1A );            // Output Compare A Interrupt: enable it
  TCCR1B |= _BV( WGM12 );          // Set CTC mode
  
  TCCR1B &= ~( _BV( CS12 ));        // Set prescaler to 1
  TCCR1B &= ~( _BV( CS11 ));        // and start timer.
  TCCR1B |= _BV( CS10 );         

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

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

Autor: Frank Goenninger (dg1sbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erledigt ! Fehler gefunden! ( War eine falsche Initalisierung des Timer 
1).

Dieser Beitrag hat mir gezeigt, wie's richtig geht:

Beitrag "Re: Timerprobleme"

Vielen Dank!

Gruß,
  Frank

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.