mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik attiny 45 Timer CompareFlag Bug?


Autor: FMaili (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich arbeite gerade an einer Schaltung auf einem attiny 45 unter avr-gcc 
die mit mehreren Interrupts arbeitet. Zum Einen habe ich den 
Software-Uart eingebaut und nutze dazu den Timer 1. Das Compareregister 
A (OCR1A) löst dabei ja zyklisch einen Interrupt aus, den man zum senden 
nutzen kann. Das klappt soweit super.

Aber jetzt kommt's:
Ein anderer Teil der Schaltung empfängt über den Pin PB2 (INT0) Daten 
aus einem zweiten Bus. Für Timeoutzwecke nutze ich hier den Timer 0. 
Wenn das Programm jetzt gerade den Interrupt (INT0) vom Pin PB2 
verarbeitet und ich hier das compare match flag mit TIFR |= ( 1 << OCF0A 
); lösche, scheint auch das Flag vom Timer 1 gelöscht zu werden, wenn 
der Match genau in dieser Zeit stattfindet!

Der Aufruf der Interruptroutine wird jedenfalls nicht nachgeholt. Lasse 
ich das TIFR |= ( 1 << OCF0A ); weg - klappt alles wir gewollt und der 
Timer1 Interrupt wird abgearbeitet.

Hat jemand schon mal ein ähnliches Problem gehabt? Ich konnte bei der 
Suche nichts finden.

Hier noch ein paar Code-Schnipsel zur Verdeutlichung:

-------------------------------------------------------------
#include <avr/io.h>
#include <avr/interrupt.h>
#ifndef SIGNAL
#include <avr/signal.h>
#endif // SIGNAL

void uart_init()
{
  ...
  SUART_TXD_PORT |= (1 << PB3);             // Testausgabe auf PB3
  SUART_TXD_DDR  |= (1 << PB3);             // Testausgabe auf PB3

  // Clear Counter wenn TCNT1 == OCR1C
  TCCR1 = ( ( 1 << CS12 ) | ( 1 << CS11 ) ) | ( 1 << CTC1 );

  OCR1C = 104;
  TIFR |= (1 << OCF1A);                     // Reset Timer1 Overflow 
Flag
  ...
}

ISR(TIM1_COMPA_vect)
{
  ...
  SUART_TXD_PORT ^=  (1 << PB3);            // Testausgabe auf PB3
  ...
}

ISR(INT0_vect)
{

  ...
  for( tmp=0; tmp<100; tmp++ )               // Verzügerung für den Test
  {
    if(len > 88) stat=44;
  }
  TIFR |= ( 1 << OCF0A );                   // clear compare match flag.

  ...
}
----------------------------------------------------------

Für Anregungen wäre ich sehr dankbar.

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In TIFR steht drinnen  (1 << OCF1A) | (1 << OCIE0).
Dann heist TIFR |= ( 1 << OCF0A ) also

TIFR = TIFR or ((1 << OCF0A) or (1 << OCF1A) or (1 << OCIE0))

Nimm einfach  TIFR = (1 << OCF0A); und lasse das ODER weg. Beim Löschen 
von Bits in TIFR haben nur gesetzte Bits im Wert eine Wirkung, 0 Bits 
verändern an den TIFR Flags nichts.

Gruß Hagen

Autor: FMaili (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klasse, vielen Dank für die schnelle Hilfe.

An das Oder habe ich gar nicht mehr gedacht. Hat sich irgendwie 
eingeschlichen und ich habe das gar nicht mehr in Betracht gezogen.

Besten Dank

FMaili

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.