Voy a tratar de simplificar los problemas y no tratar de explicarlos a todos. Eso te lo dejo a vos.
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.
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.