Bueno, mi primer post! Aquí dejo un programa para el pic16f84 hecho por mi! No esta simulado en el proteus por lo que no se si funciona muy bien, pero bueno, lo revise y creo que esta bien! Lo dejo por si alguien no entiende muy bien la parte de interrupciones y necesite un ejemplo para guiarse!

Comenten si no entiende muy bien, encuentran un error, o solo dejen su opinión si les sirvió!

Enunciado:

1) Usted desea elaborar con el PIC16F84, un programa que permita controlar el funcionamiento de unas luces de navidad. Como podemos ver en el diagrama, hay un botón el cual si es presionado (usar interrupciones externas), cambia la forma de iluminación de las luces, las cuales tienen 4 diferentes formas de proyección:

a) Se encuentran todas encendidas
b) Se encuentran todas encendidas durante x segundos y luego se apagan todas durante otros x segundos
c) La mitad de las luces se encienden durante x segundos, mientras que la otra mitad se encuentran apagadas, y luego se apagan las luces que se encontraban inicialmente encendidas durante x segundos, y se encienden las que estaban apagadas.
d) Todas se encuentran apagadas.

Los botones que se encuentran en RA0 y RA1 permiten disminuir o aumentar la velocidad de encendido y apagado, es decir modifican el valor de x. Se poseen 4 diferentes velocidades, es decir, 4 diferentes valores de x: 0,5 seg, 1 seg, 1,5 seg y 2 seg.
NO PUEDE utilizar el retardo por TMR0 para realizar los tiempos de x.
Para evitar que se sobrecaliente el PIC y los LEDs, las luces solo pueden permanecer encendidas continuamente durante 1 hora, por lo que al llegar a este tiempo debe congelar el programa durante 10 minutos y luego continuar normalmente (durante este tiempo todos los botones quedan deshabilitados). Debe realizar estos retardos usando interrupciones por TMR0. Reloj externo de 0,5 segundos.
El programa esta configurado por default como todas las luces apagadas y un tiempo de 0,5 segundos.
Considerar los botones ideales


Codigo:

list p=PIC16F84A.INC
INCLUDE p16F84A.INC
CBLOCK ;Declarar las variables
AUX1
AUX2
TIEMP
TIPO
R_ContA ; Contadores para los retardos.
R_ContB
ENDC

ORG 0 ;Aca inicia el programa
GOTO INICIO
ORG 4 ;Aca llega si ocurre una interrupción
GOTO INTERRUPCION

INTERRUPCION:
BCF INTCON,7 ;Se deshabilitan las interrupciones
BTFSC INTCON,2 ;INTERRUPCION DEBIDO A TRM0
GOTO RTMR0
BTFSC INTCON,1 ;INTERRUPCION EXTERNA. Incrementa Tipo
GOTO REXTERNO

REGRESAR:
MOVLW B'10110000'
MOVWF INTCON
RETFIE

RTMR0:
CLRF INTCON
DECFSZ AUX1 ;COMO EL RETARDO ES DE 10 MIN, PARA LA HORA SON 6*10MIN.
;por eso mientras no se cumpla se reestablecen los 10 min
;Cuando pasen los 6, entonces se queda 10 minutos en descanso.
GOTO REESTABLECER

DESCANSO: ;Mientras esta aqui no funciona ninguno de los botones

MOVLW D'106'
MOVWF TMR0
CLRF PORTB ;SE APAGAN LOS LED's
AAA:
BTFSS INTCON,2
GOTO AAA
MOVLW D'6'
MOVWF AUX1 ;DESPUES DE ESTO EJECUTA REESTABLECER

REESTABLECER:
MOVLW D'106'
MOVWF TMR0
GOTO REGRESAR

REXTERNO:
MOVLW D'4'
SUBWF TIPO,0
BTFSC STATUS,Z
GOTO REESTABLECER_TIPO
INCF TIPO,1
GOTO REGRESAR

REESTABLECER_TIPO:
MOVLW D'1'
MOVWF TIPO
GOTO REGRESAR
INICIO:

BSF STATUS,RP0
MOVLW B'00000001'
MOVWF TRISB
MOVLW B'00010011'
MOVWF TRISA
MOVLW B'10101010' ;1:8
MOVWF OPTION_REG
BCF STATUS,RP0
CLRF PORTA
CLRF PORTB
MOVLW B'10110000'
MOVWF INTCON
MOVLW D'106' ; RETARDO DE 10 MIN.
MOVWF TMR0
MOVLW D'6'
MOVLW AUX1
MOVLW D'1'
MOVWF TIPO
MOVLW D'1'
MOVWF TIEMP

PROGRAMA:

MOVLW D'1' ;TODAS APAGADAS
SUBWF TIPO,0 ;el resultado se guarda en w
BTFSS STATUS,Z
GOTO TIPO2 ;esto quiere decir que tipo es diferente de 1
CLRF PORTB
BTFSC PORTA,1 ;rutina para comprobar si se oprime el boton
GOTO INCREMENTAR_TIEMPO
BTFSC PORTA,0
GOTO DECREMENTAR_TIEMPO
GOTO PROGRAMA

TIPO2:
MOVLW D'2' ;TODAS ENCENDIDAS
SUBWF TIPO,0
BTFSS STATUS,Z
GOTO TIPO3
MOVLW B'00111100'
MOVWF PORTB
BTFSC PORTA,1
GOTO INCREMENTAR_TIEMPO
BTFSC PORTA,0
GOTO DECREMENTAR_TIEMPO
GOTO TIPO2

TIPO3:

MOVLW D'3' ;TODAS ENCENDIDAS Y APAGADAS
SUBWF TIPO,0
BTFSS STATUS,Z
GOTO TIPO4
MOVLW B'00111100' ;las enciende
MOVWF PORTB

BTFSC PORTA,1
GOTO INCREMENTAR_TIEMPO
BTFSC PORTA,0
GOTO DECREMENTAR_TIEMPO
CALL TIEMPO

CLRF PORTB ;las apaga

BTFSC PORTA,1
GOTO INCREMENTAR_TIEMPO
BTFSC PORTA,0
GOTO DECREMENTAR_TIEMPO

CALL TIEMPO
GOTO TIPO3

TIPO4:

MOVLW D'4' ;Mitad y mitad
SUBWF TIPO,0
BTFSS STATUS,Z
GOTO TIPO4
MOVLW B'00101000'
MOVWF PORTB

BTFSC PORTA,1
GOTO INCREMENTAR_TIEMPO
BTFSC PORTA,0
GOTO DECREMENTAR_TIEMPO

CALL TIEMPO

MOVLW B'00010100'
MOVWF PORTB

BTFSC PORTA,1
GOTO INCREMENTAR_TIEMPO
BTFSC PORTA,0
GOTO DECREMENTAR_TIEMPO

CALL TIEMPO
GOTO TIPO4

GOTO PROGRAMA

TIEMPO:

MOVLW D'1'
SUBWF TIEMP,0
BTFSS STATUS,Z
GOTO TIEMPO2
CALL Retardo_500ms

TIEMPO2:

MOVLW D'2'
SUBWF TIEMP,0
BTFSS STATUS,Z
GOTO TIEMPO3
CALL Retardo_500ms
CALL Retardo_500ms


TIEMPO3:

MOVLW D'3'
SUBWF TIEMP,0
BTFSS STATUS,Z
GOTO TIEMPO4
CALL Retardo_500ms
CALL Retardo_500ms
CALL Retardo_500ms

TIEMPO4:

CALL Retardo_500ms
CALL Retardo_500ms
CALL Retardo_500ms
CALL Retardo_500ms

RETURN

INCREMENTAR_TIEMPO:
MOVLW D'4'
SUBWF TIEMP,0
BTFSS STATUS,Z
INCF TIEMP,1
INC1:
BTFSC PORTA,1 ;SI SE DEJA APRETADO EL BOTON
GOTO INC1
RETURN


DECREMENTAR_TIEMPO:
MOVLW D'1'
SUBWF TIEMP,0
BTFSS STATUS,Z
DECF TIEMP,1
DEC1:
BTFSC PORTA,0 ;SI SE DEJA APRETADO EL BOTON
GOTO DEC1
RETURN


Retardo_500ms:
CALL Retardo_200ms
CALL Retardo_200ms
CALL Retardo_100ms
RETURN

Retardo_200ms: ; La llamada "call" aporta 2 ciclos máquina.
movlw d'200' ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.
Retardo_100ms: ; La llamada "call" aporta 2 ciclos máquina.
movlw d'100' ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.

Retardos_ms:
movwf R_ContB ; Aporta 1 ciclo máquina.
R1ms_BucleExterno:
movlw d'249' ; Aporta Mx1 ciclos máquina. Este es el valor de "K".
movwf R_ContA ; Aporta Mx1 ciclos máquina.
R1ms_BucleInterno:
nop ; Aporta KxMx1 ciclos máquina.
decfsz R_ContA,F ; (K-1)xMx1 cm (cuando no salta) + Mx2 cm (al saltar).
goto R1ms_BucleInterno ; Aporta (K-1)xMx2 ciclos máquina.
decfsz R_ContB,F ; (M-1)x1 cm (cuando no salta) + 2 cm (al saltar).
goto R1ms_BucleExterno ; Aporta (M-1)x2 ciclos máquina.
return ; El salto de retorno aporta 2 ciclos máquina.