8051 Interrupciones siempre activadas

0

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) )?

    
pregunta Max Vit

2 respuestas

0

Al comienzo de 'main', tiene una instrucción 'clr P3.3' que hace que el pin P3.3 / INT1 sea bajo.

La MCU genera continuamente interrupciones INT1 porque su pin P3.3 / INT1 siempre está bajo.

¿Puedes cambiar 'clr P3.3' a 'setb P3.3' y ver si esto elimina ese problema, lo que debería.

Por cierto, no he revisado mucho el resto del programa, pero no habilitas las interrupciones globalmente con un 'setb EA' en ninguna parte. ¿Está el programa en un estado de piratería mientras intentaba resolver el problema de las interrupciones continuas?

    
respondido por el TonyM
1

Parece que estás usando la interrupción externa en el modo de nivel, no activada por el borde.

Consulte la página 27 de la hoja de datos y lea la descripción del registro TCON. Además, como esto sucede con el generador de funciones desconectado, supongo que no tiene una resistencia de extracción externa. Sin embargo, pg. 20 sugiere que dejar flotar P3.3 podría ser malo.

    
respondido por el FRob

Lea otras preguntas en las etiquetas