Hola.me he decicado a crear una libreria para el uso de un teclado resistivo.cuyo valor sera introducido en una entrada analogica del pic.
en este programa la entrada sera por el pin AN0.asi que con solo dos hilos podemos utilizar muchas teclas.
el teclado puede configurarse con un numero determinado de teclas.en el programa esta configurado para el uso de un teclado de 4x4.
que son 16 teclas.pero puede modificarse un valor para un mayor o menor numero de teclas.
tal y como se muestra en la imagen:

en modo reposo a la entrada AN0 se le aplica un valor positivo de tension 0xff.y cuando se pulsa una tecla el valor varia entre los valores
0x00 y 0xff ambos no inclusive.
el programa esta preparado para pregrabar en la memoria eeprom las teclas que vallamos pulsando.las teclas adquiriran los valores o,1,2,3,4....
hasta la cantidad de teclas que definemos.por defecto son hasta 16 teclas.
si hemos definido 16 teclas.cuando terminemos de meter la numero 16.el programa saldra del modo de pregrabado.aunque si queremos menos teclas
tambien podemos finalizar el pregrabado pulsando la primera tecla que se pulso.
este programa tiene un metodo "anti rebote" que consiste en la comparacion de 10 valores analogicos capurados desde AN0.y escoger el
valor mas repetido.
;Este programa devuelbe en el registro TEMP_TECLA ,el indice de la tecla pregrabada.
;la peculariedad de que este programa sea tan grande,es que tiene un sistema de comprovacion de errores,que al pulsar
;una tecla.se almazenan en memoria 10 valores de esa tecla y se coje el valor mas repetido.de esa forma se evita el que al
;pulsar un boton resistivo,no cojamos el valor mas aproximado al real de ese boton.y que nos falle la identificacion de esa tecla.
;el programa tarda en ejecutarse
;La memorizacion de teclas esta limitada a 16 para mas teclas modificar: (#define N_BYTES .16)
;pero habra que tener en cuenta un byte en la posicion 17 para el valor de numeros de teclas memorizadas
;La memorizacion se realiza pulsando el numero de teclas definido.en el caso de que las teclas sean inferiores a las definidas
;solo haria falta pulsar la primera tecla que se presiono para la finalizacion del aprendizaje.
;la primera tecla sera asignada con el valor .0 la siguiente .1 .2 .3 - etc y asi hasta que finalizemos.
;Para el borrado de teclas y reaprendizage,poner a masa la entrada analogica.
CBLOCK BOTON_PULS_VAR
TEMP_ANALOG ;registro de tecla pulsada
COMPARADOR
TEMP_KEY
TEMP_KEY2
CONT_REG
CONT_COINC
CONT_ALMAC ;contador de las teclas almacenadas
PRIMR_TECL ;primera tecla plsada en el aprendizaje
FLAGS_KEY
N_KEYS ;numero de teclas aprendidas
TEMP_TECLA
ENDC
#define INI_RAM 0XF6 ;zona donde se ubicaran los datos analogicos de tecla pulsada
#define INI_TABLA 0XEC
#define KEY_OK bsf FLAGS_KEY,0
#define KEY_NOK bcf FLAGS_KEY,0
#define KEY_OK2 bsf FLAGS_KEY,1
#define FIND_OFF bsf FLAGS_KEY,2
#define FLASH_OK bsf FLAGS_KEY,3
#define N_BYTES .16 ;numero de teclas a gestionar y direccion de la eeprom donde se metera el dato del numero de bytes guardados
BOTON_PULS setf PRIMR_TECL
setf TEMP_KEY2
btfsc FLAGS_KEY,3 ;comprueba si ha habido pregrabacion en la eeprom de datos
goto SEARCH ;si la ha habido salta a busqueda de tecla pulsada
bt2 clrf DIR_EEPROM
call ALMAC ;salta a almacenamiento de aprendizage de teclas pulsadas en la eeprom
btfss FLAGS_KEY,2 ;comprueba si se termino con el aprendizage del teclado
goto bt3
call EEP_RAM ;si es asi,traspasa los bytes de la eeprom a la ram
return
bt3 setf TEMP_KEY2 ;en caso contrario setea el registro
goto bt2 ;y sigue el aprendizage
;********************************************************** KEYB ***********************************************************************
;adquisicion de valor de tecla pulsada
KEYB call TECLA ;lee valor de tecla pulsada
btfss FLAGS_KEY,0 ;comprueba si se ha pulsado una tecla
return ;si no es si,retorna
movff TEMP_KEY,TEMP_KEY2 ;guarda valor de tecla pulsada
kb1 call TECLA ;lee valor de tecla pulsada
btfsc FLAGS_KEY,0 ;comprueba si se ha soltado la tecla
goto kb1 ;si no es asi,vuelbe a leer valor de tecla pulsada
return ;retorna
;************************************************************ TECLA ********************************************************************
;Lectura de la entrada analogica y transferencia de 10 valores a la ram
TECLA setf TEMP_KEY
movlw INI_RAM
movwf FSR0L
movlw BANCO_GENERAL
movwf FSR0H
REPE call DAT_AN ;lee dato analogico
call BORRA_TECL ;opcion a borrado de teclado
setf WREG ;valor 0xff.tecla sin pulsar
cpfseq TEMP_ANALOG ;compara con el valor analogico de tecla
goto tec1
KEY_NOK
return ;si el valor analogico de la teclaes 0xff repite busqueda analogica(VALOR DE TECLA SIN PULSAR)
tec1 movff TEMP_ANALOG,INDF0
incf FSR0L,F ;incrementa FSR
clrf WREG
cpfseq FSR0L
goto REPE ;si no se ha llegado al tope de la ram repite
; aqui leemos la ram y buscamos el dato mas repetido
; en esta rutina se cogen los valores almacenados entre las direcciones seleccionadas y se coge valor que tenga mas numeros repetidos.
BUSCA_REP movlw BANCO_GENERAL ;banco donde trabajaremos con los registros generales
movwf FSR2H ;selecciona bancos de direccionamiento indirecto
movwf FSR1H
movwf FSR0H
movlw INI_TABLA ;inicio de tabla ram donde estan los valores a comparar
movwf FSR0L ;selecciona indice de tabla
decf FSR0L,F ;decrementa una direccion para luego incrementarla
movlw INI_RAM ;inicio de tabla ram donde se introduciran cantidad de coincidencias
movwf FSR2L ;selecciona indice de tabla
decf FSR2L,F ;decrementa una direccion para luego incrementarla
movlw .11 ;bytes a comparar menos 1
movwf CONT_COINC ;contador de comparaciones
regsig2 dcfsnz CONT_COINC,F ;decrementa el contador de comparaciones
goto discrim ;si se ha terminado de comprobar las coincidencias salta a esta direccion
movlw INI_RAM ;inicio de tabla ram donde se introduciran cantidad de coincidencias
movwf FSR1L ;selecciona indice de tabla
incf FSR2L,F ;incrementa indice de tabla
decf FSR1L,F
movff INDF2,COMPARADOR ;introduce valor de la tabla en registro comparador
movlw .11 ;registros a comparar
movwf CONT_REG ;contador de registros a comparar
incf FSR0L,F ;incrementa indice de registros
regsig1 incf FSR1L,F ;incrementa indice de comparaciones
movf INDF1,W ;lee el registro indexado
dcfsnz CONT_REG,F ;decrementa contador de registros
goto regsig2 ;si se ha llegado al limite salta a lectura de siguiente registro
cpfseq COMPARADOR ;comprueba si w es igual a COMPARADOR
goto regsig1 ;siguiente comparacion
incf INDF0,F ;incrementa direccion seleccionada si hay coincidencia
goto regsig1 ;siguiente comparacion
;busca el valor mas alto
discrim movlw .9 ;cantidad de registros a comparar
movwf CONT_REG ;registro contador
movlw INI_TABLA ;inicio de tabla
movwf FSR0L ;direcciona tabla ram
movff INDF0,TEMP_KEY ;introduce el valor contenido en ram al registro prevalescente
dis1 incf FSR0L,F ;siguiente direccion
movf INDF0,W ;carga valor direccionado en W
cpfsgt TEMP_KEY ;comprueba si es mayor
movff INDF0,TEMP_KEY ;si es mayor introduce el valor en el registro prevalescente
decfsz CONT_REG,F ;decrementa contador de comprobaciones
goto dis1 ;siguiente comprovacion
;busca el valor mas alto de las coincidencias
movlw INI_TABLA ;carga inicio de tabla
movwf FSR0L
pre1 movf INDF0,W ;carga el valor direccionado en W
xorwf TEMP_KEY,W ;comparalo con el valor mas alto
btfsc STATUS,Z ;si se ha encontrado,
goto pre2 ;salta a pre2
incf FSR0L,F ;incrementa direccion
goto pre1 ;repite comparacion
pre2 movlw .10 ;valor de salto a tabla de valores
addwf FSR0L ;salta al valor
movff INDF0,TEMP_KEY ;introduce valor en W
KEY_OK
KEY_OK2
return ;retorna CON EL VALOR ANALOGICO DE LA TECLA PULSADA
;******************************************************* BORRA_TECL **********************************************************************
;Borrado de teclas para nuevo aprendizage "entrada analogica a masa para el borrado"
BORRA_TECL clrf WREG ;valor 0x00
cpfseq TEMP_ANALOG ;comprueba si la tecla pulsada esta a masa
return ;retorna en caso de que no este a masa
clrf DIR_EEPROM ;direccion 0x00 de la eeprom
setf DATO_EEPROM ;valor 0xff a grabar en la eeprom
call ESCRIBIR_DATO ;graba el dato
pop ;salir de todas las llamadas
pop
pop
pop
return ;retorna
;//////////////////////////////////(conversor A/D)////////////////////////////////////////////////////////////////////////////////////////////////
;///////////////busca el dato analogico introducido por el pin seleccionado/////////////////////////////////////////////////////////////////////
;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;Si queremos que funcionen todas las entradas analogicas.hay que habilitar las lineas deshabilitadas
DAT_AN bsf ADCON0,GO_DONE ;inicia la conversion
AD_GOIN btfsc ADCON0,GO_DONE ;comprueva si la conversion ha finalizado
goto AD_GOIN ;si la conversion ha finalizado continua
movf ADRESH,w ;carga dato analogico en el acumulador
movwf TEMP_ANALOG ;carga el dato de w en TEMP_ANALOG
;movf ADCON0,W
;movwf CANAL ;mete el contenido de ADCON0 en CANAL
;movf CONT_AD,W ;dato que se suma a ADCON0 para que a la siguiente lectura sea en el proximo canal de AD
;addwf ADCON0,F ;incrementa el canal analogico(AN0->AN4)
;movlw b'00100001';valor para usar AN5 -> b'00101001' ;valor del ultimo registro del conversor analogico
;xorwf ADCON0,w
;btfss STATUS,Z ;si llega a este valor
;return
;movlw 0x01 ;selecciona de nuevo el conversor AN0
;movwf ADCON0
return
;******************************************************** ALMAC *******************************************************************
;Aprendizaje del teclado.
ALMAC clrf FLAGS_KEY
call KEYB ;devuelve dato de tecla pulsada
movlw 0x02
cpfseq FLAGS_KEY
goto ALMAC
AL2 clrf WREG ;valor 0x00
cpfsgt DIR_EEPROM ;comprueba si es la primera tecla pulsada
movff TEMP_KEY2,PRIMR_TECL;almacena la primera tecla pulsada en PRIMR_TRCL.
cpfsgt DIR_EEPROM ;comprueba si es la primera tecla pulsada
goto al1
movf PRIMR_TECL,w ;comprueba si se ha vuelto a pulsar la primera tecla.
cpfseq TEMP_KEY2 ;si no se ha pulsado,-
goto al1 ;salta a al1
al3 movff DIR_EEPROM, N_KEYS ;guardar el numero de teclas aprendidas
movff N_KEYS,DATO_EEPROM ;pasalo a DATO_EEPROM
movlw N_BYTES ;direccion de la eeprom donde se metera el dato del numero de bytes guardados
movwf DIR_EEPROM ;carga direccion de la eeprom
call ESCRIBIR_DATO ;graba el dato
FIND_OFF ;finalizacion de la memorizacion de teclas
return ;retorna.fin del programa
al1 movff TEMP_KEY2,DATO_EEPROM;carga valor analogico de tecla pulsada en registro de dato eeprom
call ESCRIBIR_DATO ;graba el dato en la eeprom
incf DIR_EEPROM,F ;incrementa la direccion
movlw N_BYTES ;carga tope de bytes a grabar
cpfseq DIR_EEPROM ;comprueba si ha llegado al tope
goto ALMAC ;si no ha llegado salta a ALMAC para siguiente tecla
goto al3 ;en caso contrario salta a al3 para ultima grabacion de numero de bytes y finaliza.
;*************************************************** SEARCH *******************************************************************
;Compara entre tecla pulsada y los valores de tecla almacenados en la eeprom
SEARCH setf TEMP_TECLA
call KEYB ;lee valor de tecla
setf WREG ;valor para tecla sin pulsar
cpfseq TEMP_KEY2 ;comprueba si la tecla esta pulsada.
goto sr1 ;si esta pulsada salta a sr1
return ;en caso contrario.retorna
sr1 clrf DIR_EEPROM ;direccion 0 de la eeprom
sr3 call LEER_DATO ;lee el dato
cpfseq TEMP_KEY2 ;comparalo con la tecla pulsada
goto sr2 ;siguiente direccion a comparar
goto SELEC ;si se ha encontrado la tecla pulsada selecciona valor de tecla.
sr2 incf DIR_EEPROM,F ;increenta la direccion a leer de la eeprom
movf DIR_EEPROM,W ;introducela en el acumulador
cpfsgt N_KEYS ;si la tecla pulsada no esta memorizada,
return ;retorna
goto sr3 ;en caso contrario compara siguiente tecla
SELEC movff DIR_EEPROM,TEMP_TECLA ;almacena en TEMP_TECLA el valor de tecla pulsada.
return ;retorna
;******************************************************* COPM_FLASH *************************************************************
COMP_MEMO clrf FLAGS_KEY ;borra flags
clrf WREG ;dato 0x00
movwf DIR_EEPROM ;direccion a leer de la eeprom de datos 0x00
call LEER_DATO ;lee el dato
setf WREG ;valor 0xFF
cpfseq TEMP_EEP ;comprueba si se ha grabado algo en la direccion 0x00
call EEP_RAM;FLASH_OK ;si se ha grabado algo activa flag de aprendizage
return ;retorna
;***************************************************** EEP_RAM *****************************************************************
;Traspaso de keys de la eeprom de datos a la ram
EEP_RAM btfsc FLAGS_KEY,2 ;comprueba si es primer reinicio del pic
goto eep2 ;si es el primero,salta a eep2.en caso contrario lee de la eeprom el valor de bytes almacenados
movlw N_BYTES ;direccion de numero de bytes a leer
movwf DIR_EEPROM ;carga la direccion
call LEER_DATO ;lee el dato almacenado en la eeprom
movff TEMP_EEP,N_KEYS ;carga el valor en numero de teclas pulsadas
eep2 lfsr 0,0X07EB ;principio de direccion donde se introduciran los datos leidos de la eeprom de datos
clrf WREG ;dato 0x00
movwf DIR_EEPROM ;direccion a leer de la eeprom de datos 0x00
eep1 call LEER_DATO ;lee el dato
movff TEMP_EEP,INDF0 ;traspasa el dato ledo de la eeprom a la ram
decf FSR0L ;direccion anterior de la ram
incf DIR_EEPROM,f ;siguiente dato a leer de la eeprom
movf N_KEYS,w ;numero de bytes previamente almacenados
cpfseq DIR_EEPROM ;comprueba si se ha llegdo al final de la lectura
goto eep1 ;si no ha llegado.tarspasa siguente byte
FLASH_OK ;flag de datos grabados en flash
return ;retornaaparte de configurar los puertos al programa se le llamara de esta forma:
call COMP_MEMO ;comprueba si hay algun dato guardado en la direccion 0x00 de la eeprom de datos.y restablece valores de teclas pulsadas
;pr call BOTON_PULS ;deteccion de tecla pulsada
; setf WREG
; cpfseq TEMP_TECLA
; NOP
; goto prcuando pulsemos una tecla el programa pasara por el NOP
;libreria para manejo de la eeprom
;//////////////////////////////////////////////ESCRIBIR DATO EN EEPROM///////////////////////////////////////////////////
ESCRIBIR_DATO ;clrwdt
GIE_OFF
;BANK0 ;selecciona banco 0
movf DIR_EEPROM,W ;temporal de direccion de la eeprom de datos
;BANK1 ;selecciona banco 1
movwf EEADR ;direccion a acceder
;BANK0 ;selecciona banco 0
movf DATO_EEPROM,W ;temporal de dato de la eeprom de datos
;BANK1 ;selecciona banco 1
movwf EEDATA ;dato a grabar
bcf EECON1,EEPGD ;Puntero a la memoria de datos
bcf EECON1,CFGS ;Acceso a la EEPROM
bsf EECON1,WREN ;habilita escritura
;GIE0
movlw 0X55 ;valores imprencindibles para la grabacion de datos en eeprom de datos
movwf EECON2 ;"
movlw 0XAA ;"
movwf EECON2 ;"
;GIE1
bsf EECON1,WR ;inicia escritura
btfsc EECON1,WR ;comprueva si se grabo el dato
goto $-2 ;si lo ha grabado continua.en caso contrario repite la comprobacion.
GIE_ON
bcf EECON1,WREN ;deshabilitar escritura en eeprom
movf EEADR,W;DIR_EEPROM ;carga el valor de DIR_EEPROM en W
call VERIFICA ;salta a subprograma de verificacion de la correcta grabacion en eeprom de datos
;GIE1
return ;retorna
VERIFICA call LEER_DATO ;salta a subprograma de lectura de dato de la eeprom de datos
movf TEMP_EEP,W ;carga el contenido de TEMP_EEP en W
xorwf DATO_EEPROM,W ;comprueva si es el dato se ha grabado correctamente
btfsc STATUS,Z
return ;si es correcto.retorna
call ESCRIBIR_DATO ;en caso contrario,vuelve a grabar el dato
return ;retorna
;///////////////////////////////////////////LEER DATO DE MEMORIA EEPROM ///////////////////////////////////////////////////////
LEER_DATO ;BANK1
bcf EECON1,EEPGD ;Puntero a la memoria de datos
bcf EECON1,CFGS ;Acceso a la EEPROM
movf DIR_EEPROM,W
movwf EEADR ;escribir direccion de memoria eeprom
bsf EECON1,RD ;ORDEN DE LECTURA
LEE btfsc EECON1,RD ;espera a que se realize la lectura del dato
goto LEE
movf EEDATA,W ;carga valor de eeprom en el registro W
;BANK0 ;selecciona banco 0
movwf TEMP_EEP ;carga el valor leido de eeprom de datos al registro TEMP_EEP
return ;retorna