;+------------------------------------------------+ ;| Ejemplo 4 (LED PARPADEANTE por INTERRUPCIONES) | ;| LED conectado a RB1 ( PORTB: xxxx - xxLx ) | ;| Calcula el tiempo con el temporizador pero no | ;| utiliza interrupciones | ;| | ;| Autor: Andrés Prieto-Moreno | ;| 14 - 11 - 2002 | ;| Revisión: Alfonso Alejandre | ;| 13 - 12 - 2002 | ;+------------------------------------------------+ ; código preparado para el 16F877 o el 16F84 se debe asignar un valor a PROC #DEFINE PROC 1 ; 1 = Procesador 16F877, otro valor Procesador = 16F84 IF PROC == 1 list p=16f877, r=dec ; Indicamos procesador destino y radix #include p16f877.inc ; Define gran cantidad de constantes ; relacionadas con este procesador __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_ON & _CPD_OFF ELSE list p=16f84, r=dec ; Indicamos procesador destino y radix #include p16f84.inc ; Define gran cantidad de constantes ; relacionadas con este procesador __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC ENDIF #define BANCO_1 bsf STATUS,RP0 #define BANCO_0 bcf STATUS,RP0 ; constantes del programa TIEMPO equ 0x30 ; posicion de memoria TICKS equ 20 ; Ticks entre parpadeo 20 ; empieza el programa org 0 nop ; Este byte está reservado para el ICD goto Inicio ; ****************************************** ; * RUTINA de INTERRUPCIÓN GENERAL * ; ****************************************** org 4 btfss INTCON,T0IF ; ¿ la interrupción es por el timer ? retfie ; NO -> olvídala, devuelve el control goto Int_timer ; SI -> ve a la rutina de ateción ; ****************************************************************** ; * A continuación de la rutina de interrupción empieza el programa * ; ****************************************************************** ; Accedemos al segundo banco RAM de Datos Inicio BANCO_1 ; Configuración puertos movlw B'00000001' movwf TRISB ; Bit 0 de PORTB entrada, el resto como salida ; Configuración del Timer 0 movlw b'01010111' ; bit 7 = 0 (Desactivar resistencias Pull-up de PORTB) ; bit 6 = 1 (Entrada RB0/INT activa por flanco de subida) ; bit 5 = 0 (Reloj interno, un pulso por cada 4 ciclos de reloj) ; bit 4 = 1 (Entrada de reloj activa por flanco de subida) ; bit 3 = 0 (Prescaler asignado al Timer 0) ; bits 2..0 = 111 (Prescaler = 256) ; Con un cristal de 4 MHz. se recibe un pulso cada 256 microSeg. movwf OPTION_REG ; Accedemos al primer banco de RAM BANCO_0 ; Pongo a cero el puerto B clrf PORTB movlw TICKS ; tiempo_espera = TICKs * t_tic movwf TIEMPO ; guarda valor en memoria bsf INTCON,GIE ; activa las interrupciones bsf INTCON,T0IE ; activa interrupción del timer ; ********************************** ; * empieza el programa principal * ; ********************************** Bucle ; codigo del programa goto Bucle ; ******************************** ; * RUTINAS DE INTERRUPCION * ; ******************************** ; RUTINA DE INTERRUPCION DEL TIMER Int_timer decfsz TIEMPO,F ; ¿ TIEMPO=0 ? goto Sal_int ; no -> sigue contando movf PORTB,W xorlw 2 ; hace parpadear LED al invertir la línea RB1 movwf PORTB movlw TICKS ; tiempo_espera = TICKs * t_tic movwf TIEMPO ; guarda valor en memoria Sal_int movlw 178 ; 256-178= 78 pulsos en Timer0 para desbordarse ; 78 pulsos * 256 microSeg. por pulso = 20 mS. aprox. movwf TMR0 ; t_tic = 20 mseg bcf INTCON,T0IF ; borra el flag de interrupción retfie ; devuelve el control al programa END