Beim Aufruf einer ISR wird R1 nicht mit gesichert. R1 wird als Null angenommen und damit gerechnet. Ist R1 nicht Null, gibt es Rechenfehler.
Der Code
Code: Alles auswählen
procedure timer0_interrupt; alias: 'TIMER0_COMPA_ISR'; interrupt; public;
begin
inc(sseccnt);
if sseccnt >= 25000 then begin // 1 Sekunde
sseccnt := 0;
Code: Alles auswählen
TIMER0_COMPA_ISR:
push r26
push r20
push r19
push r18
push r0
in r0,63
push r0
# [25] inc(sseccnt);
lds r20,(U_sEM_INT_ss_SSECCNT)
lds r19,(U_sEM_INT_ss_SSECCNT+1)
ldi r18,1
add r20,r18
adc r19,r1 <= hier wird mit r1 = 0 gerechnet
sts (U_sEM_INT_ss_SSECCNT),r20
sts (U_sEM_INT_ss_SSECCNT+1),r19
Eine Multiplikation irgendwo im Programm gibt
Code: Alles auswählen
# [50] mean := (15 * mean + vval) div 16;
lds r18,(U_sEM_DEFINE_ss_MEAN)
lds r19,(U_sEM_DEFINE_ss_MEAN+1)
ldi r22,15
mov r21,r1
movw r2,r18
mul r2,r22
movw r18,r0 <= ab hier enthalten R1:R0 die Ergebnisse von mul
mul r3,r22
add r19,r0
mul r2,r21
add r19,r0
clr r1 <= hier erst wird R1 wieder sicher Null
mov r2,r19
mov r21,r1