aqui pongo una rutina para usar un teclado por resistencias.hay que configurar ADCON0 correctamente antes de su llamada.es para un 18f2550
;ESTE PROGRAMA DEVUELVE EN W,EL VALOR ANALOGICO INTRODUCIDO EN AN0,AN1,AN2 O A43 aunque esta modificado para funcionar solo con AN3
;si introducimos un valor inferior a TOPE_TECLA,y metemos un valor de voltage en uno de las cuatro entradas analogicas,
;ese valor se introduce en TEMP_ANALOG.el programa solo lee un pin a la vez,es decir si introducimos voltage en los dos
;pin,solo se tendra encuenta el primer voltage que se halla aplicado.
;
;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 118ms a 48Mhz
CBLOCK BOTON_PULS_VAR
TEMP_ANALOG ;registro de tecla pulsada
COMPARADOR
PREVALECE
CONT_REG
CONT_COINC
ENDC
#define VALOR_TOPE .240 ;valor tope de tecla sin pulsar
#define INI_RAM 0XF6 ;zona donde se ubicaran los datos analogicos de tecla pulsada
#define INI_TABLA 0XEC
BOTON_PULS movlw INI_RAM
movwf FSR0L
movlw BANCO_GENERAL
movwf FSR0H
REPE call DAT_AN ;lee dato analogico
movlw VALOR_TOPE
cpfslt TEMP_ANALOG
return ;si el valor analogico de la tecla es superior a TOPE_TECLA repite busqueda analogica(sin pulsar)
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
;********************************************************BUSCA_REP**********************************************************************;
; ;
;//////////////////////////////////////aqui leemos la ram y buscamos el dato mas repetido///////////////////////////////////////////////;
;//en este subprograma 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,PREVALECE ;introduce el valor contenido en ram al registro prevalescente
dis1 incf FSR0L,F ;siguiente direccion
movf INDF0,W ;carga valor direccionado en W
cpfsgt PREVALECE ;comprueba si es mayor
movff INDF0,PREVALECE ;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 PREVALECE,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
movf INDF0,w ;introduce valor en W
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 ;BANK0 ;selecciona banco 0
;GIE_OFF ;GIE0 ;deshabilita las interrupciones
;btfsc INTCON,GIE
;goto GIE_OFF
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