mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmel 8051er zwischen Interrupts Prioritäten wechseln geht das


Autor: Ertan Metin (drbrain)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen !

ich hätte eine ganz einfache Frage, die mir seit ein paar Tagen den Kopf 
zerbricht.

Mein Frage lautet ist es mit dem Atmel AT89C51ED2 möglich zwischen zwei 
Interrupts Prioritäten während einer Interrupt Service Routine zu 
wechseln ?

unten habe ich ein Lauflicht programmiert der durch den externen 
Interrupt(lsbzumsb auf Port 2) 0 oder Interrupt1(msbzulsb auf Port 2) 
ausgelöst werden kann die höhere Priorität ist auf den externen 
Interrupt 1
gesetzt.

wenn mann P3.2 drückt fängt das Lauflicht vom lsb zu msb sich zu bewegen
da der P3.3 die höhere Priorität hat wird die ISR2 ausgelöst wenn man 
P3.3 drückt und das Lauflicht fängt dann an sich vom msb zu lsb zu 
bewegen jedoch kann ich jetzt nicht den Interrupt0 P3.2 (lsbzumsb) 
auslösen weil der Interrupt 1 die höhere Priorität hat. Was kann ich 
bzw. muss ich machen damit die sich höhere Prioritäten im ISR sich 
switchen : einmal die Priorität 3 für EX0 und einmal für EX1 !



mov IPL0,#00000100b  Priorität 3 für EX1
mov IPH0,#00000100b  Priorität 3 für EX1





include C51ED2.inc

code at 0
sjmp init


isr1:
org 003h
push acc
push psw
call lsbzumsb
pop acc
pop psw
reti


isr2:
org 0013h
push acc
push psw
call msbzulsb
pop acc
pop psw
reti


lsbzumsb:
mov r3,#150
sprung3:
mov p2,a
call zeit
RL a
djnz r3,sprung3
ret


msbzulsb:
mov r4,#150
sprung4:
mov p2,a
call zeit
RR a
djnz r4,sprung4
reti


init:
mov IPL0,#00000100b
mov IPH0,#00000100b
mov a,#1
setb IT0
setb IT1
clr IE0
clr IE1
setb EX0
setb EX1
setb EA

zeit:
mov r1,#200
sprung2:
mov r2,#200
sprung1:
djnz r2,sprung1
djnz r1,sprung2
ret


haupt :

sjmp haupt

end.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja man kann die Priorität jederzeit ändern.

Der 8051 hat eine äußerst clevere und einfache Methode, die Prioritäten 
zu verwalten.
Für die 4 Prioritäten sind nur 4 Bits nötig.
Die Priorität wird beim Interrupteintritt ausgewertet und setzt das 
entsprechende Bit. Jedes RETI löscht dann wieder genau ein Bit, das 
höherwertige zuerst.

Wenn man nun in einem Interrupt seine eigene Priorität erhöht, muß das 
unmittelbar vor dem RETI geschehen, sonst kann es passieren, daß man 
sich selbst unterbricht (2 Instanzen des Handlers).


So und nun die schlechte Nachricht, das wird Dir bei Deinem Problem 
nicht das geringste helfen.

Interrupts sind dazu da, daß man nur kurz darin verweilt und sein Ding 
macht. Du willst aber für immer drin bleiben und das geht nicht.

Du mußt also Deinen Programmablauf nochmal neu überdenken.


Interrupts sind auch generell keine gute Methode, Tasten abzufragen, da 
Tasten prellen.


Peter

Autor: Ertan Metin (drbrain)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo erstmal vielen dank für die schnelle Antwort !
die Verwaltung von Prioritäten werden bei mir über mov IPL0,#00000100b
mov IPH0,#00000100b gesetzt, die Entprellung kann ja über eine 
Zeitverzögerung  kompensiert werden.
Wenn Sie mir vielleicht ein Programmbeispiel zeigen könnten
wäre ich Ihnen sehr verbunden.


Mit freundlichen Grüßen

Ertan

Autor: Bruno (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Ertan,

setze in den Interrupts doch einfach nur bits sozusagen als Flags, z.B.:

isr1:
org 003h
setb ($2F).0
clr ($2F).1
reti

isr2:
org 0013h
clr ($2F).0
setb ($2F).1
reti


Im Initialisierungsteil löschst du die beiden Flags:

init:
...
clr ($2F).0
clr ($2F).1


Den eigentlichen Aufruf von lsbzumsb und msbzulsb erfolgt dann im 
Hauptprogramm anhand der Flags:

haupt :

jnb ($2F).0,keinlsbzumsb
call lsbzumsb

keinlsbzumsb:
jnb ($2F).1,keinmsbzulsb
call msbzulsb

keinmsbzulsb:

sjmp haupt


Wenn Du sofort umschalten können willst, mußt Du die Schleifen noch 
abbrechen können:

lsbzumsb:
clr ($2F).0
mov r3,#150
sprung3:
mov p2,a
call zeit
RL a
jb ($2F).1,Endelsbzumsb
djnz r3,sprung3
Endelsbzumsb:
ret


msbzulsb:
clr ($2F).1
mov r4,#150
sprung4:
mov p2,a
call zeit
RR a
jb ($2F).0,Endemsbzulsb
djnz r4,sprung4
Endemsbzulsb:
reti

Wenn ($2F).0 gesetzt ist (durch isr1), dann wird lsbzumsb aufgerufen.
Wenn ($2F).1 gesetzt ist (durch isr2), dann wird msbzulsb aufgerufen.

Hab's nicht ausprobiert, aber ich hoffe, es funktioniert...

Viel Glück,

Bruno

Autor: Ertan Metin (drbrain)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo erstmal vielen dank für eure schnelle Antwort .

die Idee ist super jedoch kann ich mit den Flags nichts anfangen da der 
Compiler diese Syntax nicht erkennt setb ($2F).0 ! ? bitte um Hilfe !


MfG Ertan

Autor: E. B. (roquema) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welcher Compiler? Das ist doch Assembler. Welchen benutzt Du denn?
Im RAM ist der Bereich 20h bis 2Fh bitadressierbar.
(Siehe Datenblatt bzw. 8051 Hardwarebook)
Will man ein Bit davon nutzen, schreibt man das entspr. Bit hinter die 
Adresse der Speicherzelle z.B.
2F.0h 1.Bit (niederwertigstes) der Speicherzelle 2Fh im RAM
2F.1h 2. Bit    "
usw.

Wie die Syntax genau bei deinem Assembler aussieht musst Du im Manual 
nachsehen.
Probier mal: clr 2F.0h bzw. setb 2F.0h

Autor: Ertan Metin (drbrain)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo :-))

ich benutze den RIDE51 RAISONANCE Kit !

setb 2F.0h bzw. 2F.0h akzeptiert der Compiler nicht aber setb 2Fh 
compiliert er ohne Probleme ?



MfG

Ertan

Autor: Bruno C. (bruno)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Ertan,

leider kenne ich Deinen Compiler nicht, in meinem ist die Syntax wie ich 
oben beschrieben habe, z.B. ($2F).1

Wenn das bei Dir nicht funktioniert, dann nimm anstelle eines Bits ein 
ganzes Byte als Flag, z.B. nimmst Du 30h anstelle von ($2F).0 und 31h 
anstelle von ($2F).1 und weist denen entweder 0 oder 1 zu. Dann werden 
nur die Sprünge etwas umständlicher, aber Du könntest den jew. Wert in 
den Akku kopieren und dann jz bzw. jnz benutzen.

Also anstelle von

   clr ($2F).0    bzw.    setb ($2F).0

schreibst Du

   mov 30h,#0     bzw.    mov 30h,#1

und anstelle von

   jb ($2F).0,Endelsbzumsb

schreibst Du dann

   mov A,30h
   jnz Endelsbzumsb

bzw. aus

   jnb ($2F).0,keinmsbzulsb

wird dementsprechend

   mov A,30h
   jz keinmsbzulsb

Dann mußt Du aber ggf. den Akku retten, wenn Du ihn irgendwo sonst in 
Deinem Programm ebenfalls benutzt (Push ACC und Pop ACC).

Apropos push und pop, mit fällt da gerade noch etwas auf: In Deinen 
Interrupt Serviceroutinen rettest Du den Akku und das PSW, aber Du mußt 
darauf achten, sie in umgekehrter Reihenfolge vom Stack zurückzuholen, 
wie Du sie hinaufschiebst. Du hast

push acc
push psw
call lsbzumsb
pop acc
pop psw

geschrieben, es müßte aber

push acc
push psw
call lsbzumsb
pop psw
pop acc

sein. Das ist sehr wichtig, denn ansonsten findet sich der Inhalt des 
Akkus anschließend im PSW wieder und umgekehrt. Allerings brauchst Du 
Akku und Prozessorstatuswort nur dan zu retten, wenn Du es auch 
veränderst, ansonsten kannst Du die Befehle weglassen.

Viel Spaß mit Deinem Projekt,

Bruno

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.