hallo
ich habe ein problem mit meinem atmega16 bzw auch schon mit dem
simulator in avrstudio.
bei solchem asm code wie unten spring er immer falsch.
.org 0x000 ; kommt ganz an den Anfang des Speichers
rjmp RESET ; Interruptvektoren überspringen
; und zum Hauptprogramm
rjmp EXT_INT0 ; IRQ0 Handler
rjmp EXT_INT1 ; IRQ1 Handler
rjmp TIM2_COMP
rjmp TIM2_OVF
rjmp TIM1_CAPT ; Timer1 Capture Handler
rjmp TIM1_COMPA ; Timer1 CompareA Handler
rjmp TIM1_COMPB ; Timer1 CompareB Handler
rjmp TIM1_OVF ; Timer1 Overflow Handler
rjmp TIM0_OVF ; Timer0 Overflow Handler
rjmp SPI_STC ; SPI Transfer Complete Handler
rjmp USART_RXC ; USART RX Complete Handler
rjmp USART_DRE ; UDR Empty Handler
rjmp USART_TXC ; USART TX Complete Handler
rjmp ADC ; ADC Conversion Complete Interrupt
rjmp EE_RDY ; EEPROM Ready Handler
rjmp ANA_COMP ; Analog Comparator Handler
rjmp TWSI ; Two-wire Serial Interface Handler
rjmp SPM_RDY ; Store Program Memory Ready Handler
bei diesem code springt er bei TIM0_OVF Interrupt statt nach 0x009
immer zu 0x018. auch im avrstudio simulator springt er immer dahin.
wo liegt da der fehler?
luxx
wegen: "Besser is das!" Guck doch mal ins "Instruction Set Summary" - da wirst du einen Unterschied zwischen "rjmp" und "jmp" finden.
Auch WERNER sagte schon: Jo, besser is´das! Ich habe auch die Erfahrung gemacht, daß rjmp sonstwo hinspringt. MfG Paul
rjmp an sich springt nicht "irgendwohin", sondern exakt dorthin, was man angibt. Das Problem liegt in diesem Fall daran, dass rjmp nur 1 word breit ist, jmp 2 word. Und um den vollen Programmspeicher direkt anspringen zu können, hat Atmel klugerweise die Interrupteinsprung-Adressen im Doppelword-Abstand angeordnet. Selbstverständlich kannst du auch rjmp benutzen: .org 0x000 rjmp RESET .org 0x002 rjmp EXT_INT0 ; IRQ0 Handler .org 0x000 rjmp RESET nop rjmp EXT_INT0 ; IRQ0 Handler nop rjmp EXT_INT1 ; IRQ1 Handler nop Sinn macht es nicht, du gewinnst nichts, verlierst aber die Möglichkeit, den gesamten Programmspeicher anzuspringen.
jmp in der Vektortabelle kommt bei allen größeren Prozis ab 16k Flash-Speicher zum Einsatz, bei allen kleineren wird rjmp benutzt; auch etwas, was im Datenblatt steht...
>Nur zur Vollständigkeit: rjmp ist 1 Takt schneller
weil es auch 1 Byte kürzer ist...
Du kannst auch dafür sorgen, dass deine Interrupt-routine innerhalb des von rjmp adressierbaren bereichs liegt. Also gleich nach den Interruptvektoren oder ganz am Ende des Speichers. Aber ob dir der eine Takt den Ärger wirklich wert ist musst du selbst wissen. Mir wär er's nicht. Sebastian
Die Befehlslänge spielt in diesem Fall ja keine Rolle, die Ausführungszeit evtl. schon. Es läßt sich durchaus eine kleine Routine innerhalb des Interruptblocks unterbringen, vorausgesetzt, man hat nur wenige Interrupts und findet eine entsprechende Lücke.
"Die Befehlslänge spielt in diesem Fall ja keine Rolle" Hu??? In der Interrupt-Vektor-Tabelle zählt einzig die Position. Wen die Laufzeit von JMP stört (ähem, wegen 1 Takt?), der mag halt hinter jedem RJMP noch ein NOP plazieren, aber es müssen 2 Worte pro Sprung sein.
Ärger, Sebastian? - Nur eine Frage der Organisation. Aber ich wollte, als Reaktion auf TravelRec., nur verdeutlichen, dass der Interruptblock mit rjmp oder jmp theoretisch gar nichts zu tun hat: der Prozessor springt hinein, ob bzw. wie mein Programm dann herausspringt ist eine andere Sache.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.