Verständnisproblem bei Interrupts

Gast #1127982
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!
#1127988
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!
Gast #1127989
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?
Gast #1127992
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?
Gast #1127999
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.
#1128005
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.
#1128013
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()

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