www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Verständnisproblem bei Interrupts


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: AuchnurGast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AuchnurGast wrote:

> kann aber auch sein, dass ich da jetzt vollkommen falsch liege.

Mit Teil 1 (lass das Zeugs in Ruhe, darum kümmert sich der Compiler) 
liegst du richtig.
Mit Teil 2 liegst du falsch.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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()

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erstmal vielen dank für eure Antworten! werde es jetzt so probieren, das 
ich den Timer TCCR2=0x00 setzen werde!

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.