list P=16F877A ;Comando que indica el Pic usado
#include "p16F877A.inc" ;Etiquetas genéricas para el Pic16F887
; CONFIG
; __config 0xFFFD
__CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_OFF & _BOREN_ON & _LVP_ON & _CPD_OFF & _WRT_OFF & _CP_OFF
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
; -------
ORG 0x00
GOTO EMPEZAR
ORG 0x04
GOTO INTERRUPCION
ORG 0x05
; ------------- Configuracion ---------------
EMPEZAR
MOVLW 0x07
MOVWF CMCON
BSF STATUS, RP0 ; Banco 1
BCF STATUS, RP1
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'11110000'
MOVWF TRISB ; Puerto B como entrada
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
BCF INTCON, RBIF
;BCF INTCON, T0IF
BSF INTCON, GIE
;--------------------------------------
INICIO
nop
GOTO INICIO
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'
INTERRUPCION
MOVWF W_TEMP
SWAPF STATUS,W
MOVWF STATUS_TEMP
MOVLW D'99'
MOVWF TMR0
BTFSC INTCON,RBIF
GOTO INTERRUPCIONEXT
BTFSC INTCON,T0IF
GOTO INTERRUPCIONINT
RETORNA
BCF INTCON,T0IF
SWAPF STATUS_TEMP,W
MOVWF STATUS
SWAPF W_TEMP,F
SWAPF W_TEMP,W
RETFIE
LED0
MOVF Cont1A,W
CALL TABLA
MOVWF PORTD
BCF PORTC,3
BSF PORTC,1
BCF PORTC,2
RETURN
LED1
MOVF Cont2A,W
CALL TABLA
MOVWF PORTD
BCF PORTC,1
BSF PORTC,2
BCF PORTC,3
RETURN
LED2
MOVF Cont3A,W
CALL TABLA
MOVWF PORTD
BCF PORTC,1
BCF PORTC,2
BSF PORTC,3
RETURN
TABLALED
ADDWF PCL,F
GOTO LED0
GOTO LED2
GOTO LED1
GOTO LED0
;Rel_ContLED
;MOVLW D'4'
;MOVWF ContLED
;GOTO RETORNA
INTERRUPCIONEXT
BCF INTCON, GIE
;------Rotacion de display
MOVF Cont2A,W
MOVWF Cont1A
MOVF Cont3A,W
MOVWF Cont2A
;-------------------------
CALL Ver_Teclado
MOVWF Cont3A
MOVLW B'00000000'
MOVWF PORTB
BCF INTCON, RBIF
BSF INTCON, GIE
GOTO RETORNA
INTERRUPCIONINT
;--------------IMPRIME lo que hay en los contadores
DECFSZ ContTMR,F
GOTO SEGUIR
GOTO SEGUIR1
SEGUIR1
MOVLW D'3'
MOVWF ContTMR
MOVF ContLED,W
CALL TABLALED
DECFSZ ContLED,F
GOTO SEGUIR
MOVLW D'3'
MOVWF ContLED
SEGUIR
GOTO RETORNA
;-------------- NO LO USAMOS
; DECFSZ Cont1,F
;GOTO RETORNA
;GOTO Rei0
;------------- Identifica la tecla
Ver_Teclado
BTFSS PORTB, 4 ; Fila 0
GOTO Fila0
BTFSS PORTB, 5 ; Fila 1
GOTO Fila1
BTFSS PORTB, 6 ; Fila 2
GOTO Fila2
BTFSS PORTB, 7 ; Fila 3
GOTO Fila3
Fila0
MOVLW B'00001110'
MOVWF PORTB
BTFSS PORTB, 4 ; Columna 3
GOTO $+3
CALL ANTIR
RETLW D'15'
MOVLW B'00001101'
BTFSS PORTB, 4 ; Columna 2
GOTO $+3
CALL ANTIR
RETLW D'12'
MOVLW B'00001011'
BTFSS PORTB, 4 ; Columna 1
GOTO $+3
CALL ANTIR
RETLW D'9'
MOVLW B'00000111'
BTFSS PORTB,4 ; Columna 0
GOTO $+3
CALL ANTIR
RETLW D'1'
Fila1
MOVLW B'00001110'
MOVWF PORTB
BTFSS PORTB, 5 ; Columna 3
GOTO $+3
CALL ANTIR
RETLW D'14'
MOVLW B'00001101'
BTFSS PORTB, 5 ; Columna 2
GOTO $+3
CALL ANTIR
RETLW D'11'
MOVLW B'00001011'
BTFSS PORTB, 5 ; Columna 1
GOTO $+3
CALL ANTIR
RETLW D'8'
MOVLW B'00000111'
BTFSS PORTB, 5 ; Columna 0
GOTO $+3
CALL ANTIR
RETLW D'16'
Fila2
MOVLW B'00001110'
MOVWF PORTB
BTFSS PORTB, 6 ; Columna 3
GOTO $+3
CALL ANTIR
RETLW D'13'
MOVLW B'00001101'
BTFSS PORTB, 6 ; Columna 2
GOTO $+3
CALL ANTIR
RETLW D'10'
MOVLW B'00001011'
BTFSS PORTB, 6 ; Columna 1
GOTO $+3
CALL ANTIR
RETLW D'7'
MOVLW B'00000111'
BTFSS PORTB, 6 ; Columna 0
GOTO $+3
CALL ANTIR
RETLW D'2'
Fila3
MOVLW B'00001110'
MOVWF PORTB
BTFSS PORTB, 7 ; Columna 3
GOTO $+3
CALL ANTIR
RETLW D'6'
MOVLW B'00001101'
BTFSS PORTB, 7 ; Columna 2
GOTO $+3
CALL ANTIR
RETLW D'5'
MOVLW B'00001011'
BTFSS PORTB, 7 ; Columna 1
GOTO $+3
CALL ANTIR
RETLW D'4'
MOVLW B'00000111'
BTFSS PORTB, 7 ; Columna 0
GOTO $+3
CALL ANTIR
RETLW D'3'
;-------------------------
ANTIR
BTFSC PORTB, 4
GOTO ANTIR
BTFSC PORTB, 5
GOTO ANTIR
BTFSC PORTB, 6
GOTO ANTIR
BTFSC PORTB, 7
GOTO ANTIR
RETURN
END
Bastante cosas a ver:
- El PORTA seguro que no te anda por que en el reset se configuran como analogicos, observaras que el PORTA tambien tiene la funcion del ADC ( ANx ), para ponerlos como digitales debes modificar el registro ADCON1, los bits PCFG3:PCFG1
- Hay algunas cosas del Hardware que me causan dudas. Como normalmente se hace el teclado matricial, se deberian activar una por 1 las columnas o las filas, y observar si se produce un cambio en su contraparte ( si activo columnas observo filas ) , si queres usar las interrupciones esto quiere decir que lo que leo, deberia estar conectado al RB4:RB7. Por otra parte como decia el hardware, supongamos que en diagrama activamos las filas y leemos las columnas, mientras no se presione nada las columnas van a estar en un valor incierto.. ya que no hay nada que los tenga en 0 o en 1. Asi que deberian tener una resistencia de pull-down o pull-up segun como utilizes tu logica. Esto tal ves en la simulacion si afecteLo hice al reves, pero calculo que deberia andar igual, no se porque se me dio por hacerlo al reves, debí poner las filas como entradas (RB4-RB7) y las otras como salidas.
- No creo que la simulacion afecte que los displays no tienen resistencia, pero si pensas hacerlo fisico deberias tenerlo en cuenta.En la simulacion no afecta, pero en fisico si lo pongo, pasa que como no hace falta en la simulacion lo salteo.
Tu rutina de interrupcion:- Tenes razon, eso me olvide corregir.
- Estas recargando el timer cuando todavia no preguntas por que entraste a la interrupciones, esa recarga del timer deberia ir en lo que llamas INTERRUPCIONINT.
- Existe una posibilidad de que mientras estas haciendo el tratamiento del teclado ocurra una interrupcion del timer, pero no creo que exista ningun problema por que solo se retraso un poco un disparo.
- Te das cuenta que jamas va a dispararse la interrupcion del PORTB ya que nunca estas activando las filas ?
- Estas activando GIE cuando eso lo hace el RETFIE
- Y pare de mirarlo xD
Con lo que mi pregunta va.. es necesario usar las interrupciones para eso ? Yo lo haria solo con una interrupcion que seria el del timer, el timer me activa un flag y ese flag permite la ejecucion de todo (o solo la actualizacion de los displays) el programa. La decision de hacerlo asi fue por que ya que si activo O desactivo una fila O se suelta el boton ,cualquiera de esas va a entrar a la interrupcion ya que es por nivel. Y de hacerlo asi tendrias que hacer un programa que discrimine todo eso. Pero aun asi deberias de activar las filas para saber si se presiono algo o no. El activar una y desactivar otra va a hacer que se dispare sola la interrupcion y tambien deberias de preveer eso.
Lo hice al reves, pero calculo que deberia andar igual, no se porque se me dio por hacerlo al reves, debí poner las filas como entradas (RB4-RB7) y las otras como salidas.Los unicos que tienen capacidad de interrupcion son RB4 a RB7, y su interrupcion es si cambio o no la señal de entrada. Si pasa de 0 a 1 o como si pasa de 1 a 0
-Esto no lo entendi, como no va a saltar la interrupcion nunca? como no activo las filas?. En teoria deberia saltar cuando toco cualquier tecla, que me pasa el "0" a la entrada en rb4-rb4, y ahi deberia saltar la interrupcion.
Tambien tengo un problema que no me salta ni la interrupcion del TMR0 si no toco nada, si desactivo los pullup, anda, si lo activo no me muestran el triple 0
Hay algunas cosas malas en el codigo, por ejemplo no podes estar esperando que se deje de presionar todo dentro de una interrupcion, la idea o concepto de una interrupcion es que se atienda lo mas rapido posible y salga. Por eso normalmente activo una flag que luego en mi programa principal actuo dependiendo de lo que se activo. Ademas solamente se activarian en los flancos esa interrupcion.
En simulacion no tenes rebotes, asi que si vas a implementar algun anti-rebote podes hacerlo por hw, o pensarlo de otra forma.
Tambien veo que en la rutina del teclado haces un MOVLW pero luego te falto ponerlo en PORTB, Tambien podria haberlo simplificado poniendo todo a 1 y el carry tambien a 1 y solo rotarlo
Con respecto al antirebote, si lo queres hacer por soft, no podes hacerlo como estas haciendolo, seguro que existen algunas formas, pero la unica que se me ocurre es:
- Implementar que cada X tiempo se lean las entradas, es decir el timer active la lectura de las entradas, con lo cual tenes esa ventana entre interrupciones del timer que vas a tener tu antirebote. Con lo cual no te serviria de nada tener la interrupcion por PORTB. Y es parecido al ejemplo que di antes.
- Para hacerlo en la interrupcion, deberias desabilitar la interrupcion del PORTB, y activarla nuevamente con el timer (limpiando flags, etc) asi de esa forma tenes esa ventana entre interrupciones para que active nuevamente la interrupcion.
El objetivo de la interrupcion es que se atienda y se salga inmediatamente, sino seria lo mismo que tenerlo en el programa principal. Me intento explicar:
Cuando ocurre una interrupcion , se deja el programa principal de lado y luego se vuelve al mismo. Casi como si nada hubiera ocurrido, pero realmente se hizo caso a esa interrupcion.
Si haces un bucle como hiciste, esto:
ANTIR
BTFSC PORTB, 4
GOTO ANTIR
Primero no es un antirebote, ya que en un rebote tenes varios 0 o 1 en periodos cortos de tiempo (Por lo que vos detectes como un 1 puede ser un rebote, lo cual entraria mas veces a la interrupcion). Por otra parte hasta que no soltes el boton no va a salir de ese bucle. Eso quiere decir que va a quedar atrapado en la interrupcion hasta que soltes el boton, si se produce el overflow del TMR0 no lo va a atender por que obviamente estan desabilitadas las interrupciones y esta atrapado ahi. Ademas si tu idea es hacer mas cosas, estarias "retrasando", o mejor dicho prihibiendo la ejecucion de lo demas hasta que soltes el boton
Si yo hiciera eso en el programa principal es otra cosa, por que ante una interrupcion, entraria a la misma y saldria, es decir las interrupciones siguen ocurriendo. Como deben ser.
Espero haberme hecho entender cual esmi punto de vista.
Es lo mismo que poner un delay dentro de una interrupcion.
Implementa o trata de implementar lo que te dije, es decir usar ese mismo timer como antirebote, es decir:
- Detecta cambio RB, interrupcion RB -> Me asguro que no sea por que se solto (1111). Pongo en 1 un flag y guardo el contador del timer en otro registro (esto para que sea al menos un ciclo de interrupcion). Desactivo interrupcion PORTB. Salgo
- Ocurre interrupcion del timer, procedo a mostrar el otro display,recargo timer, etc. Pregunto por el flag, y si contador guardado es igual a contador del timer (suponiendo que ya lo incrementaste), si se cumplen ambas condiciones, procedo a leer mi teclado matricial. Limpio flags activo nuevamente la interrupcion del PORTB.
Listo. Antirebote realizado con interrupciones. Tiempo minimo de tener apretado el boton va a ser como tomes la diferencia del contador (lo guardado y lo actual), por ejemplo si usas los 3 ciclos, entonces seria 3 * tiempo de overflow del timer, la idea seria como minimo 2 ciclos. Esto te daria tiempo para que ocurra el rebote y recien ahi leer el teclado. Luego de eso cuando se suelte se pone todo a 1111 e ignoro esa interrupcion.
Si lo queres hacer en el programa principal entonces seria algo asi como propuse yo al comienzo, lo que abarca tu flag puede ser solamente el teclado y lo del timer hacerlo en la interrupcion. Aunque aqui vas a necesitar de un registro para guardar el valor previo del puerto cuadno se detecto algo.
Fila3
MOVLW B'00001110'
MOVWF PORTB
BTFSC PORTB, 7 ; Columna 3
GOTO $+3
CALL ANTIRREBOTE
RETLW D'6'
MOVLW B'00001101'
MOVWF PORTB
BTFSC PORTB, 7 ; Columna 2
GOTO $+3
CALL ANTIRREBOTE
RETLW D'5'
MOVLW B'00001011'
MOVWF PORTB
BTFSC PORTB, 7 ; Columna 1
GOTO $+3
CALL ANTIRREBOTE
RETLW D'4'
BTFSS PORTB, 7 ; Columna 0
CALL ANTIRREBOTE
RETLW D'3'
ANTIRREBOTE
MOVLW 0XFF
MOVWF ContANT
BUCLE DECFSZ ContANT,F
GOTO BUCLE
RETURNLo que estas haciendo es un simple delay.
No es tan excesivo como esperar hasta que se deje de presionar como hiciste antes, pero es tiempo que el micro se la pasa haciendo nada y no pudiendo atender las interrupciones.
Lo cual va con tu idea principal de que el micro este desocupado para hacer otras cosas.
A mi me quedo algo asi:Código: ASM
;------------------------------------------------- ; ;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
Si hay un error es por que estaba bastante dormido.
Si, como dije estaba dormido.
Pense primero en tener un registro unicamente para las flags ( que es lo que deberia hacer, en especial si tu programa va a hacer otra cosa y necesitas de otra flag ) y otro registro para mantener el valor del Contador del TMR.
Pero luego para ahorrarme un registro utilize el mismo. Fue ahi cuando cambie el bit 0 por el bit 7. Y ese me quedo.
Tranquilamente podria NO haber usado el tema del Contador del TMR y esperar a la proxima interrupcion, pero se me pasaba por la cabeza el caso en que se toque la tecla e inmediatamente entrara a la interrupcion del timer, no cumpliendose el tiempo de espera suficiente para un rebote. Como uno normalmente presiona por milisegundos un boton entonces no deberia haber problema de esperar esa cantidad de interrupciones.
Espero que te des cuenta cual es mi idea detras de esto.