hola a todos teniendo en cuenta lo que me ha costado a mi conseguir hacerlo y en un codigo rapido y corto ahora que mas o menos lo he conseguido (seguramente con el nivel de aqui habra rutinas muchisimo mejores) cuelgo aqui la que he creado yo
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
;PROGRAMA QUE LEE UN TECLADO DE 3X4 (TELEFONICO) Y DA EL VALOR POR EL PUERTO C ;
; ;
;SE UTILIZAN LA INTERRUPCION DE CAMBIO DE ESTADO EN EL RB4-RB7 Y EL TMR0 PARA HACER LOS RETARDOS ;
; ;
;INICIALMENTE PARA EL PIC 16F873A, PERO EXTRAPOLABLE A CUALQUIERA, SOLO UTILIZA EL PUERTOB ;
;PUDIENDO COMPAGINARSE CON UN LCD PERFECTAMENTE ;
; ;
; REALIZADO POR DANIEL GARCIA PINOS ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Declaracion de micro
;-------------------------------------------------------------
list P=16f873
include "P16f873A.inc"
; Declaracion de vectores, inicio e interrupcion
;-------------------------------------------------------------
org 0x00
goto inicio
org 0x04
goto interrupcion
org 0x05
; Configuracion del pic
;---------------------------------------------------------------
inicio
bsf STATUS,RP0 ;SELECCIONAMOS BANCO DE MEMORIA 1
clrf TRISC ;Configuracion de los puertos
movlw b"00000110" ;ANULAMOS EL CONVERSOR ANALOGICO/DIGITAL
movwf ADCON1 ;
clrf TRISA ;PONEMOS EN SALIDA EL PUERTO A
movlw b"11110000" ;PONEMOS LA PARTE BAJA DEL PUERTO B COMO SALIDA Y LA PARTE ALTA COMO ENTRADA
movwf TRISB ;
movlw b"10000111" ;QUITAMOS RESISTENCIAS DEL PULL-UP Y PRESCALER DE 256 PARA EL TMR0
movwf OPTION_REG ;VOLVEMOS AL BANCO DE MEORIA 0
bcf STATUS,RP0
; Configuracion de vector de interrupcion para interrupcion RB4-7 y RB0
;------------------------------------------------------------------------------
clrf PORTA ;
clrf PORTB ;RESETEAMOS PUERTOS
clrf PORTC ;
; rutina principal
;-------------------------------------------------------------------
contador equ 0x20 ;CUENTA LA POSICION EN LA PRIMERA TABLA
contador2 equ 0x21 ;AVANZA EN LA PRIMERA TABLA
auxiliar equ 0x24 ;SALVA EL VALOR DE W EN EL RETARDO
contador3 equ 0x25 ;CUENTA EL NUMERO DE VECES QUE SE A DESBORDADO EL TMR0
contador4 equ 0x26 ;CUENTA LOS AVANCES EN LA TABLA PARA AVERIGUAR LA TECLA Y NOS DA EL VALOR EN LA
;TABLA DE CONVERSION
auxiliar2 equ 0x27 ;ALMACENA EL VALOR DEL PUERTOB PARA COMPROBAR LA TECLA
clrf contador4 ;INICIALIZAMOS CON 0X00 EL CONTADOR4
clrf auxiliar2 ;Y EL ALMACEN DEL PUERTOB
aqui movlw b"10001000" ;
movwf INTCON ;CONFIGURAMOS VECTOR DE INTERRUPCIONES, POR CAMBIO DE ESTADO EN RB4-RB7 Y ACTIVAMOS
;PERMISOS
movlw d"3"
movwf contador ;CONFIGURAMOS EL PORSICIONADOR EN LA PRIMERA TABLA (CUENTA) CON EL NUMERO DE
;POSICIONES QUE TIENE
clrf contador2 ;NOS POSICIONAMOS EN LA POSICION 0
alli movfw contador2 ;CARGAMOS LA POSICION EN W
call cuenta ;COGEMOS EL VALOR DE LA POSICION EN W
movwf PORTB ;LO SACAMOS POR LA PARTE BAJA DEL PUERTOB
nop ;
nop ;ESTABILIZAMOS LA SEÑAL (ALGUNA GENTE LO HACE CON UNO SOLO, YO PREFIERO CON 2)
incf contador2 ;AVANZAMOS EN LA TABLA
decfsz contador ;ES EL ULTIMO PUESTO
goto alli ;NO, SEGUIMOS AVANZANDO
goto aqui ;SI REINICIALIZAMOS VECTOR DE INTERRUPCION Y POSICION 0 EN LA TABLA
; tabla de salidas
;-------------------------------------------------------------------
cuenta:
addwf PCL,F
retlw b"00000001"
retlw b"00000010"
retlw b"00000100"
return
; interrupcion
;------------------------------------------------------------------
interrupcion
movfw PORTB ;CARGAMOS EL VALOR DEL PUERTOB EN AUXILIAR2
movwf auxiliar2
clrf PORTB ;LIMPIAMOS EL PUERTOB Y EL REGISTRO DE INTERRUPCIONES
clrf INTCON ;ESTO LO HAGO PQ SINO AL VOLVER Y CAMBIAR EL PUERTO OTRA VEZ HAY FALSAS
;INTERRUPCIONES
seguir movfw contador4
call tabla ;COGEMOS EL VALOR DE LA TABLA PARA PODER COMPARA CON EL PUERTO Y SABER LA TECLA
subwf auxiliar2,W ;
btfsc STATUS,Z ;RESTAMOS EL VALOR DEL PUERTO CON EL DE LA TABLA Y SI ES 0 SABEMOS QUE ES IGUAL
goto igual
incf contador4 ;SI NO, AVANZAMOS EN LA TABLA PARA PODER SEGUIR MIRANDO
goto seguir
igual
movfw contador4 ;COGEMOS EL VALOR DE LA TECLA Y LO TRANSFORMAMOS (AQUI SE PUEDE O EN ASCII O EN
;DIGITAL CAMBIANDO LA D POR NADA Y PODER MANDARLO A UN DISPLAY LCD
call tabla2
clrf contador4 ;BORRAMOS LA TECLA (SINO DA PROBLEMAS LA PROXIMAVEZ AL MIRAR EL UNO
movwf PORTC ;LO SACAMOS POR EL PUERTOC (EN MI CASO POR DISPLAYS 7 SEG, ATRAVES DE 7448
call delay3 ;
call delay3 ;
call delay3 ;TIEMPO QUE SE VE EL DATO EN EL DISPLAY 7 SEG
call delay3 ;
call delay3 ;
clrf PORTC ;LIMPIAMOS PUERTO
retfie ;SALIMOS DE LA INTERRUPCION
; tabla DE VALORES DE COMPARACION CON EL PUERTOB
;---------------------------------------------------------------
tabla
addwf PCL,F
retlw b"00010001"
retlw b"00010010"
retlw b"00010100"
retlw b"00100001"
retlw b"00100010"
retlw b"00100100"
retlw b"01000001"
retlw b"01000010"
retlw b"01000100"
retlw b"10000001"
retlw b"10000010"
retlw b"10000100"
return
; tabla2, TRANSFORMACION DE LA TECLA PULSADA
;-------------------------------------------------------------
tabla2
addwf PCL,F
retlw d"1"
retlw d"2"
retlw d"3"
retlw d"4"
retlw d"5"
retlw d"6"
retlw d"7"
retlw d"8"
retlw d"9"
retlw "*"
retlw d"0"
retlw "#"
return
; rutina de retardo
;-------------------------------------------------------------------
delay2:
movwf auxiliar ;SALVAMOS EL VALOR DE W
movlw d"100" ;CONFIGURAMOS 100 DESBORDAMIENTOS DEL TMR0
movwf contador3
bcf INTCON,T0IF ;RESETEAMOS FLAG DE SEÑALIZACION DE DESBORDAMIENTO
movlw d"100" ;HACEMOS QUE EL TMR0 TENGA QUE RECORRER 155 POSICIONES (AL SER COMPLEMENTO A
;1,255-100)
movwf TMR0
delay1
btfss INTCON,T0IF ;SE A DESBORDADO EL TMR0?
goto delay1 ;NO, LO PREGUNTAMOS OTRA VEZ
decfsz contador3 ;ES LA VEZ 100?
goto vuelta ;SI VAMOS A VUELTA
goto delay1 ;VOLVEMOS A PREGUNTAR
vuelta
movfw auxiliar ;DEVOLVEMOS SU VALOR A W
return ;VOLVEMOS A LA RUTINA QUE NOS LLAMO
delay3:
movwf auxiliar
movlw d"255"
movwf contador3
bcf INTCON,T0IF
movlw d"1"
movwf TMR0
delay4 ;LO MISMO DE ANTES PERO CON OTRA TEMPORIZACION
btfss INTCON,T0IF
goto delay4
decfsz contador3
goto vuelta2
goto delay4
vuelta2
movfw auxiliar
return
end