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
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
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
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?
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
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?
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?
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?
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
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
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
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...
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?
@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?
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
Eine eigene Frage?
Dieser Thread ist über 23 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.