Mi problema son las interrupciones, no logro entender como en medio de la ejecucion de un programa se lee el estado en un pin del micro y ejecuta otra tarea segun este programado. Vi muchos ejemplos y todos con RB.0 y quiero aprender a que ademas de ese pin me lea otros ya sea en puerto A o B.
Yo te puedo responder algunas cosas, pero nada de BASIC. Pero espero que con lo que diga te resuelva las dudas y puedas ver los ejemplos de otra forma.
Primero en principal:
No todos los pines tienen interrupcion, la interrupcion es algo realizado en hardware por el micro, lo mas comun de ver es que tengan interrupcion por flanco en RB0, es decir cuando hay un flanco ascendente ( de 0 a 1 ) o descendente ( de 1 a 0 ) en el estado del pin, Otra fuente de interrupcion en los pines suele estar en RB4 a RB7 ( esos 4 pines) estas interrupcion son POR NIVEL. Cuando cambie una no importa si pasa de 0 a 1 , o de 1 a 0 entra a la interrupcion, es 1 interrupcion para los 4 pines. Asi que es tu deber saber que pin cambio.
Hay varios modulos mas que tienen interrupciones, como los timers en el que cuando llegan a 0xFF ( o 0xFFFF en caso de 16bits ) y pasan a 0x00 se activa el flag de interrupcion.
Sabiendo que interrupciones tiene tu micro, ahora tenes que entender como es que funcionan. Cuando se produce una interrupcion se activa el flag de interrupcion de la misma (esta no depende de si esta habilitada la interrupcion o no), unicamente si esta habilitada la interrupcion esta pasa al nucleo del microcontrolador.
El microcontrolador al recibir esa señal, internamente guarda la posicion de memoria ( direccion de la instruccion que iba a ejecutar ) en un STACK, y procede a ir al vector de interrupcion, en ese vector vas a tener tu programa de la interrupcion, al salir de la interrupcion, recupera esa direccion que habia guardado y sigue desde alli. Entonces pareciera que las cosas se ejecutan al mismo tiempo, cuando en realidad se entra a la interrupcion cuando ocurre algun evento y luego se vuelve al programa principal.
Voy a intentar usar un ejemplo encontrado por internet:
x = 225
trisa = 0
trisa = a
intcon.inte = 1
enable
LOOP:
GOTO LOOP
porta = x
x = x - 1
intcon.intf = 0
RESUME
Observamos que activa la interrupcion externa ( RB0 ) el cual el bit es el INTE del registro INTCON, podria haber tambien modificado en que flanco lo deseaba, supongamos un boton cuando lo suelta, otra cosa es que nunca se pregunta por RB0, por que esto se hace por hardware como decia. Observaras tambien que su programa principal no es mas que un loop infinito sin ninguna instruccion dentro. Es decir que el programa se queda ahi hasta que el hardware del pin RB0 detecta ese flanco y le avisa al micro, entonces ahi es donde guarda donde estaba y entra a la interrupcion, realiza lo que debe realizar y al final de la interrupcion limpia el flag de interrupcion.
¿Que ocurre si no limpias el flag?
Cuando se ejecute el resume deberia volver el programa principal, pero como el flag sigue activo sigue pidiendole al micro entrar a la interrupcion, en resumen nuca saldria de la interrupcion, por eso es necesario poner el flag en 0.
Supongamos que tenes mas de una interrupcion, por ejemplo la de RB0 y la de RB4a7, ¿ como haces ?, en la rutina de interrupcion haces lo siguiente:
On interrupt
Flag de interrupcion de RB0 en 1 ?
Si -> Hago lo que debo hacer cuando ocurre la interrupcion de RB0, y limpio el flag
No->No hago nada
Flag de interrupcion de RB4a7 en 1?
Si -> hago lo que debo hacer cuando ocurre la misma y limpio el flag
No -> No hago nada
Salgo de interrupcionYo quiero leer los pines RB1,2 y 3 y que entren a la interrupcion cuando se pongan en 1!.
NO SE PUEDE, esos pines NO poseen interrupcion, Se puede realizar algo "parecido" y extensible a todos los pines, en el que usas un timer para generar una interrupcion cada tanto. Y cuando entra a la interrupcion del timer verificas que todos los pines sean iguales a la anterior ves que entro, si hay alguno distinto, sabes que uno cambio y actuas en consecuencia.
Esto no es lo mismo que los casos anteriores, los casos anteriores que se usa el mismo hardware que provee el micro, apenas se produce el evento que dispara la interrupcion entra a la misma, lo cual podes pensarlo como que una interrupcion es un evento que debe atenderse rapidamente y apenas ocurre.
¿ Que ocurriria si el programa esta dentro de una interrupcion y ocurre otra ?
Cuando el micro entra a la interrupcion, deshabilita las interrupciones ( especificamente pone a 0 el GIE por si solo ) asi que no va a atender la otra interrupcion hasta que salgas de la misma, cuando salgas de la interrupcion con el resume, este solo pone un 1 en el GIE, activandolas de nuevo y que si hay una esperando va a entrar nuevamente a la interrupcion.
Esto quiere decir que si usas un delay ( WaitMs por ejemplo ) dentro de la interrupcion, estas inhabilitando a cualquier otra interrupcion. Y por lo tanto cualquier instruccion ( LCD, delays, etc) que dure mucho tiempo o quede esperando DENTRO de la interrupcion esta prohibido, tu interrupcion debe ser rapida, entrar hacer las cosas y salir, si queres enviar un mensaje por LCD supongamos cuando se detecta la interrupcion de RB0, lo que haces en la interrupcion es poner una variable ( de 1 bit casi siempre ) a 1, y luego en tu loop principal lees esa variable y envias el mensaje al LCD.
-----------
Espero que te haya contestado varias preguntas acerca de las interrupciones, lamentablemente no puedo ser de ayuda en la parte de BASIC.