;---------------------CONFIGURO EL PIC--------------------------
__CONFIG _CP_OFF&_LVP_OFF&_WDT_OFF&_PWRTE_ON&_XT_OSC
LIST P=16F628A
#INCLUDE <P16F628A.INC>
;--------------------------------------------------------------
;----------------DECLARO LAS VARIABLES-------------------------
CBLOCK 0X20
UNIDAD
DECENA
CONT1
CONT2
CONT3
DIRECCION
DATOEE
FLAG
ENDC
;---------------------------------------------------------------
;--------------VECTORES DE RESET E INTERRUPCION-----------------
ORG 0x00
GOTO CONFIGURACION
ORG 0x04
RETURN
;---------------------------------------------------------------
;--------CONFIGURO LOS PUERTOS Y PONGO LAS VARIABLES EN 0-------
CONFIGURACION
BSF STATUS,RP0
CLRF TRISA
BCF OPTION_REG,NOT_RBPU
MOVLW B'00000001'
MOVWF TRISB
BCF STATUS,RP0
MOVLW D'7'
MOVWF CMCON
CLRF PORTB
CLRF DECENA
CLRF UNIDAD
CLRF DIRECCION
CALL LeeEEPROM
MOVF DATOEE,W
MOVWF UNIDAD
INCF DIRECCION,F
CALL LeeEEPROM
MOVF DATOEE,W
MOVWF DECENA
;--------------------BOTON---------------------------------------
;----------------------------------------------------------------
;-------------VERIFICO QUE NO LLEGUE A DIEZ----------------------
MAIN
CALL MOSTRAR_DISPLAY
CALL BOTON
GOTO MAIN
BOTON
BTFSC FLAG,0 ;Utilizo el bit este para saber si esta presionado el boton
GOTO BOTON_0
BTFSS PORTB,0 ;Pregunto si se presiono el boton
RETURN
BSF FLAG,0 ;Se presiono, para que no entre nuevamente utilizo un bit
INCF UNIDAD,F ; Incremento unidad, ahora me queda asegurarme que no este dentro del rango
MOVF UNIDAD,W ;W = Unidad
SUBLW 0x9 ;W = 9 - W , actualiza las flags C,DC y Z
BTFSS STATUS,C ;Si C=1 quiere decir que Unidad es mayor a 9
RETURN ; No supero asi que simplemente salgo
CLRF UNIDAD
INCF DECENA,F
MOVF DECENA,W ;W = Decena
SUBLW 0x9 ;W = 9 - W , actualiza las flags C,DC y Z
BTFSC STATUS,C ;Si C=0 quiere decir que Decena es menor a 9
CLRF DECENA ;Si es mayor lo borro y salgo
;Si es menor no hago nada
; Cambio las Unidades y Decenas asi que guardo
; Las unidades si o si por que cambian seguro, las decenas tal ves no
; Entonces primero leo y me aseguro que sea distinto
MOVF UNIDAD,W ;Procedo a grabar los datos, los grabo solo cuando se presiono
MOVWF DATOEE ; datoee = Unidad
CLRF DIRECCION ; Direccion = 0x00
CALL EscribirEEPROM ; Grabo
INCF DIRECCION,F ; Direccion = 0x01 (Decena)
CALL LeeEEPROM ; Leo
MOVF DATOEE,W ;
SUBWF DECENA,W ; W = Datoalmacenado - Decena
BTFSC STATUS,Z ; Z=1? es decir no cambio, entonces salgo
RETURN
; Z=0 quiere decir que cambio, entonces guardo decenas tambien
MOVF DECENA,W ; Procedo a grabar los datos, los grabo solo cuando se presiono
MOVWF DATOEE ; datoee = Decena, ya direccion esta en 0x01
CALL EscribirEEPROM ; Grabo
RETURN ;Salgo
BOTON_0 ; Caso que este presionado el boton ( lo sabemos por la flag )
BTFSS PORTB,0 ; Preguntamos asi cuando vuelve a 0 (solto el boton) podemos borrar el flag
BCF FLAG,0 ; Se solto el boton
RETURN ; Siguie presionado
;-----------------------------------------------------------------
;----------------------REALIZO EL CONTEO--------------------------
MOSTRAR_DISPLAY
CLRF PORTA ; pongo en 0 los catodos de los displays
MOVF UNIDAD,W ; Cargo el valor de las unidades en el puerto
CALL TABLA
MOVWF PORTB
BSF PORTA,0 ; Enciendo el primer display y espero mientras esta encendido
CALL RETARDO
BCF PORTA,0 ; Apago el primer display
MOVF DECENA,W
CALL TABLA
MOVWF PORTB
BSF PORTA,1 ; Enciendo el segundo display y espero
CALL RETARDO
RETURN
;------------------------------------------------------------------
;---------------------DECLARO LAS TABLAS---------------------------
TABLA
ADDWF PCL,1
RETLW B'01111110';0
RETLW B'00001100';1
RETLW B'10110110';2
RETLW B'10011110';3
RETLW B'11001100';4
RETLW B'11011010';5
RETLW B'11111010';6
RETLW B'00001110';7
RETLW B'11111110';8
RETLW B'11001110';9
RETURN
;----------------------------------------------------------------------
EscribirEEPROM:
MOVF DATOEE,W ; Cargo el valor a escribir
BSF STATUS,RP0 ; Banco 1
MOVWF EEDATA
BCF STATUS,RP0 ; Banco 0
MOVF DIRECCION,W ; Cargo direccion a escribir
BSF STATUS,RP0 ; Banco 1
MOVWF EEADR
BSF EECON1,WREN ; Habilitamos la escritura de la EEPROM
;Codigo obligatorio
BCF INTCON,GIE ; Desabilitamos interrupciones ya que afectarian la escritura
MOVLW 0x55 ; Una proteccion que posee la EEPROM, es que antes de escribir
MOVWF EECON2 ; debe escribirse los valores 0x55 y 0xAA en orden
MOVLW 0xAA
MOVWF EECON2
BSF EECON1,WR ; Finalmente podemos darle la orden que escriba en la EEPROM
;Fin codigo obligatorio
;BSF INTCON,GIE ; De usar interrupciones las habilitamos de nuevo
BCF STATUS,RP0 ; Banco 0
RETURN
LeeEEPROM:
MOVF DIRECCION,W ; CONFIG_ADDR = direccion del dato
BSF STATUS,RP0 ; Bank 1
MOVWF EEADR ; Direccion a leer
BSF EECON1,RD ; Avisamos que queremos leer asi EEDATA se carga con el valor
MOVF EEDATA,W ; ubicado en la direccion CONFIG_ADDR de la moemoria EEPROM
BCF STATUS,RP0 ; y guardamos en W, procedemos a volver al banco 0
MOVWF DATOEE
RETURN
;------------------------REALIZO EL RETARDO----------------------------
RETARDO
MOVLW .15
MOVWF CONT1
LOOP1
MOVLW .8
MOVWF CONT2
LOOP2
MOVLW .255
MOVWF CONT3
LOOP3
DECFSZ CONT3,1
GOTO LOOP3
DECFSZ CONT2,1
GOTO LOOP2
DECFSZ CONT1,1
GOTO LOOP1
RETURN
;-------------------------------------------------------------------------------------
END