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!
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?
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?
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?
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.
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.
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()
Erstmal vielen dank für eure Antworten! werde es jetzt so probieren, das ich den Timer TCCR2=0x00 setzen werde!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.