mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interrupt-Vektoren


Autor: TomTom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich beschäftige mich z.Z. intensiv mit einem Drehimpulsgeber den ich an
die beiden Interrupt Eingänge meines Atmega16 angeschlossen habe.

Habe programmiertechnisch soweit alle fertig, nur will es halt nicht so
laufen wie ich mir das vorstelle.

Irgendwie komme ich jetzt nicht so ganz klar mit den Ablauf eines
Interrupts.

Mein Programm ist nach dem folgende Schema aufgebaut:

1.Stack einrichten
2.PortD Eingang (Drehimpulsgeber)
3.PortC Ausgang (LC-Display)
4.Into & Int1 enablen
5.LCD INIT
6.LCD CLEAR

dann kommen die
Interrupt Vektoren
------------------
7.rjmp  reset2
  rjmp  Int0
  rjmp  Int1


reset2:
  Ausgangszustand Drehimpulsgeber ermitteln
        Interrupts erlauben (sei)

main:
        (HP)
        rjmp main


INTO:
       (Auswertung Drehrichtung)
INT1:
  (Auswertung Drehrichtung)

ENDE


Das Hauptpogramm funbktioniert ohne die Interruptroutine einwandfrei.
Nur wenn ich meine Routine einbau und ich den Drehgeber drehe. Flackert
das LCD und zeigt wirres zeug.

Frag ist : liegt es jetzt generell am Ablauf des kompletten Programms
mitsamt dem Interrupt ?



Wenn der Ablauf denn so stimmt muss es ja an der Routine selber liegen.

Autor: Niels Hüsken (monarch2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Auto steht in der Garage und springt nicht an. Liegt das jetzt am
nicht eingeschaltetem Licht oder an den Kaninchen, die meine Tochter im
Garten züchtet.


Man gebe mir eine Glaskugel, mal sehen, was sich machen lässt.

Autor: Kai (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuch mal den Drehimpulsgeber nicht mit Interrupt auszuwerten. Frag
ihn einfach in nem Abstand von z.B. 1 ms ab...

Kann es vlt. auch sein, dass du die Interruptvektoren an der falschen
Adresse angegeben hast?

MFG

Kai

Autor: Kai (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe gerade in meiner Datenblatt-Sammlung etwas über Drehimpulsgeber
gefunden.
Da kann man lesen(sehen): Entprellen!!!
Und zwei Flußdiagramme zur Abfrage mit µC. Einmal jede ms, das andere
mir Interrupt.

MFG

Kai

Auszug aus Datenblatt angehängt...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Programm ist nach dem folgende Schema aufgebaut:
>
> 1.Stack einrichten
> 2.PortD Eingang (Drehimpulsgeber)
> 3.PortC Ausgang (LC-Display)
> 4.Into & Int1 enablen
> 5.LCD INIT
> 6.LCD CLEAR
>
> dann kommen die
> Interrupt Vektoren
> ------------------
> 7.rjmp  reset2
>   rjmp  Int0
>   rjmp  Int1

Wie muss ich das jetzt interpretieren?
Du kannst die Interruptvektoren nicht einfach
dorthin schieben wo's Dir passt. Die muessen
ganz am Anfang stehen.
Datenblatt lesen.

Autor: TomTom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@alle: Danke für die Hilfe.....

@Karl Heinz

Danke, genau das wollte ich wissen.

Die müssen also ganz am Anfang stehen. Ich habe wohl an der falschen
stelle im Datenblatt geschaut ("External Int" anstatt "Interrupts"
Kapitel schäm)....
Ich habe es aber jetzt gefunden. DAnke


Trotzdem noch ne Frage:

Was passiert nachdem der Interrupt Vektor nach einem INT durchlaufen
ist ?
fängst dann wieder bei Reset an oder da wo ursprügnlich die
Unterbrechung war ?
Ich hab natürlich mit Push und Pop das SREG und andere Register
gesichert.

Autor: Kai (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Am Ende deiner Interruptroutine muss ein RETI stehen. Damit springt der
Controller wieder an die Stelle im Programm zurück, an welcher er in
den Interrupt gesprungen ist. Beispiel:

rjmp   reset2
rjmp   Int0
rjmp   Int1

... weiterer Code ...

Int0:               ; Start der Interrupt Routine
     push    SREG   ; Register sichern
     push    XYZ

     ... viel Code für Interrupt ...

     pop     XYZ    ; Register wieder herstellen
     pop     SREG

     reti           ; Interrupt verlassen und weiter um Hautprogramm

MFG

Kai

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein.
Ein Interrupt ist wie ein normaler CALL (*), nur dass der
Unterprogrammaufruf eben nicht durch einen Assemblerbefehl
ausgeloest wird, sondern durch irgendein Ereignis. Daher
muessen die Vektoren auch auf definierten Stellen stehen.
Bei einem normalen CALL gibt man ja die Adresse an an die
gesprungen werden soll. Bei einem externen Pin, der ein
Spannungssignal kriegt, geht das aber nicht. (**)

(*) Im Prinzip. Im Detail gibt es natuerlich Unterschiede.
RETI statt RET verwenden. Waehrend ein Interrupt abgearbeitet
wird, sind andere Interrupts automatisch gesperrt. ...

(**) Zumindest nicht auf einem AVR. Auf anderen Prozessoren
geht das sehr wohl, dann braucht man aber eine zusaetzliche
Hardware: einen Interruptcontroller.

Autor: Olaf_K (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

noch eine kleine Falle: Die Interrupttabelle beim Mega16 besteht aus 2
Worten pro Eintrag, sollte also aus JMPs bestehen, nicht RJMPs. Das
wird so gemacht, da man bei AVRs mit mehr als 8K Flash sonst nicht den
ganzen Adreßraum anspringen könnte. Siehe Datenblatt.

MfG Oil

Autor: TomTom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok..danke

So noch mehr Newbie fragen .....

Den Befehl "sei", den kann ich doch hinsetzten wo ich möchte oder ?
Ich möchte nämlich erst zu einen bestimmten Zeitpunkt im Programm einen
Interrupt erlauben.

Im GICR habe ich zuvor die Ints enabled. Das ist doch korrekt oder ?

Autor: Kai (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Oli
Danke, ich denke da hat bisher auch noch keiner dran gedacht! Habs auch
erst gesehen, als ich deine Antwort gelesen hab.

Autor: TomTom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Olaf


Aha...das ist ja mal interressant.
Das habe ich im Datneblatt nicht gesehen

Autor: TomTom (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Habe mal meine main.asm angehängt.

Könnt ihr euch ja mal anschaun.... ;)

Autor: Kai (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde mal die von Olaf angesprochene Sache mit den
Interruptverktoren ändern. Sonst fällt mir auf den ersten Blick nichts
auf - habs nur kurz überflogen.

MFG

Kai

Autor: Christoph Kessler (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Meine Drehgeberroutine hab ich auch mal angehängt, ist vielleicht etwas
kompakter

Autor: TomTom (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Dankeschön, aber ich bekomm diesen Code auch nicht am laufen.

Ich verzweifel hier schon.

Ich möchte auf meinem Display einfach, zum testen, zwei Wert von 0-9
einstellen können.

Ich kann beim Druck auf die Achse zwischen den Werten hin und her
springen (Cursor springt, Cursor blinkt).
Sobald ich aber drehe funktioniert nix mehr.
Es soll doch einfach nur Decrement oder Increment ausgeführt werden,
den neuen Wert auf dem Display angezeigt werden und danach soll
entweder auf einen Interrupt oder auf den nächsten Tasterdruck gewartet
werden.

Kann es an den Fusebits liegen ? (BOOTRST)
Oder an IVSEL ?
Oder leigt es daran wann und wo ich mit dem Befehl "SEI" die
Interrupts erlaube ?

Ich habe mal den Quellcode angehangen....

Über ein paart Tipps freue ich mich sehr....

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Christoph Kessler: Was is dasn fürn Quatsch? Der Peter Danegger hat in
der Codesammlung einen C-Code liegen der wesentlich kürzer ist. Sollte
ohne Probleme auf ASM portierbar sein.

Autor: Kai (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo TomTom,

wie Olaf oben schon gesagt hat, solltest du die Sprungbefehle von rjmp
in jmp ändern (in der angehängten Datei noch nicht geschehen!).
Bei den Fusebits musst du nur darauf achten, dass deine Reset- und
Interruptvektoren nicht in den Bootbereich verschoben werden. BOOTRST
sollte unprogrammed sein (= 1) und IVSEL sollte = 0 sein. Siehe S.44
Tabelle 19 und S.45.

MFG

Kai

Autor: TomTom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohhhh man.......


Ich habe natürlich alle Rjmps geändert, ausser die Sprünge für die
Vektoren selber, ich depp.....

Jetzt gehts.......


SUPER

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die jumps im code kannst du als rjmp lassen. aber die befehle für die
vektoren müssen jmps sein.

Autor: TomTom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Frage habe ich noch :


Wie kann ich das Int Eingänge wieder ausschalten wenn ich keinen
Interrupt mehr zulassen möchte ?

Autor: Kai (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst entweder alle Interrupts mit CLI ausschalten oder im GICR die
Bits 6 und 7 wieder auf 0 setzen. Wenn du nur die Int Eingänge
verwendest, würde ich den CLI Befehl verwenden.

MFG

Kai

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da kaum ein sinnvolles Programm ohne Timer-Interrupt auskommt, ist es
wohl besser, die Enable-Flags in GICR zurückzusetzen.

...

Autor: Kai (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Hannes: Betonung auf NUR!

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.