Forum: Mikrocontroller und Digitale Elektronik m16 Interrupt


von Manuel (Gast)


Lesenswert?

Hallo!

Ich habe mir mal folgenden code eingetippt um ein bischen mit den
Interrupts rumzuspielen (ist noch neuland für mich):

___________________________________________________________________
.include "m16def.inc"

.def temp1 = r16

.CSEG
.ORG 0000


    rjmp Main   ; Zum Maincode Springen
    reti    ; INT0
    reti    ; INT1
    reti    ; Timer1 CAPT
    reti    ; Timer1 COMPA
    reti    ; TIMER1 COMPB
    reti    ; TIMER1 COMP1
    reti    ; TIMER1 OVF
    reti    ; TIMER0 OVF
    reti    ; SPI STC
    reti     ; UART RX
    reti    ; UART UDRE
    reti    ; UART TX
    reti     ; ANA_COMP


Main:

           ldi temp1, LOW(RAMEND)      ; LOW-Byte der obersten
RAM-Adresse
           out SPL, temp1
           ldi temp1, HIGH(RAMEND)     ; HIGH-Byte der obersten
RAM-Adresse
           out SPH, temp1

       ldi temp1, 0x00
       out DDRD, temp1

       sei
___________________________________________________________________

Wenn ich nun im AVR simulator den Int0 aktiviere und das Programm
durchlaufe springt er immer an die stelle, die laut meiner kommentare
eigentlich Int1 ist.
Wenn ich im simulator INT1 aktiviere springt er zu TIMER1 COMPA.
Der Int2 springt direkt auf Reset.
Aber laut datenblatt ist doch die reset adresse 0000 -0002, int0
0003-0004 etc...

Was stimmt da bei mir nicht?
Ist es überhaupt richtig das ich 13 mal reti schreibe, wenn ich den
jeweiligen Vector nicht benutze?

von crazy horse (Gast)


Lesenswert?

Hm, M16 ist eigentlich was ganz anderes (Renesas), deshalb wohl noch
keine Antworten hier :-)
Aber du wirst wohl den Mega16 meinen.
Aufgrund der Flash-Grösse sind die Int-Vektoren im Doppelword-Abstand
angeordnet, um keine Sprungverlängerung einbauen zu müssen, wenn das
Sprungziel zu weit weg ist, also ljmp (2 word) statt rjmp (1 word)
eingesetzt werden muss. Reti hat jedoch nur nur 1 word.

entweder definierst du jeden benötigten Interrupt mit .org:
.org 0
jmp reset
.org 2  //ExInt0
reti
..

Besser jedoch:
.org 0
jmp reset
jmp ex0_int
jmp ex1_int
.
.
.
Und dann:
ex0_int:  reti
ex1_int:  reti
.
.
.
alle nicht benötigten Ints können auch auf die gleiche Sprungmarke
gehen:

ex0_int:
ex1_int:
t2_comp_int:
.
.
spm_rdy_int: reti

Gibt noch weitere Möglichkeiten:
jmp main
reti  //ex0_int
reti  //dummy-Befehl
reti  //ex1_int
reti  //dummy-Befehl
.
.
.

Oder auch ganz weglassen geht, da nicht freigeschaltete Ints nie
angesprungen werden.

von Läubi (Gast)


Lesenswert?

noch besser man benuzt die Symbolischen Namen aus der Definitionsdatei:

.org INT0addr
jmp XYZ

z.B.
Hat den Vorteil wenn man den Code mal migriert und dort die Adressen
anders sind hat man keine Probleme, und es geht nicht immer das gerate
los: Hat er jezt die richtige Adresse in der Sprungtabelle...

von Manuel (Gast)


Angehängte Dateien:

Lesenswert?

OK, danke!
Das hat jetz schonmal gut geklappt...
werds wohl in Zukunft immer mit den Symbolischen Namen machen.
gibts da eigentlich eine Liste in der alle drinstehen?

Habe jetz jedoch noch ein kleines Problem.
Habe mein Programm noch ein wenig erweitert, und will unabhängig von
irgeneinem Interrupt erstmal 0 auf einem Display ausgeben.
Jedoch bekomme ich statt 0 einfach nur zwei senkrechte striche
nebeneinander auf dem Display.
Ich mache es mit "ldi temp, '0'" was doch eigentlich gehen müsste,
habe aber auch schon "ldi temp, 0x30" versucht, und ging auch nicht.
Ich habe den code mal angehängt.

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.