Forum: Mikrocontroller und Digitale Elektronik USART INT in Timer ISR deaktivieren


von Dennis Kleine-Beck (Gast)


Lesenswert?

Hallo,

ich nutze bei nen MEGA16 timer1 (100Hz/10ms) Compare Match A interrupt
und parallel die USART (nur RX) im Interruptbetrieb @ 19200bps. Nun
würde ich gerne in der Timer-ISR den USART RXCIE (bzw. USART komplett)
deaktivieren, da dieser offenbar mit dem Auslesen des ADC in der Timer
ISR nicht harmoniert.

Also schreibe ich in der Timer ISR:

void timer (void)
{
  //...

  UCSRB |= ((0<<RXCIE)|(0<<RXEN)|(0<<TXEN)); // stopp USART

  //...
}

Zu meinem Erstaunen stoppt die USART aber nicht, sondern generiert
munter weiter Interrupts beim Empfang eines Zeichens.

Wo liegt mein Denkfehler?

(Umgekehrt kann ich mit "TCCR1B = 0x00;   // stopp timer: no CTC1,
CK/1   -- Stopp timer1" in der USART ISR den Timer wunderbar
stoppen!)

Danke!

Gruß,
Dennis

von Axel R. (Gast)


Lesenswert?

Hallo Dennis, geht andersrum
etweder analog zum Timer mit
UCSRB = 0x00;
oder mit LÖSCHEN der Bits im Register UCSRB.
mit "|=" setzt du die Bits mit "~=" werden diese gelöscht.
Allerdings  dann auch mit dem Bitkomplement. (Ich kann das nicht
erklären)
Sieh mal hier nach Bitmanipulation:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Schreiben_von_Bits

von johnny.m (Gast)


Lesenswert?

> ...Auslesen des ADC in der Timer ISR...

Wenn ich so was lese, werde ich sofort hellhörig. Frage mich oft, warum
es einen ADC-Interrupt gibt, weil ihn ja anscheinend niemand benutzt:-?
Wenn ich das richtig vermute, liest Du den ADC nicht nur in der
Timer-ISR ein sondern startest ihn wahrscheinlich auch und wartest bis
er fertig ist. Vielleicht liege ich da ja komplett falsch, aber wenn
dem so wäre, solltest Du nicht den UART-Interrupt in der Timer-ISR
deaktivieren, sondern dein Programm umbauen und den ADC-Interrupt
nutzen. Wenn Du in der Timer ISR irgendwelche Warteschleifen hast,
verwundert es überhaupt nicht, wenn da was 'nicht harmoniert'.

von Axel R. (Gast)


Lesenswert?

ähmm
mit "&=" werden die gelöscht. steht ja auch so im Tutorial.

..offenbar mit dem Auslesen des ADC in der Timer
ISR nicht harmoniert.
..

stimmt, habe ich garnicht bemerkt.
Du kannst den ADC Timer1 als Quelle angeben, wenn mich nicht alles
täuscht. Dann wird beim TimerOverflow automatisch der ADC gestartet und
in der ADComplete ISR kannst Du den Wert aus adch+l ablegen.

von Dennis Kleine-Beck (Gast)


Lesenswert?

Hallo,

danke für die Antworten, werde morgen mal testen.

> Vielleicht liege ich da ja komplett falsch

Ja, so ist es.

> Wenn Du in der Timer ISR irgendwelche Warteschleifen hast

HUST also, ich muss doch sehr bitten! Und ja, ich lese ADC komplett
und als 16 Bit-Wert ein ;-)

Ich brauche halt einen stabilen 100Hz Hertbeat. Damit steht und fällt
alles.

> Dann wird beim TimerOverflow automatisch der ADC gestartet

Das wär evtl. 'ne gute Sache! Werde mal schauen. Danke, Axel!

Ciao,
Dennis

von johnny.m (Gast)


Lesenswert?

Sorry, war ja nur ne Vermutung. Solche Sachen lese ich hier oft und
meist ist es genau das, was dafür sorgt, dass das Programm nicht
funktioniert...

Das was Axel vorgeschlagen hat, nennt sich ADC Auto Trigger und ist ne
echt feine Sache.

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.