#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