; Cada vez que presiona el pulsador conectado a la línea RA4 conmutará el estado de
; un Led conectado a la línea RB1.
;
; ZONA DE DATOS **********************************************************************
    LIST        P=16F886
    INCLUDE        <P16F886.INC>
    __CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_ON & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _EC_OSC
    __CONFIG    _CONFIG2, _WRT_OFF & _BOR21V 
    ERRORLEVEL -302    
    CBLOCK 0x110
    Dato
    ENDC
Direccion    EQU    0x10
#DEFINE Pulsador    PORTA,0        ; Pulsador conectado a RA4.
#DEFINE Led            PORTB,0        ; Línea donde se conecta el diodo Led.
; ZONA DE CÓDIGOS ********************************************************************
    ORG    0x2100
    DE 0x00
    
    ORG    0                        ; El programa comienza en la dirección 0.
Inicio
    clrf     PORTB                ;Borra los latch de salida
    BANKSEL    ANSEL
    clrf    ANSEL                ;Puerta A digital
    clrf    ANSELH                ;Puerta B digital
    BANKSEL    TRISB
    clrf    TRISB                ;RB7:RB0 se configuran como salida
    movlw    b'11111111'        
    movwf    TRISA                ;RA5:RA0 se configuran como entrada
    call    Lee_EEPROM
    BANKSEL    PORTA
        ;;;;;;; Recupera estado del Led de la EEProm
        andlw  b'00000001'  ;;;;;;;
        btfsc  STATUS,Z     ;;;;;;;
        goto   Led_off      ;;;;;;;
Led_on
        bsf Led ; Estaba encendido.;;;;;;;
        goto   Principal    ;;;;;;;
Led_off       
        bcf Led ; Estaba apagado.;;;;;;;
        BANKSEL TRISB   ;;;;;;;;;;;;;;;
        bcf Led ; Activar como salida Led con estado EEProm.;;;;;;;
        BANKSEL PORTA ; Vuelve al banco 0. ;;;;;;; 
Principal
    btfsc    Pulsador            ; ¿Pulsador presionado?, ¿(Pulsador)=0?
    goto    Fin                    ; No. Vuelve a leerlo.
;    call    Retardo_20ms        ; Espera que se estabilicen los niveles de tensión.
    btfsc    Pulsador            ; Comprueba si es un rebote.
    goto    Fin                    ; Era un rebote y sale fuera.
;    call    Retardo_20ms        ; Espera que se estabilicen los niveles de tensión.
    btfsc    Led                    ; Testea el último estado del Led.
     goto    EstabaEncendido
EstabaApagado
    bsf        Led                    ; Estaba apagado y lo enciende.
    call    Escribe_EEPROM
    goto    EsperaDejePulsar
EstabaEncendido
    bcf        Led                    ; Estaba encendido y lo apaga.
    call    Escribe_EEPROM
EsperaDejePulsar
    btfss    Pulsador            ; ¿Dejó de pulsar?. ¿(Pulsador)=1?
    goto    EsperaDejePulsar    ; No. Espera que deje de pulsar.
Fin
    goto    Principal
;Subrutina EEPROM**********************************************************************+
Lee_EEPROM
    BANKSEL EEADR ;
    MOVLW     Direccion ;
    MOVWF     EEADR ;Data Memory
;Address to read
    BANKSEL EECON1 ;
    BCF     EECON1, EEPGD ;Point to DATA memory
    BSF     EECON1, RD ;EE Read
    BANKSEL EEDAT ;
    MOVF     EEDAT, W ;W = EEDAT
    BCF     STATUS, RP1 ;Bank 0
    return
Escribe_EEPROM
    BANKSEL EEADR ;
    MOVLW     Direccion ;
    MOVWF     EEADR ;Data Memory Address to write
    MOVLW     Dato ;
    MOVWF     EEDAT ;Data Memory Value to write
    BANKSEL EECON1 ;
    BCF     EECON1, EEPGD ;Point to DATA memory
    BSF     EECON1, WREN ;Enable writes
    BCF     INTCON, GIE ;Disable INTs.
    BTFSC     INTCON, GIE ;SEE AN576
    GOTO     $-2
    MOVLW     0x55
    MOVWF     EECON2 ;Write 55h
    MOVLW     0xAA
    MOVWF     EECON2 ;Write AAh
    BSF     EECON1, WR ;Set WR bit to begin write
    BSF     INTCON, GIE ;Enable INTs.
;SLEEP ;Wait for interrupt to signal write complete
    BCF     EECON1, WREN ;Disable writes
    BCF     STATUS, RP0 ;Bank 0
    BCF     STATUS, RP1
    return
    INCLUDE <RETARDOS.INC>
    END