Página 1 de 1

Porque não desabilita RBIF?

MensagemEnviado: 21 Ago 2011 16:13
por Kleber
Olá pessoal!

Fiz este programinha abaixo para teste e não sei por qual motivo não desabilita RBIF no tratamento da interrupção. Estou utilizando o MPLAB SIM e notei que não é possível voltar ao código principal, pois a todo momento a interrupção é chamada. Estou utilizando RB4 em Stimullus com Action:Toggle.

Segue o código:
Código: Selecionar todos

;---------------------------------------------------------------------------
;PROGRAMA PARA ESTUDO DA INTERRUPÇÃO POR MUDANÇA DE ESTADO
;FUNCIONAMENTO: AO MUDAR O ESTADO DE RB4, O ESTADO DO PORTD
;            SERÁ COMPLEMENTADO
;---------------------------------------------------------------------------

#INCLUDE <P16F877A.INC>
__CONFIG _WDT_OFF & _HS_OSC & _LVP_OFF

#DEFINE BANK0 BCF STATUS,RP0
#DEFINE BANK1 BSF STATUS,RP0

      ORG 0X00         ;VETOR DE RESET
      GOTO INICIO
      
      ORG 0X04         ;VETOR DE INTERRUPÇÃO
      GOTO TRATA_INT   
      

INICIO:   BANK1            ;BANCO 1
      MOVLW .7         ;DESLIGA CONVERSOR A/D
      MOVWF ADCON1

      MOVLW B'11001000'   ;HABILITA INTERRUPÇÃO POR MUDANÇA DE ESTADO
      MOVWF INTCON

      MOVLW B'00010000'
      MOVWF TRISB         ;DEFINE RB4 COMO ENTRADA E O RESTANTE COMO SAÍDA
      CLRF TRISD         ;DEFINE TODO O PORTD COMO SAÍDA
      
      BANK0            ;BANCO 0

MAIN:   GOTO $            ;LOOP INFINITO, AGUARDANDO INTERRUPÇÃO

;--------------------------TRATA INTERRUPÇÃO--------------------------      
TRATA_INT:
      BCF INTCON,RBIF      ;APAGA FLAG DE INTERRUPÇÃO ATIVA      
      COMF PORTD
      RETFIE      
;--------------------------------FIM-----------------------------------      
      END      


Alguém pode ajudar, dizendo qual o motivo?

Grato.

MensagemEnviado: 21 Ago 2011 17:20
por jorgeluiz
Simulei o programa no PicSimulatorIde, tudo normal. A interrupçao ocorre na borda de subida, retirando o sinal, volta ao loop.
Veja se nao ha' problemas no hardware.

MensagemEnviado: 21 Ago 2011 17:36
por Kleber
jorgeluiz escreveu:Simulei o programa no PicSimulatorIde, tudo normal. A interrupçao ocorre na borda de subida, retirando o sinal, volta ao loop.
Veja se nao ha' problemas no hardware.


Jorge,

Eu estou utilizando o simulador do MPLAB v8.53, tanto no modo Animate, quanto no Passo-a-Passo. O software complementa corretamente o PORTD, mas quando chega na instrução RETFIE, a rotina de interrupção é chamada novamente. Notei que a instrução BCF INTCON,RBIF não tem efeito algum no simulador MPLAB, pois na apaga o bit RBIF.
Irei simular no Proteus e no Kit da Microgênios para testar na prática (sem simulador).

Tentei colocar uns NOPs para entre os alguns comando aqui, mas de nada adiantou.rsss

Mas obrigado por sua colaboração!!!

MensagemEnviado: 21 Ago 2011 17:54
por Kleber
Testei o código na Placa PICGenios18F com o PIC16F877A, e realmente o programa não funcionou. Sei lá qual o "gato" disto.rs
Se alguém tiver alguma idéia sobre o problema, avise.

Fiz uma pequena alteração no código, na parte do Main e tratamento da Interrupção, mas nada que interfira na configuração da Interrupção.
Segue o código:
Código: Selecionar todos

;---------------------------------------------------------------------------
;PROGRAMA PARA ESTUDO DA INTERRUPÇÃO POR MUDANÇA DE ESTADO
;FUNCIONAMENTO: AO MUDAR O ESTADO DE RB4, O ESTADO DO PORTD
;            SERÁ COMPLEMENTADO
;---------------------------------------------------------------------------

#INCLUDE <P16F877A.INC>
__CONFIG _WDT_OFF & _HS_OSC & _LVP_OFF

#DEFINE BANK0 BCF STATUS,RP0
#DEFINE BANK1 BSF STATUS,RP0

      ORG 0X00         ;VETOR DE RESET
      GOTO INICIO
      
      ORG 0X04         ;VETOR DE INTERRUPÇÃO
      GOTO TRATA_INT   
      

INICIO:   BANK1            ;BANCO 1
      MOVLW .7         ;DESLIGA CONVERSOR A/D
      MOVWF ADCON1

      MOVLW B'11001000'   ;HABILITA INTERRUPÇÃO POR MUDANÇA DE ESTADO
      MOVWF INTCON

      MOVLW B'00010000'
      MOVWF TRISB         ;DEFINE RB4 COMO ENTRADA E O RESTANTE COMO SAÍDA
      CLRF TRISD         ;DEFINE TODO O PORTD COMO SAÍDA
      
      BANK0            ;BANCO 0

MAIN:   CLRF PORTD            ;LOOP INFINITO, AGUARDANDO INTERRUPÇÃO
      GOTO MAIN

;--------------------------TRATA INTERRUPÇÃO--------------------------      
TRATA_INT:
      BCF INTCON,RBIF      ;APAGA FLAG DE INTERRUPÇÃO ATIVA      
      MOVLW B'10101010'
      MOVWF PORTD
      RETFIE      
;--------------------------------FIM-----------------------------------      
      END      

MensagemEnviado: 21 Ago 2011 18:53
por jorgeluiz
aqui funcionou bem. Tente colocar o banco antes de limpar o flag da interrupçao:
bank1
bcf intcon,0

MensagemEnviado: 21 Ago 2011 21:51
por Kleber
jorgeluiz escreveu:aqui funcionou bem. Tente colocar o banco antes de limpar o flag da interrupçao:
bank1
bcf intcon,0


Jorge,

Rapaz, não deu certo.kkkk Se esta modificação que você sugeriu desse certo, aí seria mais estranho ainda, pois o registrador INTCON está em todos os bancos, correto?

MensagemEnviado: 21 Ago 2011 22:48
por Andre_Cruz
Kleber,

Você experimentou desligar os pull-ups do PORTB ?

MensagemEnviado: 21 Ago 2011 22:58
por Kleber
Andre_Cruz escreveu:Kleber,

Você experimentou desligar os pull-ups do PORTB ?


Não, mas irei fazer isto.

De qualquer maneira, esqueci de colocar o tratamento de contexto, salvar o reg. STATUS. Enfim, o código modificado segue abaixo, mas ainda não funciona.rs
Código: Selecionar todos

;---------------------------------------------------------------------------
;PROGRAMA PARA ESTUDO DA INTERRUPÇÃO POR MUDANÇA DE ESTADO
;FUNCIONAMENTO: AO MUDAR O ESTADO DE RB4, O ESTADO DO PORTD
;            SERÁ COMPLEMENTADO
;---------------------------------------------------------------------------

#INCLUDE <P16F877A.INC>
__CONFIG _WDT_OFF & _HS_OSC & _LVP_OFF

#DEFINE BANK0 BCF STATUS,RP0
#DEFINE BANK1 BSF STATUS,RP0

      CBLOCK 0X20
      W_TEMP
      STATUS_TEMP
      ENDC

      ORG 0X00         ;VETOR DE RESET
      GOTO INICIO
      
      ORG 0X04         ;VETOR DE INTERRUPÇÃO
SALVA_CONTEXTO:
      MOVWF W_TEMP
      SWAPF STATUS,W
      MOVWF STATUS_TEMP
      GOTO TRATA_INT   
      

INICIO:   BANK1            ;BANCO 1
      MOVLW .7         ;DESLIGA CONVERSOR A/D
      MOVWF ADCON1

      MOVLW B'10001000'   ;HABILITA INTERRUPÇÃO POR MUDANÇA DE ESTADO
      MOVWF INTCON

      MOVLW B'00010000'
      MOVWF TRISB         ;DEFINE RB4 COMO ENTRADA E O RESTANTE COMO SAÍDA
      CLRF TRISD         ;DEFINE TODO O PORTD COMO SAÍDA
      
      BANK0            ;BANCO 0

MAIN:   CLRF PORTD            ;LOOP INFINITO, AGUARDANDO INTERRUPÇÃO
      GOTO MAIN

;--------------------------TRATA INTERRUPÇÃO--------------------------      
TRATA_INT:
      BCF INTCON,RBIF
      MOVLW B'10101010'
      MOVWF PORTD
      GOTO SAI_INT
;---------------------FIM DA ROTINA DE INTERRUPÇÃO--------------------            
SAI_INT:
      SWAPF STATUS_TEMP,W
      MOVWF STATUS
      SWAPF W_TEMP,F
      SWAPF W_TEMP,W
      RETFIE
;--------------------------------FIM-----------------------------------      
      END      

MensagemEnviado: 21 Ago 2011 23:04
por Kleber
Bem, desliguei os resistores de pull-up no reg. OPTION_REG, mas não obtive sucesso. Acredito que no simulador isto não faria diferença, acho!

Existe alguma coisa no simulador que toda hora está ativando a interrupção, pois coloquei a instrução BCF INTCON,RBIE ao sair da rotina de tratamento, e tudo funcionou como esperado, entretanto, uma única vez, pois desabilitei a interrupção por mudança de estado.

MensagemEnviado: 22 Ago 2011 15:01
por Kleber
FUNCIONOU!

Testei o programa no kit da CNZ e funcionou perfeitamente, estranho que no MPLAB não funciona! Vide vídeo no youtube que postei aqui.
O problema está no MPLAB, onde eu não sei.
Preciso verificar também, o porque não funcionou no kit da Microgênios.

Obrigado aos colaboradores!