Forum: Mikrocontroller und Digitale Elektronik Sprung zum falschen Interrupt?


von Peter (Gast)


Lesenswert?

Hallo, ich hab mir so eben ein kleines Programm zusammengestrickt und 
jetzt folgendes Problem. Und zwar springt mir beim Überlauf des Timers 
T0 das Programm immer an die Adresse des Interrupts "Two-Wire Serial 
Interface" anstatt an die Stelle des Timer0 Overflow Interrupts, woran 
könnte das liegen?

.include "m16def.inc"
.cseg
.org 0x00
  jmp main ; Reset Handler
  reti ; IRQ0 Handler
  reti ; IRQ1 Handler
  reti ; Timer2 Compare Handler
  reti ; Timer2 Overflow Handler
  reti ; Timer1 Capture Handler
  reti ; Timer1 CompareA Handler
  reti ; Timer1 CompareB Handler
  reti ; Timer1 Overflow Handler
  rjmp T0overflow ; Timer0 Overflow Handler
  reti ; SPI Transfer Complete Handler
  reti ; USART RX Complete Handler
  reti ; UDR Empty Handler
  reti ; USART TX Complete Handler
  reti ; ADC Conversion Complete Handler
  reti ; EEPROM Ready Handler
  reti ; Analog Comparator Handler
  reti ; Two-wire Serial Interface Handler
  reti ; IRQ2 Handler
  reti ; Timer0 Compare Handler
  reti ; Store Program Memory Ready Handler


main:

von Karl heinz B. (kbucheg)


Lesenswert?

Das liegt daran, dass der Mega16 mehr Speicher hat als
der Mega8. Folgerichtig braucht man 2 Bytes um eine
Adresse im Speicher zu adressieren. Folgerichtig
hat jeder Eintrag im Interrupt-Vektor 2 Bytes
anstatt nur 1 wie beim Mega8.

Du musst also nach den reti noch jeweils ein Byte einfügen.
Einfacher und sicherer ist es allerdings die Interrupt
Vektoren mittls .org Instruktionen auf die richtige Adresse
zu platzieren.

So wie es zb hier gemacht wurde:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer#Erste_Tests

von Peter (Gast)


Lesenswert?

Ah danke ;)

von Falk (Gast)


Lesenswert?

@Karl heinz Buchegger

> Das liegt daran, dass der Mega16 mehr Speicher hat als
> der Mega8. Folgerichtig braucht man 2 Bytes um eine
> Adresse im Speicher zu adressieren. Folgerichtig
> hat jeder Eintrag im Interrupt-Vektor 2 Bytes
> anstatt nur 1 wie beim Mega8.

Es ist viel SCHLIMMER!
Du meinst sicherlich 2 Worte = sage und schreibe 4 Bytes!
;-)

> Du musst also nach den reti noch jeweils ein Byte einfügen.

Neee, Wort.

MFG
Falk

von Karl heinz B. (kbucheg)


Lesenswert?

> Du meinst sicherlich

Kann sein, dass ich das meine :-)
Ich überlass sowas dem Compiler bzw. Assembler :-)

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Das Einfachste ist, statt "reti" ein "jmp RESET" in die unbenutzten 
Vektoren zu schreiben, dann kann man fehlgeleitete Interrupts gleich am 
Neustart erkennen und ggf. abfangen. Außerdem füllt dieses Kommando 
exakt die 2 Worte.

von Peter D. (peda)


Lesenswert?

Wenn man Interrupts nimmt, dann sollte man bitteschön auch die 
vordefinierten Vektoren nehmen.
Wozu schreiben sie die denn extra ins Include.


Die Vektoren sind nunmal bei den verschiedenen AVRs nicht in der 
gleichen Reihenfolge.

Also immer schön mit .org die Adresse setzen und dann zum Handler 
springen.

Alles andere ist Mumpitz und geht beim nächsten Derivat garantiert 
wieder schief.


Peter

von Michele B. (luxx) Benutzerseite


Lesenswert?

also mal einfach gesagt:

nicht RJMP sondern JMP verwenden....

am besten so: (MEGA16)

.org 0x000 jmp main             ; Reset Handler
                                ; steht immer ganz am Anfang des 
Speichers
           jmp falsch           ; IRQ0 Handler
           jmp falsch           ; IRQ1 Handler
           jmp falsch           ; Timer2 Compare Match
           jmp falsch           ; Timer2 Overflow
           jmp falsch           ; Timer1 Capture Handler
           jmp falsch           ; Timer1 CompareA Handler
           jmp falsch           ; Timer1 CompareB Handler
           jmp falsch           ; Timer1 Overflow Handler
           jmp falsch           ; Timer0 Overflow Handler
           jmp falsch           ; SPI Transfer Complete Handler
           jmp falsch           ; USART RX Complete Handler
           jmp falsch           ; UDR Empty Handler
           jmp falsch           ; USART TX Complete Handler
           jmp falsch           ; ADC Conversion Complete Interrupt 
Handler
           jmp falsch           ; EEPROM Ready Handler
           jmp falsch           ; Analog Comparator Handler
           jmp falsch           ; Two-wire Serial Interface Handler
           jmp falsch           ; IRQ2 Handler
           jmp falsch           ; Timer0 Compare Match
           jmp falsch           ; Store Program Memory Ready Handler

falsch:    reti

von johnny.m (Gast)


Lesenswert?

Wenn man sich nicht sicher ist: Einfach im Datenblatt nachsehen. ATMEL 
hat immer recht viele Code-Beispiele drin, und dazu zählen auch die 
Vektortabellen in Assembler. Braucht man eigentlich nur abzutippen.

von Peter D. (peda)


Lesenswert?

@ Michele

Ja, genau so sollte man es eben nicht machen.


Was stört Dich daran, für jeden Vektor das passende .org zu nehmen ?

Man muß dann bloß den nachfolgenden Code hinter dem letzten Vektor 
beginnen lassen.

Und wenn dann mal ein Vektor nicht existiert oder anders heißt, kriegt 
man sofort ne ordentliche Fehlermeldung und muß nicht erst tagelang 
debuggen.


Peter

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.