0
votes

I'm writing some assembly code for PIC16F628A and found the following problem:

The GIE (Global Interrupt Enable bit) is automatically cleared when the ISR routine is called. Then, when the ISR routine returns, the bit is automatically set again.

I want interrupts to be permanently disabled when the ISR routine returns, I don't want GIE to be reset, but it's reset no matter what.

Here is some example code:

LIST        p=16F628A
#INCLUDE    <P16F628A.INC> 

__CONFIG    _LP_OSC & _WDT_OFF & _PWRTE_OFF & _BODEN_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF


CONTROL     EQU 0X20    ; A general purpose register used to control a loop
CAN_GO_ON   EQU 0       ; A flag bit at register CONTROL

ORG 00
    goto start

ORG 04
    goto isr

ORG 10

start
    bsf     STATUS, RP0     ; Selects bank 1
    movlw   0xFF            ; Set all PORTB pins as input
    movwf   TRISB       
    bcf     STATUS,RP0      ; Selects bank 0
    movlw   0x08            ; Enables only PORTB<4:7> change interrupts
    movwf   INTCON          ; GIE is cleared for now.

; ... later in the code ...


wait_for_interrupt_to_happen
    bsf     INTCON, GIE         ; Enable interrupts. INTCON now reads 0x88
someloop                        ; This loop will go on and on until and interrupt occurs
    nop                         ; and the ISR set the flag CAN_GO_ON
    btfsc   CONTROL, CAN_GO_ON
    goto    resume_program      ; The isr returned, GIE is set. I don't want another interrupt to
                                ; happen now. But if PORTB<4:7> changes now, isr will be called
                                ; again before I have the chance to clear GIE and disable interrupts. :(
    goto    someloop


resume_program
    bcf     INTCON, GIE         ; I don't want more interrrupts to happen, so I clear GIE.
                                ; INTCON now reads 0x08
    ; ...
    ; ...
    ; ... 


isr
    nop                         ; An interrupt has ocurred. GIE is automatically disabled here.
                                ; INTCON reads 0x09
    bsf     CONTROL, CAN_GO_ON  ; flag CAN_GO_ON is set so the program can break from the loop
                                ; and resume execution
    bcf     INTCON, RBIF        ; clear the PORTB change interrupt flag. INTCON now reads 0x08
    retfie                      ; after retfie, GIE is automatically reset, and INTCON will read 0x88


end

How can I disable interrupts from the ISR in a matter interrupts aren't enabled again?

Thanks in advance for the help.

2

2 Answers

2
votes

Looks like you can replace retfie with return, doing the same job except setting GIE to 1.

0
votes

Problem solved!

The solution is simply to use return instead of retfie.

retfie will return from the interrupt service routine and re-enable interrupts. return will simply return from the routine and leave everything as is.

isr
    nop
    bsf    CONTROL, CAN_GO_ON
    bcf    INTCON, RBIF
    return