# 8051 Interrupts Always On

I am using the at89lp2052 chip and I have a pulse generator generating a pulse once every reset pulse for port 3.3, this is the interrupt. While the signal is low, the chip has to be in the interrupt service routine (incrementing R0). However, when I run the code, it goes to the interrupt service routine (ISR) as soon as I turn on the global interrupts. It then comes back and does the CJNE once more and then, it's in the interrupt again. And so on until the next reset.

If I have a clr EA to turn off the global interrupts after the CJNE, it does the ISR two times. If the clr is inside the ISR, it does the ISR only once (as expected). Note: I am using a GPIO window on an oscope to see what it's doing.

Also, if I turn off the whole channel on the pulse generator and even unplug the cable completely, it still does the same. So it's something that the chip is doing, or I am doing with the code.

The code bellow is supposed to basically increment R0 until the pulse is off and then return and use that to decide where to jump to, i.e. what instruction set. Note: I have many NOP's some of the GPIO windows to differentiate between the instructions easily on the oscope.

org 0 ; Place this code starting from byte 0 in code mem
mov 0xc3, #0xFF ; Set P1M1
mov 0xc7, #0xFF ; Set P3M1

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


Update: What am I missing to make the chip respond to the interrupts correctly (only when the interrupt pulse is present), and exit the ISR when the pulse is over (it should check for that every time it finishes the ISR completely)?

• Good overall explanation, but what exactly is your question(s). Please end actual questions with a '?'. – Sparky256 Jul 9 '16 at 3:19

At the start of 'main', you have a 'clr P3.3' instruction that drives pin P3.3/INT1 low.

The MCU then continually generates INT1 interrupts because its P3.3/INT1 pin is always low.

Can you change 'clr P3.3' to 'setb P3.3' and see if this removes that problem, which it should.

Incidentally, I haven't sifted through the rest of the program much but you don't enable interrupts globally with a 'setb EA' anywhere. Is the program in a hacked-about state while you tried to solve the continuous interrupts problem?

• Ok, I will try the setb P3.3 when I get to work on Monday. I agree that that is probably what is causing the problem. As far as the setb EA and setb EX1, it is equivalent to mov IE, #10000100B since the last bit in IE, called EA, is set to 1 (Global interrupt enable), and the 3rd bit, EX1 = 1 (Enable ext interrupt 1). – Max Vit Jul 9 '16 at 21:14
• @MaxVit, yes I skimmed through the program but now see that the 'clr EA's are commented out and presumably a part of your debugging. Good luck on a Monday. – TonyM Jul 9 '16 at 22:16
• @MaxVit, glad to hear that it solved it :-) – TonyM Jul 12 '16 at 6:20

It seems you're using the external interrupt in level mode, not edge-triggered.

Check out page 27 of the datasheet and read the TCON register description. Also, since this happens with disconnected function generator, I presume you don't have an external pullup resistor. However, pg. 20 suggests that leaving P3.3 floating might be bad.

• It's in level mode because I basically am counting for how long the pulse is on and deciding what to do based on that. Also, I may be reading it incorrectly, but it's talking only about the power-down, not normal functioning when referring to the port floating. – Max Vit Jul 9 '16 at 18:03
• But then what you see is normal behavior when the pin is low. Level interrupt fires until the level is high again or the interrupt is turned off. – FRob Jul 9 '16 at 20:13