Forum: Mikrocontroller und Digitale Elektronik Interrupt löst nicht aus


von marco (Gast)


Lesenswert?

Hi,

mein Interrupt will einfach nicht auslösen.
Arbeite mit dem Mega16 und Assembler.
Hab ich da noch irgendwas vergessen?

  ldi temp, 0b1000000
  out GICR, temp ; aktivate int1 in Generel Interrupt Control
  ldi temp, 0b00001000
  out MCUCR, temp ; INT1 bei fallender Flanke
        sei

marco

von Chris (Gast)


Lesenswert?

wie sehen denn deine Initialisierungen am Anfang deines Programmes aus?

Gruß
Chris

von crazy horse (Gast)


Lesenswert?

stack?

von Malte (Gast)


Lesenswert?

Hi marco, was mir da aufgefallen ist:

  ldi temp, 0b1000000
  out GICR, temp ; aktivate int1 in Generel Interrupt Control

Dein ldi hat nur 7 bits,
  ldi temp, 0b1000000
entspricht also
  ldi temp, 0b01000000
ist das so gewollt? eventuell hast du damit nämlich nicht den INT1
aktiviert sondern INT0....

Gruss, Malte

von Alexander Niessen (Gast)


Lesenswert?

ich denke chris meint unter anderem auch die initialisierung der
sprungtabele für den (die) interrupt(s).
dem controller muss ja schliesslich gesagt werden wo er hinspringen
soll. (siehe avr-tutorial auf der page hier)

gruesse,
alex

von Malte (Gast)


Lesenswert?

jepp. aber da er diese tabelle noch nicht nachgepostet hat hab ich noch
auf ne andere möglichkeit hingewiesen *g

gruss, malte

von marco (Gast)


Lesenswert?

die Interrupt-Vektoren müssten so passen, oder?

rjmp Reset  ;Reset
reti    ;INT0
rjmp Menu  ;INT1
reti     ;Timer2 Compare
reti     ;Timer2 Overflow
reti     ;Timer1 Capture
reti     ;Timer1 Compare A
reti     ;Timer1 Compare B
reti     ;Timer1 Overflow
reti     ;Timer0 Overflow
reti     ;SPI Transfer Complete
reti     ;USART RX Complete
reti     ;USART Data Register Empty
reti     ;USART TX Complete
reti     ;ADC Conversation Complete
reti     ;EEPROM Ready
reti     ;Analog Comparator
reti     ;Two-wire serial interface
reti     ;INT2
reti     ;Timer0 Compare
reti     ;Store Program Memory ready

@carzy horse: der stack ist da.

@Malte: die 7 Bits hab ich auf 8 geändert, aber bringt nichts.
        ldi temp, 1<<int1    geht auch nicht

muss ich den interrupt denn noch in irgend einem anderen Register noch
freischalten?

von Chris (Gast)


Lesenswert?

Und wie sieht deine Interruptroutine aus? Wenn dein Programm nicht allzu
lang ist, dan kannst du es in den Text komplett einfügen, wen nicht
schick es im Anhang.
Gruß
Chris

von marco (Gast)


Lesenswert?

Die Interruptroutine funktioniert wenn ich sie testweise mittels rcall
als normale routine im Hauptprogramm aufrufe.
Das komplette Programm ist etwas länger (ca. 900 LOC).

Sonst noch irgend welche Ideen?

von Chris (Gast)


Lesenswert?

hast du dein Programm schon mal mit AVRStudio durchgetestet?

von thkais (Gast)


Lesenswert?

Wie sieht die Hardware aus? Werden saubere Pegel erzeugt? Den richtigen
Pin am Controller erwischt?

von marco (Gast)


Lesenswert?

bin gerade dabei mit AVRStudio zu debuggen.
kommt irgendwie ganz komisches Zeug raus: sobald ich die Interrupts
einschalte (sei) springt er immer zum Timer2-Overflow, obwohl ich da
überhaupt nichts eingestellt hab??? Fehler im Studio?

von marco (Gast)


Lesenswert?

ok, habs jetzt.
die eigentliche Einsprungadresse für den INT1 (0x04)ist da, wo bei mir
Timer2-Overflow steht (s.o.).
Zwischen jeder Zeile müsste also eine Leerzeile eingefügt werden. Aber
wie schreib ich das ins Programm? nop? oder wie macht man das?

von Jens-Erwin (Gast)


Lesenswert?

Hallo, Du kannst doch die Interruptadresse direkt ansprechen.
Wenn der entsprechende Interrupt eintrifft, dann schaut der Controller
genau in dieser Adresse nach, was dort steht

Zum Beispiel:

.CSEG
.ORG    $0000
    rjmp  Init   ;Beginn des eigentlichen Programms

.ORG    $0007
    rjmp  T0_OVF  ;Interruptroutine

.ORG    $0009
    rjmp  MIDI  ;eine weitere Interruptroutine

Die richtigen Adressen bekommst Du aus dem Datenblatt.
Genauso kannst Du auch mit .ESEG einzelne Segmente im Eeprom
beschreiben.

Gruß Jens-Erwin

von Jens-Erwin (Gast)


Lesenswert?

Hallo noch mal,

ich habe gerade in der ...def.inc nachgesehen. Es müßte sogar gehen (es
geht auch so), daß Du am Anfang lediglich den entsprechenden Interrupt
mit dem Zusatz addr aufschreibst. Über die *.inc Datei weiß dann der
Assembler, wo die Interrupteinstiegsadresse ist. Zum Beispiel:


.include "2313def.inc"

.CSEG
.ORG    0x0000    ;Reset
    rjmp  Init         ;Beginn des Programms

.ORG            INT0addr
                rjmp     Oma     ;Interruptroutine bei Int0
                                 ;automatisch an der richtigen Adresse

von marco (Gast)


Lesenswert?

hab die Zwischenräume mit reti´s aufgefüllt. Sieht jetzt so aus:

rjmp Reset    ;Reset
reti
reti      ;INT0
reti
rjmp Menu    ;INT1
reti
reti       ;Timer2 Compare
reti
reti      ;Timer2 Overflow
reti
reti       ;Timer1 Capture
reti
reti       ;Timer1 Compare A
reti
reti       ;Timer1 Compare B
reti
reti       ;Timer1 Overflow
reti
reti       ;Timer0 Overflow
reti
reti       ;SPI Transfer Complete
reti
reti       ;USART RX Complete
reti
reti       ;USART Data Register Empty
reti
reti       ;USART TX Complete
reti
reti       ;ADC Conversation Complete
reti
reti       ;EEPROM Ready
reti
reti       ;Analog Comparator
reti
reti       ;Two-wire serial interface
reti
reti       ;INT2
reti
reti       ;Timer0 Compare
reti
reti       ;Store Program Memory ready
reti

von thkais (Gast)


Lesenswert?

Da war doch was - die großen Megas haben eine andere Aufteilung der
Vektoren, damit anstelle des rjmp der längere jmp - Befehl reinpaßt.
Auf die einfachsten Dinge kommt man immer zu spät...

von Jens-Erwin (Gast)


Lesenswert?

Und wie wäre es nun mit


.CSEG
.ORG     0x0000       ;Reset
         rjmp  Reset

.ORG     INT1addr
         rjmp     Menü


;Und hier das eigentliche Programm (Reset:)
;und dann eben Menü
Sieht doch etwas eleganter aus - oder?

von crazy horse (Gast)


Lesenswert?

oder einfacher:

jmp reset
jmp int0
usw. :-)

von marco (Gast)


Lesenswert?

@Jens-Erwin: ist in der Tat etwas eleganter. ich werd´s gleich ändern.

@crazy horse: wenn ich jeden interrupt nutzen würde, würde das gehen.
aber was ist, wenn zwischendurch reti´s rein müssen?

von crazy horse (Gast)


Lesenswert?

da müssen keine retis rein. Lass immer die komplette Sprungtabelle immer
drin, am besten per include, alle nichtbenutzten können dann auf
dasselbe reti führen.


ex0_int:
ex1_int:
t1_ov:    reti

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.