Autor Tema: Ayuda a hacer interrupciones con RB  (Leído 2502 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado GerardoTrejo

  • PIC10
  • *
  • Mensajes: 2
Ayuda a hacer interrupciones con RB
« en: 10 de Julio de 2017, 17:16:25 »
Hola buenas tardes he estado tratando de hacer uso de las interrupciones Rb4-Rb7con un Pic 16f877A  pero parece que no salta al vector de interrupcion.
Mi duda es : al hacer una interrupcion con int0 o Rb0 se debe configurar si responde al flanco de subida o de bajada, ¿será eso lo que estoy haciendo mal?.
Les anexo mi código para que lo revisen y me hagan algún comentario, muchas gracias por su ayuda
-------------------------------------------------------------------------
LIST p=16F877A
INCLUDE <P16F877A.INC>
ORG 0X00
GOTO SET_UP
ORG 0X04
BTFSC PORTB,4
GOTO RUTINA_INT4
BTFSC PORTB,5
GOTO RUTINA_INT5
BTFSC PORTB,6
GOTO RUTINA_INT6
GOTO RUTINA_INT7
CBLOCK 0X20
cont_1
cont_2
cont_3
INTER
ENDC

SET_UP
BCF STATUS,RP1; 0|1
BSF STATUS,RP0; banco 1
CLRF TRISC
CLRF TRISD
MOVLW 0XFF
MOVLW TRISB
MOVLW 0X88; GIE on y HABILITAR LAS INTERRUPCIONES DE RB4--RB7
MOVLW INTCON
BSF OPTION_REG,INTEDG;   flancos de subida
BCF STATUS,RP0; banco 0
CLRF PORTC
GOTO MAIN


MAIN
MOVLW 0XFF
MOVWF PORTC
CALL RETARDO_1S
CLRF PORTC
CALL RETARDO_1S
GOTO MAIN


RUTINA_INT4
CLRF PORTC
BSF PORTD,0
CALL RETARDO_1S
CLRF PORTD
BCF INTCON,RBIF
RETFIE

RUTINA_INT5
CLRF PORTC
BSF PORTD,1
CALL RETARDO_1S
CLRF PORTD
BCF INTCON,RBIF
RETFIE

RUTINA_INT6
CLRF PORTC
BSF PORTC,2
CALL RETARDO_1S
CLRF PORTC
BCF INTCON,RBIF
RETFIE

RUTINA_INT7
CLRF PORTC
BSF PORTC,3
CALL RETARDO_1S
CLRF PORTC
BCF INTCON,RBIF
RETFIE


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Ayuda a hacer interrupciones con RB
« Respuesta #1 en: 10 de Julio de 2017, 19:59:49 »
Voy a tratar de simplificar los problemas y no tratar de explicarlos a todos. Eso te lo dejo a vos.

Citar
Mi duda es : al hacer una interrupcion con int0 o Rb0 se debe configurar si responde al flanco de subida o de bajada, ¿será eso lo que estoy haciendo mal?.

La interrupcion del PORTB de RB4 a RB7 es por nivel y no por flanco, es decir si estaba en 1 y paso a 0, o si estaba en 0 y paso a 1 ambos van a disparar la interrupcion.
Por ende si supones que tenes 4 botones desde RB4 a RB7 , cuando presiones 1 va a entrar a la interrupcion y cuando lo soltes va a entrar tambien.

Eleminar el flag de esta interrupcion, realmente no recuerdo cual es la condicion suficiente para poder quitarlo, se que uno debe leer el puerto para poder borrar el flag, si uno no lo lee, el flag sigue en 1, lo cual siempre esta en la interrupcion.

Citar
Les anexo mi código para que lo revisen y me hagan algún comentario, muchas gracias por su ayuda

Encuentro varios problemas:

- El primero y muy importante es que no guardas contexto y lo restableces al entrar y salir respectivamente de la interrupcion.
  Esto esta explicado en el datasheet, un resumen de esto es:
  Cuando se genera una interrupcion deberias guardar STATUS y W en registros auxiliares, y luego al salir deberias restablecerlos, asi el codigo que se ejecuta en tu loop infinito (main) sigue trabajando con los mismos valores.
  El datasheet te da el codigo de inicio de la interrupcion y cuando tenes que salir de la misma, Tu codigo debe pasar por esto siempre, busca en el datasheet W_TEMP que suele ser el nombre que usa Microchip siempre para el registro auxiliar de W en estos casos.

- Como comentario, es no poner un CBLOCK entre el codigo, sino ponerlo arriba de los vectores de reset e interrupcion.

- Debido a que no sabias como funciona la interrupcion del PORTB de RB4 a RB7, tenes que si ninguna de las entradas esta en 0, va a ir si o si a Rutina_int7 lo cual seguramente sea un error, ya que podrias haber soltado todos los botones.

- Nunca pero NUNCA pongas algo que demora demasiado en una interrupcion, SIEMPRE pensa que la interrupcion es hacer algo rapido y salir, Asi que los delays dentro de la interrupcion deberias quitarlos. Si queres hacer algo con tiempo entonces mejor usa un registro mas y por ejemplo activa el bit0 para indicar que ocurrio la interrupcion. Luego en tu main Lees ese registro y encendes o apagas tu salida con las demoras que vos quieras.
 Esto es debido que cuando se encuentra en una interrupcion no hay forma de salir de alli, ya que al entrar a la interrupcion se desactivan las interrupciones hasta el RETFIE, por lo tanto es mala practica, simplemente respeta lo que puse al comienzo de este punto. Lo mismo va con escribir en LCD entre otras cosas.

- Imagino que antes de borrar el flag, deberias leer el PORTB completo, con un MOVF PORTB, W y de alli borrar el flag, ya que no recuerod si el BTFSS/C es valido como "lectura" del PORTB.

Desconectado Pinolillo16

  • PIC18
  • ****
  • Mensajes: 324
Re:Ayuda a hacer interrupciones con RB
« Respuesta #2 en: 10 de Julio de 2017, 22:04:49 »
Gerardo, como el código no esta mal. Parece que solo quieres saber como funcionan las interrupciones, los flancos no tienen que ver con RBIF. Como lo menciono KillerJC solo es por cambio de estado, si por alguna razon se activa una interrupcion por otro medio o periferico ira directo a tu rutina INT7. Lo que te sugiero es:

En el vector de reset:

0RG 0X04
BTFSS   INTCON,RBIF
RETFIE
BTFSS   PORTB,X

Con esto, sabras que si entro por cambio de estado. De lo contrario se puede estar desbordando el timer o alguna otra interrupción y puede causar error. Desde mi punto de vista es lo primero que debes hacer, asegurarte de que si esta entrando al ISR vector por donde tu lo has configurado.

Retomando el comentario de Killer, en aplicaciones reales es muy complicado que requieras retardos para atender rutinas, y lo de guardar registros W,STATUS y PCL al entrar y regresarlos al estado orginal antes de salir es inprecindible.

Saludos

Desconectado GerardoTrejo

  • PIC10
  • *
  • Mensajes: 2
Re:Ayuda a hacer interrupciones con RB
« Respuesta #3 en: 11 de Julio de 2017, 00:40:18 »
muchas gracias por su ayuda, ya he podido echar andar las interrupciones....