Forum: Mikrocontroller und Digitale Elektronik Hilfe INT0 u. INT1


von Merle (Gast)


Lesenswert?

Hallo wi kann ich arbeite mit AVR studio yaap und dem AT90S4433 wie kann
ich folgendes machen??
________________________________________________________
.include "4433def.inc"

.def temp = r16

.org 0x000
         rjmp main  ; Reset Handler
.org INT0addr
         rjmp a1    ; IRQ0 Handler
.org INT1addr
         rjmp a2    ; IRQ1 Handler


main:                         ; hier beginnt das Hauptprogramm



         ldi temp, 0b00001010  ;INT0 und INT1 konfigurieren
         out MCUCR, temp

         ldi temp, 0b11000000  ;INT0 und INT1 aktivieren
         out GIMSK, temp

         sei                   ;Interrupts allgemein aktivieren
_________________________________________________________________

Wi kann ich das machen wenn jetzt oben steht das mit a1 und a2 wie kann
ich das in weiter unten stehenden programmen mit z.B.mit a3 und a4
verwenden wenn ich es hinunterkopiere dann zeigt mein assemblerstudio
error an. wie kann ich das machen das es auch bei weiteren programmen
mit anderen a Zahlen (a3-a4-a5-a6-.....) funktioniert ohne
fehlermeldung??

Mfg.merle

von thkais (Gast)


Lesenswert?

Ähm, also meine Wahrsagerkugel sagt mir nicht viel.
Könnte es sein, daß Du den INT0 / INT1 mehrfach für verschiedene
Aufgaben verwenden möchtest?
Erklär bitte mal genau, was Du mit a3-a4-a5... meinst - ich kann Dir
leider nicht so richtig folgen.

von Merle (Gast)


Lesenswert?

Ja ich will ihn mehrfach für verschiedene auf gaben benutzen.

mit a1-a2 usw. mein ich nur das programm zu dem man mit tastendruck
springt.

von Tobias Breckle (Gast)


Angehängte Dateien:

Lesenswert?

wenn ichs jetzt richtig verstehe meinst du das du zb 5 taster hast und
wenn einer davon gedrückt wird soll dein programm einen interrupt
auslösen, oder??

wenn ja dann hier mal nen vorschlag per anhang (haut mich wenns so
nicht geht).

bei tastendruck eines tasters wird nun der interrupt ausgelöst. im
interrupt dann kannst du prüfen welcher port gedrückt wurde. (dioden
sind da damit der strom nicht an allen ports anliegt.)

von Merle (Gast)


Lesenswert?

ne ich mein es so:
Ich habe 2 Taster einen an INT0 und einn an INT1 und so solls später
funzen:

_______________________________________________
der 1. INT0-INT1 code mit a1 und a2

dann das dazugehörige Program

dann a1

dann a2

jetzt das 2. INT0-INT1 code mit a3 und a4

dann das dazugehörige Programm

dann a3

dann a4

usw. bis a10
______________________________________________

also weist du zufällig wie das funzen könnte???

von thkais (Gast)


Lesenswert?

Da gibts mehrere Möglichkeiten.
1. Du machst eine zusätzliche Fallunterscheidung. Beispiel:

int0:
     cpi register,$01
     breq a1
     cpi register,$02
     breq a2
     cpi register,$03
     breq a3
usw.
in den jeweiligen a1,a2,a3... muß dann "register" so definiert
werden, daß der nächste Sprung richtig ausgeführt wird.

2. Nutzung eines Registers als "Flag".

int0:
    sbrc register,0
    rjmp a1
    sbrc register,1
    rjmp a2
    sbrc register,2
    rjmp a3
etc.

Hier müssen die entsprechenden Bits gesetzt/rückgesetzt werden.


3. Du benutzt den Befehl "ijmp".
Im Z-Register (R30 / R31) kann man eine Sprung-Adresse hinterlegen.
Da Du allerdings int0 und int1 verwendest, bräuchtest Du zwei getrennte
Sprungadressen, leider gibts nur eine.

Was für ne komplizierte Sache hast Du denn vor? Eventuell läßt sich das
auch anders lösen. Die obigen Vorschläge haben nämlich einen Nachteil:
Wenn man nicht aufpaßt, insbesondere bei ijmp, dann kommt es zu
unvorhersehbaren Auswirkungen und man sucht sich tot nach dem Fehler im
Prog....

von Peter (Gast)


Lesenswert?

hi merle,
wenn ich dich richtig verstanden habe willst du andere routinen bei den
interrupts anspringen.

das geht nicht direkt, du kannst den flashspeicher während der laufzeit
nicht verändern, die sprungtabelle liegt an einer festen adresse in
flash.

du kannst allerhöchstens in der interrupt-routine eine entscheidung
treffen und dann nochmal zur richtigen funktion springen.

am einfachsten wohl so: dein hauptprogramm für den jeweiligen
Programmteil legt die Adressen der gewünschten interrupt-routine in 2
16-bit variablen ab. in der interruptroutine den wert ins z-register
schieben und dann mit ijmp verzweigen.

Peter

von Merle (Gast)


Lesenswert?

hallo thkais wie mach ich das bei der 1. Möglichkeit ich bin noch
Anfänger???

Mfg. Merle

von Merle (Gast)


Lesenswert?

Ich mein das so:
__________________________________________
INT0-INT1 Programm1.

Dazugehöriges Programm das bei drücken von INT0 auf a1 und INT1 auf a2
springt.

dann a1

dann a2

INT0-INT1 Programm2.

Dazugehöriges Programm das bei drücken von INT0 auf a3 und INT1 auf a4
springt.

dann a3

dann a4

usw bis a10
__________________________

von thkais (Gast)


Lesenswert?

Woher weiß der Controller, ob er Progamm 1 oder 2 ausführen soll?

von Jens Renner (Gast)


Lesenswert?

Sehe ich das richtig, dass bei erstmaliger Aktivierung von INT0 a1
angesprungen werden soll, bei der zweiten a3, bei der dritten a5 usw.?
Und entsprechend 1. Mal INT1 -> a2, 2. Mal a4, 3. Mal a6 usw.

Wenn das der Fall ist, würde ich zwei allgemeine Interrupthandler
nehmen, und dort wird jeweils eine Variable für jede Aktivierung
hochgezählt (darf natürlich nicht außerhalb des Handlers verändert
werden).

Am einfachsten (aber auch am wenigsten elegant) wäre dann eine
Fallunterscheidung. Kann man vielleicht auch besser lösen.

von Merle (Gast)


Lesenswert?

hallo jens renner wie mach ich so eine Fallunterscheidung und wie führe
ich sie in einem Programm aus??

Mfg. Merle

von Merle (Gast)


Lesenswert?

hallo kannst du mir jetzt sagen wie das funzt??

von Peter D. (peda)


Lesenswert?

Interrupts kann man nicht drücken.

Wenn Du mit Drücken aber Tasten meinst, dann suche mal nach "Tasten
abfragen und entprellen". Nicht ohne Grund, wirst Du dafür viele
Beispiele und Erklärungen finden, weil da eben sehr oft falsch
rangegangen wird.


Am besten aber, Du schaltest erstmal den PC aus, nimmst Papier und
Bleistift und machst Dir erstmal ein Konzept (Programmablaufplan).

Dann ist es nämlich milliardenfach leichter, dieses in ein Programm
umzusetzen. Eventuell kann dann auch einer von uns verstehen, was Du
eigentlich machen willst.

Einfach drauf los zu schreiben führt nur zu dem gefürchteten
Spaghettikode, d.h. lange Arbeit, wenig Überblick, viele Fehlerquellen
und Frust.


Peter

von Jens Renner (Gast)


Lesenswert?

Hey Merle,

erstmal den Ball flachhalten. Durch mehrfache Aufforderung lese ich den
Beitrag auch nicht eher.
Du kannst Dir sicher sein, ich äußere mich schon, wenn ich was zu sagen
habe. Zum Beispiel jetzt :-)
Ein möglicher Interrupt-Handler könnte so aussehen:


int0_handler:
  ; SREG sichern etc.

  ; int0counter vor dem ersten aufruf mit 0 initialisieren
  cpi int0counter, 3 ; max. anzahl der versch. routinen erreicht?
  brne int0_handler_a1 ; wenn nicht, mache weiter
  clr int0counter ; sonst setze zähler zurück

  ; ab hier fallunterscheidung
int0_handler_a1:
  cpi int0counter, 0
  brne int0_handler_a3 ; nicht zu a1? dann prüfe a3
  rcall a1
  rjmp int0_handler_end

int0_handler_a3:
  cpi int0counter, 1
  brne int0_handler_a5 ; nicht zu a3? dann prüfe a5
  rcall a3
  rjmp int0_handler_end

int0_handler_a5:

  ; ... hier fortsetzen

int0_handler_end:
  inc int0counter ; erhöhe zähler

  ; SREG wiederherstellen
reti



Jens

P.S.: Und beherzige Peters Ratschlag.

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
Noch kein Account? Hier anmelden.