Estoy usando el chip at89lp2052 y tengo un generador de impulsos que genera un impulso una vez que se reinicia cada impulso para el puerto 3.3, esta es la interrupción. Mientras la señal es baja, el chip debe estar en la rutina de servicio de interrupción (incrementando R0). Sin embargo, cuando ejecuto el código, pasa a la rutina de servicio de interrupción (ISR) tan pronto como enciendo las interrupciones globales. Luego regresa y vuelve a hacer el CJNE y luego vuelve a estar en la interrupción. Y así hasta el próximo reinicio.
Si tengo un AE clr para desactivar las interrupciones globales después del CJNE, hace el ISR dos veces. Si el clr está dentro del ISR, lo hace solo una vez (como se esperaba). Nota: estoy utilizando una ventana GPIO en un oscope para ver qué está haciendo.
Además, si desactivo todo el canal en el generador de impulsos e incluso desconecto el cable completamente, sigue haciendo lo mismo. Así que es algo que el chip está haciendo, o estoy haciendo con el código.
Se supone que el código de abajo básicamente incrementa R0 hasta que el pulso se apaga y luego regresa y lo usa para decidir a dónde saltar, es decir, qué conjunto de instrucciones. Nota: tengo muchas de las ventanas GPIO de NOP para diferenciar fácilmente las instrucciones en el oscope.
org 0 ; Place this code starting from byte 0 in code mem
mov 0xc3, #0xFF ; Set P1M1
mov 0xc7, #0xFF ; Set P3M1
jmp main ; Jump to main (skip ISR for interrupt 1)
isr_int1:
org 13H ; Place this code starting form byte 13H in code mem
mov R1, #1 ; Set R1 to show that interrupt has ran (2 clock cycle)
inc R0 ; Increment R0 (1 clock cycle)
inc R0 ; Increment R0 (1 clock cycle)
mov 0x90, #0x00 ; Pull GPOI window down
mov 0x90, #0x01 ; Pull GPOI window up
;clr EA ; Global disable interrupts (Runs ISR 1 times)
reti ; Return from ISR
main:
org 30H ; Place this code starting form byte 1BH in code mem
clr P3.3 ; Clear port 3.3
mov R0, #0 ; Reset R0
mov R1, #0 ; Reset R1
isr_wait:
mov IE, #10000100B ; EA = 1 (Global interrupt enable) and EX1 = 1 (Enable ext interrupt 1)
wait_loop: cjne R1, #1, wait_loop ; Waiting for interrupt 1
;clr EA ; Global disable interrupts (Runs ISR 2 times)
cmp1:
cjne R0, #1, cmp2 ; If ISR ran 1 times,
jmp instr1 ; Go to instruction 1
cmp2:
cjne R0, #2, cmp3 ; If ISR ran 1 times,
jmp instr2 ; Go to instruction 2
cmp3:
cjne R0, #3, cmp1 ; If ISR ran 1 times,
jmp instr3 ; Go to instruction 3
instr1: ; Instruction 1 code
mov 0x90, #0x00 ; Pull GPOI window down
mov A, #0 ; Instruction to execute (mov A, #data = 2 clock cycles)
mov 0x90, #0x01 ; Pull GPOI window up
jmp end_loop
instr2: ; Instruction 2 code
mov 0x90, #0x00 ; Pull GPOI window down
div AB ; Instruction to execute (div AB = 4 clock cycles)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
mov 0x90, #0x01 ; Pull GPOI window up
jmp end_loop
instr3: ; Instruction 3 code
mov 0x90, #0x00 ; Pull GPOI window down
add A, R0 ; Instruction to execute (add A, R0 = 1 clock cycles)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
mov 0x90, #0x01 ; Pull GPOI window up
end_loop: jmp end_loop
end
Actualización: ¿Qué me falta para que el chip responda correctamente a las interrupciones (solo cuando está presente el pulso de interrupción), y salga de la ISR cuando haya terminado la pulsación (debería comprobarlo cada vez que finalice la ISR por completo) )?