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


von FMaili (Gast)


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.

von Hagen R. (hagen)


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

von FMaili (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.