hace 17 años
a ver si te sirve
;===================================================================
;programa el cual detecta y decodifica un teclado matricial
;de 4*4 el cual estara conectado al puerto B
;se utilizaran los 4 bits menos significativos como salidas y los
;otros 4 como entradas ademas de utilizar la interrupcion de cambio
;de estado en los 4 bits mas significativos
;
;
; RB3------------>---------|
; RB2----------->------| |
; RB1------->------| | |
; RB0---->-----| | | |
; | | | |
; -----------------
; RB4 ---<---| 0 | 1 | 2 | 3 |
; -----------------
; RB5 ---<---| 4 | 5 | 6 | 7 |
; -----------------
; RB6 ---<---| 8 | 9 | A | B |
; -----------------
; RB7 ---<---| C | D | E | F |
; -----------------
;*******************************************************************
; Luis Daniel Tellez Garcia *
; 4 de Agosto del 2000 *
;*******************************************************************
LIST P=16C84 ;se utiliza el pic16C84
;-------------------------------------------------------------------
PuertoB equ 0x06 ;direccion del puerto B
Estado equ 0x03 ;direccion del Estado
PCL equ 0x02 ;direccion del apuntador del programa
opt_tmro equ 0x01 ;direccion del registro OPTION
Intcon equ 0x0b ;registro de control de interrupciones
w equ 0 ;
f equ 1 ;
CBLOCK 0x0c
tecla ;registro para grabar el valor correspondiente a la tecla precionada
contador ;registro para grabar el contador que nos dara el valor en decimal de la tecla precionada
timer1
timer2
temp
ENDC
;------------------------------------------------------------------
; PROGRAMA PRINCIPAL
reset org 0 ;el reset esta en la direccion 00
goto inicio
org 4 ;la interrupcion esta en la direccion 04
goto inter
org 5 ;
inicio bsf Estado,5 ;pone en 1 el bit 5 del Estado
movlw 0xf0 ;los 4 bits menos significativos como salidas
movwf PuertoB ;y los mas significativos como entradas
bcf opt_tmro,7 ;activa las resistencias pull_up en el PuertoB
bcf Estado,5 ;pone en 0 el bit 5 del Estado
clrf PuertoB
movlw b'10001000' ;Activo la interrupcion global
;y la interrupcion por cambio de estado en el Puerto B
movwf Intcon ;
ciclo goto ciclo ;no hago nada hasta que haya una interrupcion
;***** INTERRUCION ***********************************************
inter btfss Intcon,0 ;Explora la bandera de interrupcion por cambio en el PuertoB
goto fin ;si la interrupcion fue por causa diferente diferente no hago nada
goto decodif ;si fue por el cambio de estado del Puerto B activo la alarma
decodif call ret20ms
movf PuertoB,w ;Si la interrupcion es por cambio de estado en el PuertoB
andlw 0xf0 ;leo unicamente las entradas
sublw 0xf0 ;checo si se preciono por equivocacion.
btfsc Estado,2 ;si el resultado es diferente de cero se preciono una tecla
goto fin ;si el resultado es 0, por error se preciono el teclado
;**************************checar los renglones************************************
movf PuertoB,w ;vuelvo a leer el PuertoB
andlw 0xf0
movwf tecla ;las grabo para tener el renglón
;*****************checar las columnas***********************************************
bsf Estado,5 ;pone en 1 el bit 5 del Estado
swapf PuertoB,f ;los 4 bits mas significativos como salidas
;y los menos significativos como entradas
bcf Estado,5 ;pone en 0 el bit 5 del Estado
clrf PuertoB ;mando ceros por los 4 bit mas significativos
movf PuertoB,w ;vuelvo a leer el PuertoB
andlw 0x0f
movwf temp
iorwf tecla,f ;las grabo para tener el columna
;***************checar si se solto la tecla*****************************************************
soltar movf PuertoB,w ;leo el puertoB
andlw 0x0f ;hago la and para tener solo los valores que me interesan
subwf temp,w ;y lo resto con el valor que encontre de el renglon
btfsc Estado,2 ;si el resultado de la resta
goto soltar ;es igual a cero significa que no he soltado la tecla
;si es diferente de cero significa que ya solte la tecla
call ret20ms ;llamo a un retardo para evitar rebotes al soltar la tecla
clrf contador ;ademas de limpiar un contador que nos servira para detectar tecla
;******************************encuentra el valor en decimal************************************
otra call tec_tab ;llamo a la subrutina para encontrar el valor en el teclado
subwf tecla,w ;saco un valor de la tabla y lo comparo con elvalor que tenia
btfsc Estado,2 ;
goto fin ;si el resultado es igual a 0 significa que el valor es valido
incf contador,f ;si no incremendo el contador para que la tabla nos regrese otro valor
btfss contador,4 ;como solo tenemos 16 valores posibles tecla no valida
goto otra ;si no hemos llegado a 16 busca otro valor
fin bsf Estado,5 ;pone en 1 el bit 5 del Estado
swapf PuertoB,f ;los 4 bits menos significativos como salidas
;y los mas significativos como entradas
bcf Estado,5 ;pone en 0 el bit 5 del Estado
clrf PuertoB
movlw b'10001000' ;Activo la interrupcion global
;y la interrupcion por cambio de estado en el Puerto B
movwf Intcon ;
retfie ;regreso de la interrupcion
;***********************************************************************************************
tec_tab movf contador,w ;mando el valor del contador =0
addwf PCL,f ;y lo sumo a el contador del programa y asi tener un desplazamiento
retlw 0xee ;0
retlw 0xed ;1
retlw 0xeb ;2
retlw 0xe7 ;3
retlw 0xde ;4
retlw 0xdd ;5
retlw 0xdb ;6
retlw 0xd7 ;7
retlw 0xbe ;8
retlw 0xbd ;9
retlw 0xbb ;A
retlw 0xb7 ;B
retlw 0x7e ;C
retlw 0x7d ;D
retlw 0x7b ;E
retlw 0x77 ;f
;**********RUTINA DE RETARDO ***********************************
ret20ms movlw 0x08 ;0xC8
movwf timer2
exter movlw 0x04 ;0x64
movwf timer1
ciclint nop
decfsz timer1,f ;rutina de retardo de 20ms
goto ciclint ;para evitar rebotes en los
decfsz timer2,f
goto exter
retlw 0 ;regreso de la subrutina y cargo el registro W con 0
end ;fin
;====================================================================
SAludos
¿Realmente quieres cerrar esta reparación?
Sí
No
¿Realmente quieres reabrir esta reparación?
Sí
No
¿Realmente quieres borrar este post?
Sí
No