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.