PIC: отключить прерывания при возврате из ISR

#assembly #microcontroller #interrupt #pic

#сборка #микроконтроллер #прерывание #pic

Вопрос:

Я пишу некоторый код сборки для PIC16F628A и обнаружил следующую проблему:

GIE (бит разрешения глобального прерывания) автоматически очищается при вызове процедуры ISR. Затем, когда процедура ISR возвращается, бит автоматически устанавливается снова.

Я хочу, чтобы прерывания были постоянно отключены при возврате процедуры ISR, я не хочу, чтобы GIE сбрасывался, но он сбрасывается, несмотря ни на что.

Вот несколько примеров кода:

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

__CONFIG    _LP_OSC amp; _WDT_OFF amp; _PWRTE_OFF amp; _BODEN_OFF amp; _INTRC_OSC_NOCLKOUT amp; _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
  

Как я могу отключить прерывания из ISR, если прерывания снова не будут включены?

Заранее спасибо за помощь.

Ответ №1:

Похоже, вы можете заменить retfie на return , выполнив ту же работу, за исключением установки значения GIE равным 1.

Комментарии:

1. Только что получил это. Большое вам спасибо!

Ответ №2:

Проблема решена!

Решение состоит в том, чтобы просто использовать return вместо retfie .

retfie вернется из процедуры обслуживания прерываний и снова включит прерывания. return просто вернется из процедуры и оставит все как есть.

 isr
    nop
    bsf    CONTROL, CAN_GO_ON
    bcf    INTCON, RBIF
    return