Verständnisproblem bei Interrupts

Gast #1127982
Hallo zusammen,
habe folgendes Problem mit Interrupts!
Ich habe ein Programm geschrieben, welches einen externen Timer benutzt, 
dieser Timer hat einen Timer overflow interrupt, der auch einwandfrei 
funktioniert. Zusätzlich, habe ich auch eine Interruptroutine, die 
ausgelöst wird, wenn ein Bit über die USART0 geschickt wird. Jetzt würde 
ich gerne alle Interrupts ausschlaten, also auch den timer anhalten, 
aber mit der Routine aus dem ARV-gcc-tutorial läuft der Timer immer 
noch! Jedoch ist die USART0 Interrupt routine ausgeschlatet, wie kann 
das sein?

Programmiert habe ich es wie im Beispiel!
cli()
aufruf funktion


Funktions Kopf
uint8_t tmp_sreg=0;
tmp_sreg=SREG
cli();

nicht unterbrechbarer code
MCUCSR |= (1<<JTD);
MCUCSR |= (1<<JTD);

SREG = tmp_sreg;

wieder im hauptprogramm

dann habe ich noch eine Frage, wenn ich keine funktion verwende reicht 
es dann wenn ich so etwas programmiere?

void main()
{ programm code
   cli();
   tmp_sreg=SREG;

  nicht unterbrechbarer programm code

  MCUCSR |= (1<<JTD);
  MCUCSR |= (1<<JTD);

  SREG = tmp_sreg;

  sei();
}



oder geht das so nicht?
wäre für jede hilfe dankbar!
Gast wrote:

> ausgelöst wird, wenn ein Bit über die USART0 geschickt wird. Jetzt würde
> ich gerne alle Interrupts ausschlaten,

Interrupts global ein und ausschalten macht man mittels cli() und sei(). 
Soweit ist das korrekt

> also auch den timer anhalten,

Ob der Timer läuft oder nicht, hat nichts mit Interrupts zu tun.
Ein Timer tickt vor sich hin, sobald er einen Vorteiler gesetzt bekommen 
hat. Setzt du den Vorteiler wieder auf 0, macht auch der Timer keinen 
Mucks mehr.

> Funktions Kopf
> uint8_t tmp_sreg=0;
> tmp_sreg=SREG
> cli();
>
> nicht unterbrechbarer code
> MCUCSR |= (1<<JTD);
> MCUCSR |= (1<<JTD);
>
> SREG = tmp_sreg;

Lass um Himmels willen das SREG in Ruhe.
Prozessorregister gehen dich als C-Programmiere nichts an!
Gast
Wenn der timer aktiviert ist dann läuft der solange bis du ihn wieder 
ausschaltest (stoppst) egal ob du die IRQs freischaltest oder sperrst.
Btw. kann man über die usart nur ganze bytes (nicht einzelne bits) 
verschicken, oder?
Gast
Hast natürlich recht! Man kann nur Bytes über die USART schicken! Das 
heisst also, dass ich den Timer nicht über einen Stopp der Interrupts 
ausschalten kann? Aber ist diese Routine nicht ein Interrupt?
ISR(TIMER2_OVF_vect)
{
  time++;
}
Und wenn ich die Interrupt routinen stoppe dann kommt er trotzdem da 
rein?
Gast
Aber ist das nicht so im avr-gcc tutorial beschrieben, und speicher ich 
nicht das SREG register in einer Variablen, damit das Programm nacher 
wieder weiß wo es war?
Gast
Hallo,

du brauchst das sreg nicht zu sichern, da kümmert sich der µC selber 
drum.
Wenn du es in einer Variable sichern möchtest so müßte die Syntax meiner 
Meinung nach so lauten:

tmp_sreg:=sreg;

Sonst sicherst du den Inhalt der variablen in deinem SREG.

kann aber auch sein, dass ich da jetzt vollkommen falsch liege.
Gast wrote:
> Aber ist das nicht so im avr-gcc tutorial beschrieben, und speicher ich
> nicht das SREG register in einer Variablen, damit das Programm nacher
> wieder weiß wo es war?

Nein. Ist völliger Unsinn.

Lass Dinge in Ruhe, von denen du nichts weißt und (als C-Programmierer) 
auch nichts zu wissen brauchst. Du kannst es nur schlimmer machen wenn 
du dem Compiler ins Handwerk pfuscht.
Gast wrote:
> Das
> heisst also, dass ich den Timer nicht über einen Stopp der Interrupts
> ausschalten kann?

Welchen Teil des Satzes:
"Ein Timer läuft sobald er einen Vorteiler eingestellt hat"
verstehst du nicht?

> Aber ist diese Routine nicht ein Interrupt?
> ISR(TIMER2_OVF_vect)
> {
>   time++;
> }
> Und wenn ich die Interrupt routinen stoppe dann kommt er trotzdem da
> rein?

Das was du da hast, ist eine Interrupt Routine. Die kann ausgeführt 
werden, wenn das entsprechende Ereignis eintritt. In deinem Fall ist das 
Ereignis: der Timer läuft über.
Ein Timer der aber nicht zählt kann auch nicht überlaufen.
Kein Überlauf -> kein Interrupt Ereignis -> Funktion wird nicht 
angesprungen

Die anderen Möglichkeiten, wie man das Anspringen der Funktion 
verhindern kann (der Timer aber trotzdem imHintergrund weiterläuft) 
sind:
* Für jedes Interrupt Ereignis gibt es ein Bit in irgendeinem Register, 
welches gezielt nur dieses eine Interrupt Ereignis sperren oder 
freigeben kann
* Die globale Interrupt Freigabe mittels sei() bzw. cli()

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.