LIST p=16F877A ; Directiva para iniciar el tipo de PIC
INCLUDE P16F877A.INC ; Definiciones de registros internos
__CONFIG _XT_OSC & _WDT_OFF & _LVP_OFF ; Cristal como oscilador, WDT OFF, Modo bajo consumo OFF
; Programa que haga un temporizador digital decimal con dos displays
; de 7 segmentos que vayan desde 0.0 a 9.9 y se reinicie
; Cada 20 veces 5ms es 0.1 s
DECIMAS EQU 0X20 ; Parametro para seleccionar el valor de las decimas que se muestra en el display 2
UNIDADES EQU 0X21 ; Parametro para seleccionar el valor de las decimas que se muestra en el display 2
CONTADOR EQU 0X30 ; Contador de repeticiones para hacer 0.1s con 5ms
DELAY1 EQU 0X31 ; Variables para la subrutina de retardo
DELAY2 EQU 0X32
DELAY3 EQU 0X33
ORG 0X00
GOTO INICIO
ORG 0X05 ; Salto vector de interrupciones
INICIO CLRF DECIMAS ; Limpio por si hubiera aglún valor metido
CLRF UNIDADES
CLRF PORTD ; Borramos el PORTD
CLRF PORTA
CLRW
BSF STATUS,RP0 ; Banco 1, poniendo a 1 el bit RP0 del STATUS
CLRW ; Movemos al acumulador W el valor 0X00 (0000 0000)
MOVWF TRISD ; Llevamos el valor del acumulador al TRISD, los pins
; puestos a 1 son Input y los puestos a 0 son Output, ponemos como salidas PORTD
MOVLW b'00000110' ;Definimos el PORTA
MOVWF ADCON1 ;con todas sus señales como digitales
MOVLW 0xF0 ; Movemos al acumulador W el valor 0XF0 (1111 0000)
MOVWF TRISA ; Llevamos el valor del acumulador al TRISA, los pins
; puestos a 1 son Input y los puestos a 0 son Output
BCF STATUS,RP0 ; Banco 0, poniendo a 0 el bit RP0 del STATUS
MOVLW 0x13 ; 19 veces tiene que pasar por el retardo de 5ms para ser 0.1s(100ms)
MOVWF CONTADOR
CONTAR CALL RETARDO5ms
DECFSZ CONTADOR,1 ; Si es 0 no ejecuta la siguiente intrucción
GOTO CONTAR
MOVLW 0X13 ; 19 veces tiene que pasar por el retardo de 5ms para ser 0.1s(100ms)
MOVWF CONTADOR
MOVLW .9 ; Se mueve el valor 10 a WREG, para ver si el número es mayor a 9
SUBWF DECIMAS,0 ; Se resta el valor de WREG (0x09) al valor de DECIMAS para ver si es mayor a 9
BTFSS STATUS,C ; Se comprueba si C=0 del registro STATUS, si hay prestamo c=0
; No está bien porque haria lo de borrar decimas despúes
GOTO FINAL ; Llama a la subrutina de incremento si aún no ha llegado a o
CLRF DECIMAS ; Limpia decimas si ha llegado a 9
INCF UNIDADES ; Incrementa las unidades
DECF DECIMAS
MOVLW .9
SUBWF UNIDADES,0 ; Comprueba si unidades ha llegado a 9
BTFSS STATUS,C ; Se resta el valor de WREG (0x09) al valor de UNIDADES para ver si es mayor a 9
GOTO FINAL ; Va al final
CLRF UNIDADES ; Limpia las unidades si llega a 9
FINAL CALL MOSTRAR ; Muestra valores
GOTO CONTAR ; Se repite
MOSTRAR
INCF DECIMAS ; Incrementa el valor de decimas
CALL TABLALEDD
CALL RETARDO5ms
CALL TABLALEDU
CALL RETARDO5ms
RETURN
;******************************************************************************
; Subrutina para el control de los displays
; Manda el código del dígito al PORTD y
; el código que activa el dígito al PORTA
;******************************************************************************
TABLALEDD ; Usa los valores cogidos del programa principal de decimales y unidades para representarlas con una subrutina
BCF PORTA,1
BSF PORTA,0 ; Pone a 1 el RA0 que activa el display 1
MOVF DECIMAS,0 ; Mueve decimas a tablaled
CALL TABLA1 ; Vamos a la tabla para volver en W con
MOVWF PORTD ; lo que hay que sacar por el Puerto D
RETURN
TABLALEDU
BCF PORTA,0 ; Apaga RAI 0
BSF PORTA,1
MOVF UNIDADES,0 ; Mueve unidades a tablaled
CALL TABLA1 ; Vamos a la tabla para volver en W con
MOVWF PORTD ; lo que hay que sacar por el Puerto D
RETURN
;SITUAMOS LA TABLA EN LAS POSICIONES INICIALES
;PARA ASEGURAR QUE LA PARTE ALTA DEL PC NO SE CAMBIA AL REALIZAR LA SUMA
TABLA1 ADDWF PCL,F ;Suma del PC con el dígito a representar (en W)
RETLW 0xC0 ;Para el cero
RETLW 0xF9 ;el uno
RETLW 0xA4 ;el dos
RETLW 0xB0 ;el tres
RETLW 0x99 ;el cuatro
RETLW 0x92 ;el cinco
RETLW 0x82 ;el seis
RETLW 0xF8 ;el siete
RETLW 0x80 ;el ocho
RETLW 0x98 ;el nueve
;******************************************************************************
;* Subrutina de Espera de 5ms (aprox.) mediante 3 bucles anidados
;* Ciclos máquina = 3nmp+4mp+4p +1
;* Con p=1, m=10 y n=165 salen 5000 ciclos máquina (aprox.)
;* Como fosc = 4 MHz ? Ciclo máquina = 1 ?s
;******************************************************************************
RETARDO5ms:
MOVLW 0x01 ; Cargamos dos contadores,
MOVWF DELAY1 ; uno con (p = 0x01)
BUCLE1 MOVLW 0x0A ; otro
MOVWF DELAY2 ; con (m = 0x0A, 10)
BUCLE2 MOVLW 0xA5 ; y el otro
MOVWF DELAY3 ; con (n= 0xA5)
BUCLE3 DECFSZ DELAY3,F
GOTO BUCLE3
DECFSZ DELAY2,F
GOTO BUCLE2
DECFSZ DELAY1,F
GOTO BUCLE1
RETURN ; Final de la subrutina de espera
END ; Fin del programa fuente