Bueno, exactamente no se que les dio su profesora, vos llegaste con el problema de crear una interrupcion del timer0 e ir sumando una variable 1 en 1, y eso es lo que intentamos hacer. No hay distintas formas de hacerlo por interrupcion, hay normalmente 1 sola. Lo que voy a decirte ahora es exactamente sobre INTERRUPCION. Lo que seguro tu profesora llamo interrupcion es leer el flag del modulo, que no es lo mismo.
Lo que yo te digo no es por capricho, es el funcionamiento del microcontrolador. Este seria un formato de programa en ASM, y que lo vas a ver por todos lados:
; Fuses/ Config
;Include
;Aca nombras los registros necesarios
;Vectores
ORG 0x00
GOTO INICIO
ORG 0x04
GOTO INTERRUPCION
INICIO:
; Aca setup de los modulos: puertos/timers/etc
; Inicializas los registros que sean necesario hacerlos
PRINCIPAL:
; Programa Principal
GOTO PRINCIPAL ;Principal caracteristica que es un loop infinito es decir esta siempre encerrado
INTERRUPCION
; Aca guardo contexto, es decir W,STATUS,PCLATH para que al final de la interrupcion los vuelva a cargar
; Aca es el codigo de la interrupcio
; Vuelvo a dejar W, STATUS y PCLATH como estaban antes de entrar a la interrupcion
RETFIE
Observaras que si seguis la linea del programa jamas llegaria a "interrupcion", y se quedaria haciendo solo lo de Principal. Y esto es lo que hace el micro, es decir se queda haciendo lo de principal una y otra ves hasta que ocurre una interrupcion.
Cuando ocurre una interrupcion, El PC ( Program Counter) es decir lo que apunta la instruccion a ejecutar pasa a valor 0x04, y es ahi donde entra a la interrupcion realiza esta y luego sale, pero sale y vuelve donde estaba el programa. Suponete algo bastante simple.. Voy a hacer un programa que es erroneo para que veas cual es el error y por que te estoy pidiendo lo que te pido.
Voy a obviar cosas como el setup de modulos para hacerlo lo mas simple posible y vamos a suponer que es un timer el que lo manda a la interupcion ( habilitado/configurado y todo) solo que no lo pongo para llegar rapido al asunto. Este es el programa:
ORG 0x00
GOTO INICIO
ORG 0x04
GOTO INTERRUPCION
INICIO:
BCF STATUS, Z
PRINCIPAL:
BTFSC STATUS, Z
BSF PORTB, 0
GOTO PRINCIPAL
INTERRUPCION
BSF STATUS, Z
RETFIE
Un programa bien realizado ( guardar W,STATUS,etc en la interrupcion) nunca se pondria RB0 a 1. Pero aca si. Vamos a ir paso por paso para ver que esta pasando.
Comienza el programa, se configuran todos los modulos, se activan las interrupciones, pongo la bandera Z en 0, Y entra en principal, lo cual va a estar preguntando si la bandera es 0 o no, Si es 0 salta, asi que va a estar saltando siempre. Es decir se ecutaria el BTFSC, "salta" es decir el PC se carga con la direccion de memoria donde esta el GOTO, Se ejecuta el GOTO poniendo en el PC la direccion de memoria del BTFSC y se queda alli.
Ahora esta la interrupcion. Supongamos que el GOTO esta en la direccion de memoria 0x100, y es la proxima instruccion a ejecutar por lo cual el PC tiene el valor 0x100, ocurre una interrupcion y el micro guarda esa direccion ( 0x100 ) en un STACK, una pila. (Parecido a lo que ocurre con un CALL) Y pone en el PC la direccion del vector de interrupcion 0x04, Es decir que pasa a ejcutar ese GOTO Interrupcion. Continuando la ejecucion se ejecuta el BSF STATUS,Z y pone a 1 Z, finalmente el RETFIE.
El RETFIE es como un RETURN, pero que ademas pone el bit GIE ( interrupcion global ) en 1, es decir vuelve a habilitar las interrupciones. Lo que hace este RETURN/RETFIE es sacar la ultima direccion de la pila ( 0x100 ) y volverla a poner en el PC.
Genial, Volvimos a nuestra rutina principal, se ejecuta el GOTO principal y llegamos al BTFSC, pero ups, esta ves Z esta en 1, lo cual NO DEBERIA. y pondria RB0 en 1.
Entonces como solucionas esto?, ocurre si guardas todos los bits de STATUS al entrar la interrupcion, haces lo que quieras dentro de la interrupcion donde se van a modificar todos o algunos, y luego cuando vas a salir de la interrupcion recuperas eso que guardaste dejando el STATUS como estaba ANTES de entrar a la interrupcion.
Por que se hace esto ? Se lo hace por que la interrupcion puede ocurrir en cualquier lado.
Que tal si hago mi rutina principal asi?:
PRINCIPAL:
BCF STATUS, Z
BTFSC STATUS, Z
BSF PORTB, 0
GOTO PRINCIPAL
Existe la posibilidad que luego de ejecutarse el BCF, se produzca una interrupcion y aun asi se ponga en 1 RB0.
Lo mismo ocurre con W, pero puede ser aun mas "devastador". Suponete algo asi:
MOVLW 0x10
ADDWF VARIABLE1
Vos pensaras que siempre ocurriria que Variable1 se le van a sumar 0x10, pero si entra a la interrupcion luego de ejecutarse el MOVLW, y al salir de la interrupcion tenes un W en 0x50, le estarias sumando 0x50 y no 0x10.
Por eso mismo se realiza lo que te decia.
Otra de las cosas si te fijas en el "formato" que te di es que no hay una conexion entre el programa de la interrupcion y el programa principal que se ejecuta siempre. Es decir no se llaman entre uno u otro. Son como 2 programas apartes.
Tenes que entender que esto funciona de esta forma:
Se va a estar ejecutando el programa principal continuamente, lo unico que puede sacarlo de ese estado es una interrupcion, lo cual va a ejecutar otro codigo aparte, y luego va a volver a la rutina principal.
----------------------------------------------------------------------------------------------------
Lo que decia que tu profesor puede haber llamado interrupcion es simplemente leer el flag del modulo, lo cual no es una interrupcion pero que algunos por desconocimiento le dicen asi. Y el programa se simplifica
ORG 0x00
GOTO INICIO
ORG 0x04
RETURN
INICIO:
;Configuro modulos
PRINCIPAL:
BTFSS INTCON, TMR0IF ;Pregunto por el flag del Timer0, si esta en 1 desbordo
GOTO PRINCIPAL
MOVLW 0x00 ;Cargo el TIMER0
MOVWF TMR0
BCF INTCON, TMR0IF ; Limpio flag del TIMER0, asi se cuando rebalso
;Aca hago lo que tengo que hacer
GOTO PRINCIPAL ; Vuelvo al comienzo esperando por que el TMR0 desborde nuevamente
Observaras que en el vector de interrupcion puse un RETURN, esto es una proteccion por si activas sin querer la interrupcion. En este caso solamente estoy leyendo el flag del TIMER0, que se activa cuando desborda. Ese flag se pone a 1 por mas que no esten activadas las interrupciones.
Lo unico que hace el activar la interrupcion es dar paso a ese 1 al nucleo de microcontrolador para que vaya a 0x04, nada mas. Si esta desactivada la interrpucion se bloquea ese camino, pero el flag se sigue poniendo a 1.
----------------------------------------------------------------------------
Para finalizar todo esto esta en el datasheet explicado, esto y mucho mas. Me refiero al comportamiento del micro ante las instrucciones y eventos como las interrupciones.