Interrupt priorität

Gast #130712
Lesenswert?
• ▲
▼
Hallo zusammen


Ich habe ein ATmega8515 auf meiner Platine der zwei interrupts auslöst.
Ein Timer0 interrupt der 5 LED'S ansteuert und ein USART
Empfangsinterrupt, die ausgelöst wird wennn Daten vom PC gesendet
werden.(Ich sende 255 Byte (Datenpacket)an Daten an den µC).
Mein Problem ist wenn ich Daten vom PC aus sende stört mein Timer
Interrupt den USART Interrupt und ich kann die Daten nicht richtig
empfangen!?!?!. (Liegt wohl daran das der Timer INT höhere Priorität
hat und ziemlich schnell durch läuft).
Meine Frage:
Kann ich den TImerInterrupt solange aussetzten bis mein Empfang zu Ende
ist?
Gast #130716
Lesenswert?
• ▲
▼
Du kannst auch genau den einen Timerinterrupt über sein EnableBit im
entsprechenden Steuerregister abschalten, wenn dir CLI und SEI nicht
passen. Du verlierst damit halt aber die entsprechenden Aufrufe...
Gast #130717
Lesenswert?
• ▲
▼
@tobi
"ist eigentlich standard in der int routine die ints auszuschalten"
????
Was soll das denn? Allenfalls schaltet man sie gelegentlich an, um
anderen Ints zu ermöglichen, die gerade laufende ISR ebenfalls zu
unterbrechen.
Bei Annahme eines Int wird von der Hardware das i-flag von der Hardware
gelöscht, damit können erstmal andere Ints nicht dazwischen babbeln. Bei
reti wird es wieder gesetzt.
Gast #130719
Lesenswert?
• ▲
▼
@Thomas: auch das ist nicht ganz korrekt. Wird das TOIE0 gelöscht, wird
erstmal kein Timer0-Int mehr ausgeführt, bei Überlauf des Timers aber
schon das T0OV-Bit gesetzt. Wird TOIE0 wieder gesetzt, wird sofort der
noch anhängige Timer0-Int ausgeführt. Verlieren wird man erst was, wenn
eine neuer Int auftritt, bevor der alte bearbeitet wurde - der ist dann
wirklich futsch. Klingt alles haarspalterisch, ist es aber nicht.
Gast #130725
Lesenswert?
• ▲
▼
während einer interrupt-routine ist das i-flag im sreg gelöscht, d.h.
niemand kann während dieser routine dazwischenfunken.. deswegen gibt es
auch den befehl "reti", weil der den interrupt wieder setzt..

bei 2 interrupts kannste die recieve-routine einfach lassen und bei der
timer-routine einfach am anfang ein "sei" reinhauen, dann könnte der
recieve den timer unterbrechen.. damit wäre die priorität schon einmal
erhöht (entsprechend kann der timer NICHT den recieve unterbrechen)

eine richtige irq-hierarchie gibts ja nischt, oder erzähl ich
scheibenkleister?

dave
Gast #130726
Lesenswert?
• ▲
▼
Eine recht einfache Methode ist, deie Interruptroutine so schnell wie
möglich zu verlassen und den eigentlich zur Interruptroutine gehörigen
Programmteil als call weiterlaufen zu lasse.
Zu beachten ist dabei, das die abzuarbeitende Routine nicht zu lange
dauert.

Also etwa so

einsprung_von_interruptabelle:
  ldi temp1,low(interrutservice)
  push temp1
  ldi temp1,high(interruptservice)
  push temp1
  reti    ;Interruptfreigabe, alle einkommenden Interrupt werden
akzeptiert
interruptservice:
  nop    ;die eigentliche Interruptroutine
  nop
  ret
Gast #130729
Lesenswert?
• ▲
▼
Reti auf Ret umändern?? - Das wird wohl nix. Jedenfalls nicht dann, wenn
man zu Beginn der ISR das SREG (mit gesetztem I-Flag) gesichert hat und
es vor dem RET(I) wiederherstellt. Dann ist das I-Flag nämlich wieder
gesetzt und erfordert RETI... 8-D

Aber zwischendurch haben andere (möglichst kurze) ISRs Vorrang. Diese
sollten das SREG allerdings separat sichern.

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