Mitch64
22.03.2009, 10:27
Hallo an alle AVR'ler
Ich programmiere in BascomAVR 1.11.9.3 und scheitere an einer Inline-Assembler-Routine mit dem ASM-Befehl ICALL.
Hierzu habe ich folgenden Code geschrieben:
$regfile = "m48def.dat" ' ATmega48, Alternativ: ATmega88 o. ATmega168
$hwstack = 32
$swstack = 32
$framesize = 32
$crystal = 20000000 ' CPU kann 20MHz
Dim SubRoutine as word
SubRoutine = Loadlabel(Test_Routine1)
print hex(SubRoutine)
on int0 ISR_Horizontal nosave
enable int0
enable interrupts
do
nop
loop
' Horizontal-Interrupt
ISR_Horizontal:
push r24 ' r24 sichern
lds r24,sreg ' Statusregister nach r24
push r24 ' Statusregister sichern
push r30 ' Register Z sichern
push r31
lds r30 , {SubRoutine} ' Adresse von SubRoutine nach Z
lds r31 , {SubRoutine+1}
Icall ' SubRoutine aufrufen
pop r31 ' Z-Register restaurieren
pop r30
pop r24 ' Statusregister vom Stack holen
sts sreg,r24 ' Statusregister restaurieren
pop r24 ' r24 restaurieren
Return
Test_Routine1:
nop
Return
Test_Routine2:
nop
Return
Kurz zur Erklärung was ich bezwecken will:
In einer zeitkritischen Interruptroutine (hier stellvertretend INT0) mochte ich auf verschiedene Unter-Routinen verzweigen. Hierzu habe ich eine Word-Variable dimensioniert, die die Adresse enthält, auf die in der Interrupt-Routine verzweigt werden soll.
In der Interrupt-Routine selbst lade ich nun das Z-Register (r30 / r31) mit der Adresse und versuche den Call mit ICALL durchzuführen.
In der Simulation wird der Sprung auf die im Code angegebene Routine nicht durchgeführt. In der Statuszeile wird "Stopped" angezeigt. Beim weiter steppen in der Simulation beginnt das Programm bei Programmcounter (PC) Adresse 0.
Was mache ich falsch?
Lade ich die Register R24/R25 falsch oder funktioniert der Assembler-Befehl ICALL nicht in Bascom?
Habe es auch mit IJMP versucht, auch da stürzt das Programm ab.
Kann mir jemand von euch weiter helfen?
Gruß Mitch.
Ich programmiere in BascomAVR 1.11.9.3 und scheitere an einer Inline-Assembler-Routine mit dem ASM-Befehl ICALL.
Hierzu habe ich folgenden Code geschrieben:
$regfile = "m48def.dat" ' ATmega48, Alternativ: ATmega88 o. ATmega168
$hwstack = 32
$swstack = 32
$framesize = 32
$crystal = 20000000 ' CPU kann 20MHz
Dim SubRoutine as word
SubRoutine = Loadlabel(Test_Routine1)
print hex(SubRoutine)
on int0 ISR_Horizontal nosave
enable int0
enable interrupts
do
nop
loop
' Horizontal-Interrupt
ISR_Horizontal:
push r24 ' r24 sichern
lds r24,sreg ' Statusregister nach r24
push r24 ' Statusregister sichern
push r30 ' Register Z sichern
push r31
lds r30 , {SubRoutine} ' Adresse von SubRoutine nach Z
lds r31 , {SubRoutine+1}
Icall ' SubRoutine aufrufen
pop r31 ' Z-Register restaurieren
pop r30
pop r24 ' Statusregister vom Stack holen
sts sreg,r24 ' Statusregister restaurieren
pop r24 ' r24 restaurieren
Return
Test_Routine1:
nop
Return
Test_Routine2:
nop
Return
Kurz zur Erklärung was ich bezwecken will:
In einer zeitkritischen Interruptroutine (hier stellvertretend INT0) mochte ich auf verschiedene Unter-Routinen verzweigen. Hierzu habe ich eine Word-Variable dimensioniert, die die Adresse enthält, auf die in der Interrupt-Routine verzweigt werden soll.
In der Interrupt-Routine selbst lade ich nun das Z-Register (r30 / r31) mit der Adresse und versuche den Call mit ICALL durchzuführen.
In der Simulation wird der Sprung auf die im Code angegebene Routine nicht durchgeführt. In der Statuszeile wird "Stopped" angezeigt. Beim weiter steppen in der Simulation beginnt das Programm bei Programmcounter (PC) Adresse 0.
Was mache ich falsch?
Lade ich die Register R24/R25 falsch oder funktioniert der Assembler-Befehl ICALL nicht in Bascom?
Habe es auch mit IJMP versucht, auch da stürzt das Programm ab.
Kann mir jemand von euch weiter helfen?
Gruß Mitch.