Countdown-Timer Interrupt wird nach Aktivierung ausgelöst

OP (Firma: Neutron Mikroelektronik GmbH) #5155650
Lesenswert?

Hallo alle zusammen,

ich verwende einen ATtiny1634 Baustein, um ein bestimmtes Protokoll auf 
Basis der UART Schnittstelle zu implementieren.

Dabei möchte ich nach einem Ereignis (Startbit bei UART erkannt) eine 
definierte Zeit warten und danach eine Aktion auslösen.

Für die Zeit habe ich den Timer1 so konfiguriert, dass er jeweils nach 
270µs auslöst.
1
TCCR1B  = (1<<WGM12);    // Clear Timer on Compare Match
2
TCCR1B |= (1<<CS11);     // Prescaler 8
3
OCR1A   = 269;           // Liefert bei 8MHz ein 270us Intervall

Im Interrupt, der bei Erkennung eines Startbits ausgelöst wird, starte 
ich den Timer
1
ISR(USART0_RXS_vect)
2
{
3
    TCNT1  = 0;           // Counter auf 0 setzen
4
    TIMSK |= (1<<OCIE1A); // Compare Interrupt erlauben
5
}

Im zugehörigen Timer Interrupt deaktiviere ich den Compare Interrupt 
wieder
1
ISR(TIMER1_COMPA_vect)
2
{
3
    TIMSK  &= ~(1<<OCIE1A);   // Compare Interrupt deaktivieren
4
    ...
5
}

Mein Problem ist jetzt, dass der Compare-Interrupt jedes mal direkt 
ausgelöst wird, nachdem er aktiviert wurde. Also direkt nach dem 
USART0_RXS_vect.


Natürlich kann ich jetzt immer den ersten Interrupt ignorieren, aber 
dass kann's ja wohl nicht sein. Außerdem verstehe ich es nicht. Ich hab 
auch schon versucht, direkt vor oder nach Aktivierung des Timers das 
Output-Compare-Flag OCF1A zu löschen. Hab ich aber entweder nicht 
richtig gemacht oder es hat nichts genutzt.

Kann mir da bitte jemand helfen bzw. es erklären?
#5155661
Lesenswert?

Wolfgang K. schrieb:
> Außerdem verstehe ich es nicht.

Du verbietest nur die Ausführung des Handlers, das Pending-Bit ist davon 
völlig unberührt. Es wird gesetzt, wenn die Bedingung erfüllt ist. Und 
wenn Du später den Handler erlaubst, wird er natürlich ausgeführt.

Wolfgang K. schrieb:
> Hab ich aber entweder nicht
> richtig gemacht oder es hat nichts genutzt.

Kleine Gemeinheit von Atmel, Pending-Bits löscht man durch Setzen. In 
diese Fallgrube tappt jeder Programmierer mal.
Nebenfallgrube daraus:
Setzen darf man nicht mit OR, da dann alle Pending-Bits im selben 
Register mit gelöscht werden. Man darf daher nur mittels Zuweisung oder 
AND löschen.

Andere Möglichkeit: Du kannst den Timer auch einfach anhalten.
#5155700
Lesenswert?

Route 6. schrieb:
> Das verstehe jetzt wer will. Gerade mit OR wird doch nur das
> betreffende Bit gesetzt, und alle anderen bleiben unbeeinflusst!

Das ist eine Read-Modify-Write Operation. Das Byte wird also gelesen, 
bearbeitet und wieder geschrieben.

Steht z.B. 0000 0011 drin und du veroderst mit 0000 0001, weil du Bit0 
löschen willst, wird danach 0000 0011 drauf geschrieben. Und das löscht 
beide Bits. Schreibst du direkt 0000 0001 drauf, wird nur Bit0 gelöscht.

Ist halt kein normales Register.
OP (Firma: Neutron Mikroelektronik GmbH) #5155899
Lesenswert?

Danke an alle für die Beiträge,

der Vorschlag mit dem Anhalten des Timers von Peter Dannegger war für 
mich die Lösung.

Ich hatte zwar auch schon daran gedacht, war aber irgendwie der Meinung, 
man könne die Timer nicht unabhängig voneinander anhalten. Weiß auch 
nicht, wie ich darauf kam. Dabei muss man ja nur den Prescaler 
entsprechend setzen.

Vielen Dank auf jeden Fall

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