;-------------------------------------------------
;
;Palabra de configuracion
;
;-------------------------------------------------
; __config 0xFFFD
__CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_OFF & _BOREN_ON & _LVP_ON & _CPD_OFF & _WRT_OFF & _CP_OFF
;-------------------------------------------------
;
; Definicion de variables
;
;-------------------------------------------------
W_TEMP EQU 0X21
STATUS_TEMP EQU 0X22
Cont1 EQU 0x23
Cont2 EQU 0x24
Cont3 EQU 0x25
Cont4 EQU 0x26
Cont1A EQU 0x27
Cont2A EQU 0x28
Cont3A EQU 0x29
Cont4A EQU 0x30
ContLED EQU 0x31
ContTMR EQU 0x32
FLAG EQU 0x33
;-------------------------------------------------
;
; Vectores de reset/interrupcion
;
;-------------------------------------------------
ORG 0x00
GOTO EMPEZAR
ORG 0x04
GOTO INTERRUPCION
;-------------------------------------------------
;
; Configuracion
;
;-------------------------------------------------
EMPEZAR
MOVLW 0x07
MOVWF CMCON
BSF STATUS, RP0 ; Banco 1
BCF STATUS, RP1
MOVLW b'11110000'
MOVWF TRISB ; Puerto B como entrada
CLRF TRISC ; Puerto C como salida
CLRF TRISD ; Puerto D como salida
MOVLW B'00000111' ; ------ Configuramos el option REG con disivor 1:64 y R PULL up
MOVWF OPTION_REG
MOVLW B'00101000' ; ------ Habilito Interrupcione por EXT
MOVWF INTCON
BCF STATUS, RP0 ; Banco 0
MOVLW B'11110000'
MOVWF PORTB
CLRF PORTC
CLRF PORTD
MOVLW D'16'
MOVWF Cont1A
MOVWF Cont2A
MOVWF Cont3A
MOVLW D'3'
MOVWF ContLED
MOVLW D'3'
MOVWF ContTMR
MOVLW D'99'
MOVWF TMR0
MOVF PORTB,W ;Leo el PORTB y limpio flags antes de activar las interrupciones.
BCF INTCON, RBIF
BCF INTCON, T0IF
BSF INTCON, GIE
;-------------------------------------------------
;
; Programa Principal
;
;-------------------------------------------------
INICIO
nop
GOTO INICIO
;-------------------------------------------------
;
; Tabla Hex - 7 segmentos
;
;-------------------------------------------------
TABLA
ADDWF PCL,F
RETLW B'00000000'
RETLW B'01011100' ; F
RETLW B'01111110' ; E
RETLW B'01001111' ;D
RETLW B'00110110' ;c
RETLW B'00011111'
RETLW B'01101111'
RETLW B'01101111'
RETLW B'01111111'
RETLW B'01100001' ;7
RETLW B'00111111'
RETLW B'00111011';5
RETLW B'01011001'
RETLW B'01101011';3
RETLW B'01101110'
RETLW B'01000001'
RETLW B'01110111'
;-------------------------------------------------
;
; Rutina de Interrupcion
;
;-------------------------------------------------
INTERRUPCION
MOVWF W_TEMP
SWAPF STATUS,W
MOVWF STATUS_TEMP
BTFSC INTCON,T0IF ;El orden aca es importante
GOTO INTERRUPCIONINT
BTFSC INTCON,RBIF
GOTO INTERRUPCIONEXT
RETORNA
SWAPF STATUS_TEMP,W
MOVWF STATUS
SWAPF W_TEMP,F
SWAPF W_TEMP,W
RETFIE
;-------------------------------------------------
;
; Rutina de interrupcion del PORTB
;
;-------------------------------------------------
INTERRUPCIONEXT
COMF PORTB,W ; Complemento , para saber si es que se solto el boton. Esto hace que si todas las entradas estan a 1 (1111 sin nada presionado) sean 0 y poder ver el flag Z
ANDLW 0xF0 ; Separo unicamente entradas
BTFSC STATUS,Z
GOTO INT_PORTB_SALIR ; Se solto el boton, no hay nada presionado, todas las entradas en 1111, asi que salgo
CLRF FLAG
BSF FLAG,7 ; Flag que entro aqui
MOVF ContTMR,W
IORWF FLAG,F ; Guardo el valor del contador en el nibble bajo, esto para no crear otro registro.
BCF INTCON, RBIE ; Desactivo interrupciones por PORTB asi no toma en cuenta cualquier rebote.
GOTO RETORNA
;-------------------------------------------------
;
; Rutina de interrupcion del TMR0
;
;-------------------------------------------------
INTERRUPCIONINT
BCF INTCON,T0IF
MOVLW D'99'
MOVWF TMR0
DECFSZ ContTMR,F ; Loop contador de interrupciones de timer
GOTO MANEJO_KBD
MOVLW D'3'
MOVWF ContTMR ; Si se cumplio lo recargo
MOVF ContLED,W ; Que display tengo que encender?
CALL TABLALED
DECFSZ ContLED,F ; Llego a 0? Lo recargo y vuelvo
GOTO MANEJO_KBD
MOVLW D'3'
MOVWF ContLED
MANEJO_KBD
BTFSS FLAG,0
GOTO RETORNA ; En caso de que no se activo el PORTB salgo
MOVLW 0x0F ; Separo el nibble que me interesa
ANDWF FLAG,W
SUBWF ContTMR,W ; Reviso si es igual
BTFSS STATUS,Z ; Si es igual entonces realizo mi codigo, sino
GOTO RETORNA
BCF FLAG,7 ; Borro flag
COMF PORTB,W ; Compruebo nuevamente que no sea 0, por si se solto muy rapido.
ANDLW 0xF0 ;
BTFSC STATUS,Z
GOTO INT_PORTB_AUX
MOVF Cont2A,W ; En caso de que realmente se haya presionado un boton
MOVWF Cont1A ; Rotacion del display
MOVF Cont3A,W
MOVWF Cont2A
CALL Ver_Teclado ; Veo que tecla se presiono
MOVWF Cont3A
MOVLW B'00000000' ; Pone a 0 el PORTB, esto implica que puede llegar a dispararse de nuevo la interrupcion o activarse el flag
MOVWF PORTB
INT_PORTB_AUX
BSF INTCON, RBIE ; Habilito la interrupcion nuevamente
INT_PORTB_SALIR
MOVF PORTB,W ; Leo asi me permite la limpieza del flag
BCF INTCON, RBIF ; Limpieza del flag
GOTO RETORNA
;-------------------------------------------------
;
; Funciones auxiliares de la interrupcion del TMR0
;
;-------------------------------------------------
TABLALED
ADDWF PCL,F
GOTO LED0
GOTO LED2
GOTO LED1
GOTO LED0
LED0
MOVF Cont1A,W
CALL TABLA
MOVWF PORTD
BCF PORTC,3 ; Acomode para que siempre desactive todo y luego active.
BCF PORTC,2
BSF PORTC,1
RETURN
LED1
MOVF Cont2A,W
CALL TABLA
MOVWF PORTD
BCF PORTC,1
BCF PORTC,3
BSF PORTC,2
RETURN
LED2
MOVF Cont3A,W
CALL TABLA
MOVWF PORTD
BCF PORTC,1
BCF PORTC,2
BSF PORTC,3
RETURN
;-------------------------------------------------
;
; Funciones auxiliares de la interrupcion del PORTB
;
;-------------------------------------------------
Ver_Teclado
BTFSS PORTB, 4 ; Fila 0
GOTO Fila0
BTFSS PORTB, 5 ; Fila 1
GOTO Fila1
BTFSS PORTB, 6 ; Fila 2
GOTO Fila2
GOTO Fila3 ; Fila 3 - No queda otra
Fila0
MOVLW B'00001110'
MOVWF PORTB
BTFSS PORTB, 4 ; Columna 3
RETLW D'15'
MOVLW B'00001101'
MOVWF PORTB
BTFSS PORTB, 4 ; Columna 2
RETLW D'12'
MOVLW B'00001011'
MOVWF PORTB
BTFSS PORTB, 4 ; Columna 1
RETLW D'9'
RETLW D'1'
Fila1
MOVLW B'00001110'
MOVWF PORTB
BTFSS PORTB, 5 ; Columna 3
RETLW D'14'
MOVLW B'00001101'
MOVWF PORTB
BTFSS PORTB, 5 ; Columna 2
RETLW D'11'
MOVLW B'00001011'
MOVWF PORTB
BTFSS PORTB, 5 ; Columna 1
RETLW D'8'
RETLW D'16'
Fila2
MOVLW B'00001110'
MOVWF PORTB
BTFSS PORTB, 6 ; Columna 3
RETLW D'13'
MOVLW B'00001101'
MOVWF PORTB
BTFSS PORTB, 6 ; Columna 2
RETLW D'10'
MOVLW B'00001011'
MOVWF PORTB
BTFSS PORTB, 6 ; Columna 1
RETLW D'7'
RETLW D'2'
Fila3
MOVLW B'00001110'
MOVWF PORTB
BTFSS PORTB, 7 ; Columna 3
RETLW D'6'
MOVLW B'00001101'
MOVWF PORTB
BTFSS PORTB, 7 ; Columna 2
RETLW D'5'
MOVLW B'00001011'
MOVWF PORTB
BTFSS PORTB, 7 ; Columna 1
RETLW D'4'
RETLW D'3'
END