Autor Tema: Interrupcion no retorna, pic16f877a  (Leído 3251 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado timh

  • PIC10
  • *
  • Mensajes: 23
Interrupcion no retorna, pic16f877a
« en: 13 de Noviembre de 2011, 19:54:42 »
Hola a todos,buenas tardes,  soy nuevo en el foro, escribo para perdirles un poco de ayuda lo que pasa que empiezo con este tema de las interrupciones e hice un pequeño programa que capta interrupciones del puerbo rb4-rb7 y la interrupcion si se dispara, el problema es que la rutina de la interrupcion se cicla y no termina, les dejo mi codigo para que mas o menos se den una idea de como esta el asunto.

   
Código: [Seleccionar]
LIST P=16F877A
    INCLUDE <P16F877A.INC>

LOC EQU 0x20
VIS EQU 0x21
W_TEMP EQU 0x22
STATUS_TEMP EQU 0x23
TEMP EQU 0x24
AUX EQU 0x25

    cblock 0x26
        PDel0
        PDel1
        PDel2
    endc

;-----------------INICIO--------------
    ORG 0
    GOTO INICIO
    ORG 4
    GOTO INTERRUPT

INICIO
            BSF STATUS,RP0
            BSF INTCON,GIE
            BSF INTCON,RBIE
            MOVLW 0xFF
            MOVWF TRISB
            CLRF TRISD
            CLRF TRISC
            BCF STATUS,RP0
            CLRF PORTD
            CLRF PORTC
            CALL MOSTRAR

MOSTRAR     MOVF LOC,W
            MOVWF PORTC
            MOVF VIS,W
            MOVWF PORTD
            CALL DEMORA
            MOVLW 0xFF
            MOVWF PORTC
            MOVLW 0xFF
            MOVWF PORTD
            CALL DEMORA

INTERRUPT   MOVWF W_TEMP
            MOVF STATUS,W
            MOVWF STATUS_TEMP
            MOVLW .9
            MOVWF PORTC
            CALL DEMORA
            MOVLW 0xFF
            MOVWF PORTC
            CALL DEMORA
            MOVF STATUS_TEMP,W
            MOVWF STATUS
            SWAPF W_TEMP,F
            SWAPF W_TEMP,W
            RETFIE
           
;-------------------------------------------------------------
; Generado con PDEL ver SP  r 1.0  el 13/11/2011 Hs 10:40:28 a.m.
; Descripcion: Delay 3000000 ciclos
;-------------------------------------------------------------
DEMORA  movlw     .67       ; 1 set numero de repeticion  (C)
        movwf     PDel0     ; 1 |
PLoop0  movlw     .91       ; 1 set numero de repeticion  (B)
        movwf     PDel1     ; 1 |
PLoop1  movlw     .122      ; 1 set numero de repeticion  (A)
        movwf     PDel2     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
        decfsz    PDel2, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel1,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
        decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (C)
        goto      PLoop0    ; 2 no, loop
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.
;-------------------------------------------------------------

    END
Estoy trabajando con el pic16f877a y lo tengo con un cristal de 4Mhz. Les dejo mi esquema de proteus.

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: Interrupcion no retorna, pic16f877a
« Respuesta #1 en: 13 de Noviembre de 2011, 20:41:59 »
tienes que limpiar el flag INT0IF para que no se vuelva a repetir la interrupcion

Desconectado timh

  • PIC10
  • *
  • Mensajes: 23
Re: Interrupcion no retorna, pic16f877a
« Respuesta #2 en: 13 de Noviembre de 2011, 21:25:37 »
Ya lo hice y no paso nada, la interrupcion se siguie repitiendo, pero tengo la duda que INT0IF no esta en el registro INTCON del 16f877a y como estoy trabajando sobre las interrupciones que se producen con el RB4-RB7 la bandera que creo que debo borrar es la RBIF, y la borro, pero aun asi se sigue ciclando la interrupcion, ¿Alguna otra sugerencia?
« Última modificación: 13 de Noviembre de 2011, 21:29:31 por timh »

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: Interrupcion no retorna, pic16f877a
« Respuesta #3 en: 13 de Noviembre de 2011, 21:41:04 »
cierto, no me fije ke era rbif lo confundi con intcon, otra cosa que he visto que en MOSTRAR no tiene puesto un return y en inicio tampoco tienes puesto ningun loop, tu codigo se reproduce de arriba a abajo y llega a interrupt, ahi vuelve a retfie que nose que efectos causara.

Revisa bien todo el codigo, puedes usar el proteus como debugger y ver como se procesa el codigo.

Desconectado timh

  • PIC10
  • *
  • Mensajes: 23
Re: Interrupcion no retorna, pic16f877a
« Respuesta #4 en: 13 de Noviembre de 2011, 22:23:39 »
Ya modifique el código pero aún se me sigue ciclando en la interrupcion, ya no se que mas hacer, ¿alguna sugerencia?

Código: [Seleccionar]
    LIST P=16F877A
    INCLUDE <P16F877A.INC>

LOC EQU 0x20
VIS EQU 0x21
W_TEMP EQU 0x22
STATUS_TEMP EQU 0x23
TEMP EQU 0x24
AUX EQU 0x25

#DEFINE BANCO0 BCF STATUS,5
#DEFINE BANCO1 BSF STATUS,5

    cblock 0x26
        PDel0
        PDel1
        PDel2
    endc

;-----------------INICIO--------------
    ORG 0
    GOTO INICIO
    ORG 4
     BCF  INTCON,0
     MOVWF W_TEMP
     MOVF STATUS,W
     MOVWF STATUS_TEMP
     MOVLW .9
     MOVWF PORTC
     CALL DEMORA
     MOVLW 0xFF
     MOVWF PORTC
     CALL DEMORA
     MOVF STATUS_TEMP,W
     MOVWF STATUS
     SWAPF W_TEMP,F
     SWAPF W_TEMP,W
     RETFIE

INICIO      BANCO1
            MOVLW 0xFF
            MOVWF TRISB
            CLRF TRISD
            CLRF TRISC
            BANCO0
            BSF INTCON,GIE
            BSF INTCON,RBIE
            BANCO0
            CLRF PORTD
            CLRF PORTC
            CALL MOSTRAR

MOSTRAR     MOVF LOC,W
            MOVWF PORTC
            MOVF VIS,W
            MOVWF PORTD
            CALL DEMORA
            MOVLW 0xFF
            MOVWF PORTC
            MOVLW 0xFF
            MOVWF PORTD
            CALL DEMORA
            return
           
;-------------------------------------------------------------
; Generado con PDEL ver SP  r 1.0  el 13/11/2011 Hs 10:40:28 a.m.
; Descripcion: Delay 3000000 ciclos
;-------------------------------------------------------------
DEMORA  movlw     .67       ; 1 set numero de repeticion  (C)
        movwf     PDel0     ; 1 |
PLoop0  movlw     .91       ; 1 set numero de repeticion  (B)
        movwf     PDel1     ; 1 |
PLoop1  movlw     .122      ; 1 set numero de repeticion  (A)
        movwf     PDel2     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
        decfsz    PDel2, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel1,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
        decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (C)
        goto      PLoop0    ; 2 no, loop
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.
;-------------------------------------------------------------

    END

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Interrupcion no retorna, pic16f877a
« Respuesta #5 en: 13 de Noviembre de 2011, 22:37:51 »
  Lo primero que hay que hacer dentro del bloque de interrupción es deshabilitar las mimas haciendo 0 el bit GIE. Para que no se produzca una nueva interrupción mientras aún estamos dentro del bloque de interrupción.
  Otra cosa a tener en cuenta es que, para que desaparezca la condición de cambio de estado sobre el puerto B, hay que hacer una lectura del mismo y luego sí se podrá borrar el flag correspondiente (RBIF)
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado timh

  • PIC10
  • *
  • Mensajes: 23
Re: Interrupcion no retorna, pic16f877a
« Respuesta #6 en: 13 de Noviembre de 2011, 22:44:11 »
No me queda muy claro lo de "hacer una lectura", ¿esto como se hace?

Desconectado timh

  • PIC10
  • *
  • Mensajes: 23
Re: Interrupcion no retorna, pic16f877a
« Respuesta #7 en: 13 de Noviembre de 2011, 22:49:13 »
Ya casi lo logro, muchas gracias por su apoyo, a todos.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Interrupcion no retorna, pic16f877a
« Respuesta #8 en: 13 de Noviembre de 2011, 22:50:39 »
  Para hacer una lectura del puerto se puede recurrir a hacer

Código: ASM
  1. movf portb,W

 por ejemplo
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado timh

  • PIC10
  • *
  • Mensajes: 23
Re: Interrupcion no retorna, pic16f877a
« Respuesta #9 en: 13 de Noviembre de 2011, 22:58:59 »
Bueno pues ya la interrupcion se detecta y retorna como debería pero ahora lo que pasa es que despues de retornar de la interrupcion el pic se queda como en pausa unos 20 seg y vuelve a hacer lo que debe, ¿A que se podría deber que sucede esto?

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Interrupcion no retorna, pic16f877a
« Respuesta #10 en: 13 de Noviembre de 2011, 23:22:22 »
Ya modifique el código pero aún se me sigue ciclando en la interrupcion, ya no se que mas hacer, ¿alguna sugerencia?

Código: [Seleccionar]
    LIST P=16F877A
    INCLUDE <P16F877A.INC>

LOC EQU 0x20
VIS EQU 0x21
W_TEMP EQU 0x22
STATUS_TEMP EQU 0x23
TEMP EQU 0x24
AUX EQU 0x25

#DEFINE BANCO0 BCF STATUS,5
#DEFINE BANCO1 BSF STATUS,5

    cblock 0x26
        PDel0
        PDel1
        PDel2
    endc

;-----------------INICIO--------------
    ORG 0
    GOTO INICIO
    ORG 4
     BCF  INTCON,0
     MOVWF W_TEMP
     MOVF STATUS,W
     MOVWF STATUS_TEMP
     MOVLW .9
     MOVWF PORTC
     CALL DEMORA
     MOVLW 0xFF
     MOVWF PORTC
     CALL DEMORA
     MOVF STATUS_TEMP,W
     MOVWF STATUS
     SWAPF W_TEMP,F
     SWAPF W_TEMP,W
     RETFIE

INICIO      BANCO1
            MOVLW 0xFF
            MOVWF TRISB
            CLRF TRISD
            CLRF TRISC
            BANCO0
            BSF INTCON,GIE
            BSF INTCON,RBIE
            BANCO0
            CLRF PORTD
            CLRF PORTC
            CALL MOSTRAR

MOSTRAR     MOVF LOC,W
            MOVWF PORTC
            MOVF VIS,W
            MOVWF PORTD
            CALL DEMORA
            MOVLW 0xFF
            MOVWF PORTC
            MOVLW 0xFF
            MOVWF PORTD
            CALL DEMORA
            return
           
;-------------------------------------------------------------
; Generado con PDEL ver SP  r 1.0  el 13/11/2011 Hs 10:40:28 a.m.
; Descripcion: Delay 3000000 ciclos
;-------------------------------------------------------------
DEMORA  movlw     .67       ; 1 set numero de repeticion  (C)
        movwf     PDel0     ; 1 |
PLoop0  movlw     .91       ; 1 set numero de repeticion  (B)
        movwf     PDel1     ; 1 |
PLoop1  movlw     .122      ; 1 set numero de repeticion  (A)
        movwf     PDel2     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
        decfsz    PDel2, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel1,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
        decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (C)
        goto      PLoop0    ; 2 no, loop
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.
;-------------------------------------------------------------

    END

  Me parece ver un error en tu código y sería el siguiente... dentro del programa principal, en la etiqueta INICIO, llamas a la función MOSTRAR. Cuando termina dicha función y retornas al programa principal, lo hace a la instrucción que sigue a "call MOSTRAR" -lo cual estaría bien- pero justamente lo que sigue es el bloque de la función MOSTRAR y por lo tanto cuando llegue al "return" no va a saber adonde retornar. Yo ordenaría el código de una manera diferente.

  Tal vez algo así...

Código: ASM
  1. org 0 goto inicio
  2. org 4
  3. ....
  4. ....
  5. ....
  6. ; todo el bloque de la interrupción
  7.  
  8. DEMORA
  9. .........
  10. ........
  11. .......
  12. ; todo el bloque de la función demora
  13.  
  14. MOSTRAR
  15. .........
  16. .........
  17. .........
  18. ;todo el bloque de la función mostrar
  19.  
  20. INICIO
  21. ...........
  22. ........
  23. .........
  24. .........
  25. LoopPrincipal
  26.   nop; no hace nada
  27.   nop; no hace nada
  28.   call MOSTRAR
  29.   goto LoopPrincipal; volver al loop principal
  30. end

  de esa manera podes repetir constantemente la función mostrar
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado timh

  • PIC10
  • *
  • Mensajes: 23
Re: Interrupcion no retorna, pic16f877a
« Respuesta #11 en: 14 de Noviembre de 2011, 00:07:42 »
Muchas gracias por toda su ayuda, ya todo va a la perfección. Solo una unica cosa que tengo duda ¿Hay alguna forma de saber de que pin RB4-RB7 provino la interrupción?, creo que lei que no era posible utilizar los pines para interrupciones individuales, pero ¿Se puede saber de que pin provino?

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Interrupcion no retorna, pic16f877a
« Respuesta #12 en: 14 de Noviembre de 2011, 00:20:08 »
  Hay que tener en cuenta que la interrupción se produce por cambio, o sea que tanto cambie el pin de 0 a 1 como de 1 a 0 se producirá una interrupción.

  Lo que si se puede hacer es testear como están los pines.
  Suponiendo que utilizas pulsadores a GND y por lo tanto resistencias de pull-ups, esto quiere decir que mientras no se tenga presionado ningún pulsador el valor en los puertos de entrada será un 1. Es decir desde RB4 a RB7 están en 1. Cuando presionas algún pulsador, el pin al cual esté conectado quedará a GND por ende en dicho pin habrá un 0 entonces para saber que swtich fue presionado se podría hacer algo así...

Código: ASM
  1. btfss portb,4
  2. goto presionado_4  ; si RB4 esta en 0
  3. btfss portb,5
  4. goto presionado_5 ; si RB5 esta en 0
  5. btfss portb,6
  6. goto presionado_6 ; si RB6 esta en 0
  7. btfss portb,7
  8. goto presionado_7 ; si RB7 esta en 0
  9. goto ninguno_presionado ; si ninguno estaba en 0 la interrupcion se debio a un suelte de switch

  Hay que tener en cuenta que los switch tienen lo que se denomina "rebote" por lo tanto conviene hacer una demora y luego leer cada bit para saber si realmente el switch sigue presionado o solamente fue un rebote
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado timh

  • PIC10
  • *
  • Mensajes: 23
Re: Interrupcion no retorna, pic16f877a
« Respuesta #13 en: 14 de Noviembre de 2011, 00:26:34 »
Jeje muchas gracias, ya todo quedo solucionado, la verdad que estoy muy agradecido con todos ustedes que se tomaron algo de su valioso tiempo en responder mis preguntas (algunas veces preguntas tontas xD), y me gustaria devolver el favor ayudando a otros con lo poco que se y que ire aprendiendo, de verdad muchisimas gracias a todos.
Saludos.


 

anything