jueves, 10 de diciembre de 2009

INTERRUPCION PIC16F84A

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
; Nombre: Demo de Interrupciones ^
; Que hace => Encender un LED en RB1, lo haremos dormir y ^
; despertarlo al accionar un pulsador en RB0/INT lo encenderá para ^
; hacerlo dormir hasta la siguiente interrupcion que lo apagará. ^
; --- Descripcion del circuito --- ^
; El pin 7 (RB1) conectado al anodo del LED, el catodo a masa. ^
; El pin 6 (RB0/INT) conectado a positivo a traves de R de 10K ^
; El pin 6 (RB0/INT) conectado a contacto pulsador, el otro a masa.^
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LIST P=16F84
#include
ACUM equ h'000C' ;se declara acum
STAT equ h'000D' ;se declara stat

#DEFINE BANCO0 BCF STATUS,5

Org 0x00 ;Posicion 0 de la Memoria de Programa (apuntador)
;Viene cuando hay una interrupcion.
goto inicio ;Va a la etiqueta INICIO

ORG 0x04 ;viene cuando hay una interrupcion
GOTO rsi ;salta a rutina de rsi que atiende la interrupcion
ORG 0X05

; ****Bits del registro OPTION *******************************
; bit8 = 0 Resistencias de polarización deshabilitadas
; bit7 = 0 Interrupción externa por flanco bajada (no usada)
; bit6 = 0 Fuente de reloj, interno (Usa TMR0 como temporizador)
; bit5 = 0 Flanco de señal externa (no lo usamos)
; bit4 = 0 Divisor asignado al TMR0
; bit3 = 1 bit2 = 1 bit1 = 0 División por 128
; *******************************************************

;---- Inicio ------
ini BSF status,RP0 ; configurando puertos
MOVLW 01 ; carga w con 0000 0001
MOVWF trisb ; RB0/INT es entrada
BCF option_reg,6 ; seleccionamos flanco descendente
BCF status,RP0
;---- Activa interrupciones ----
BSF intcon,GIE ; habilita todas las interrupciones
BSF intcon,INTE ; que sean interrupciones externas
CLRF portb ; limpia el puerto B
dormir SLEEP
GOTO dormir ; poner a dormir
;---- rutina servicio interrupciones
rsi BTFSC portb,0 ; verifica que se suelte el pulsador
GOTO rsi ; espera
; comenzamos guardando el contenido del W
MOVWF ACUM ; Copia el acumulador al registro acum
MOVF status,W ; Guarda STATUS en el acumulador
BANCO0 ; para restaurarlos antes de volver
MOVWF STAT ; Copia el acumulador al registro STAT

BTFSC portb,1 ; y ahora sí, si el led está a 1
GOTO off_led ; ir a off_led para apagarlo
BSF portb,1 ; sino, encender el LED
BCF intcon,INTF ; borrar bandera de interrupción
GOTO HECHO ; salta a restaurar valores
RETFIE ; antes de volver

off_led BCF portb,1 ; apaga el LED
BCF intcon,INTF ; borra bandera de interrupción
; Restauramos los valores del W y status
HECHO MOVF STAT,W ; Guarda el contenido de STAT en el W
MOVWF STATUS ; Restaura el STATUS
SWAPF ACUM,F ; Da la vuelta al registro ACUM
SWAPF ACUM,W ; Vuelve a dar la vuelta al registro ACUM
; y lo restaura

RETFIE ; retorna al programa principal
END

Fuente: http://www.hispavila.com/3ds/chipspic/interrupciones.html