Un posible planteamiento:
Se utiliza el mdulo A/D para realizar la conversin de la entrada de tensin
del canal analgico 0.
Se configura el mdulo A/D para que utilice el reloj basado en la red RC
interna independiente del oscilador del microcontrolador (valor nominal de
Tad de 4s y con una variacin posible entre 2s y 6s). Se lanza la
conversin con el canal seleccionado y se activa la generacin de
interrupciones cuando finalice dicha conversin.
El mdulo A/D puede proporcionar el resultado con una resolucin de 10 bits
(de b9 a b0) en dos registros: ADRESH y ADRESL, pudiendo realizarse la
justificacin del resultado a la izquierda, con este resultado:
SUMA_ALT
O
Subprograma de conversin de Binario a BCD (BINBCD)
Se puede utilizar cualquiera de los ejemplos de conversin de Binario a BCD
que estn disponible.
Algoritmo desarrollado:
INICIALIZACIN
CONVERTIDOR A/D:
-Entrada RA0 como analgica y referencia de 5V, resto entradas digitales. El
resultado de la conversin lo recogeremos ajustado a la izquierda (los 8 bits
ms significativos en el registro ADRESH)
-Reloj de conversin Tad basado en red RC interna (4s)
-Canal analgico de entrada: canal 0.
PUERTOS:
-PORTA (RA1, RA2 y RA3 con salidas para activacin de los displays, resto
de las lneas como entradas).
-PORTD (salida para control de los segmentos)
TMR0: definido en modo temporizador y con prescaler de 32 para
temporizar posteriormente 5 ms.
Subprograma PRODUCTO_2
Realiza el producto de los 8 bits contenidos en FACTOR1 por los 8 bits
almacenados en la posicin FACTOR2 y el resultado en conjunto, va a parar
a dos posiciones denominadas: BIN_ALTO + BIN_BAJO (vase detalle del
algoritmo en el planteamiento inicial)
;
;
;
;
;
;
;
;Fichero de inclusin
CBLOCK 0x20
FACTOR1, FACTOR2
SUMA_ALTO, SUMA_BAJO
BIN_ALTO,BIN_BAJO
CONTADOR
ENDC
; Esta parte de cdigo slo llama al subprograma y se queda esperando en un bucle infinito
; hasta que detengamos el programa desde el entorno MPLAB para comprobar el resultado que
; se obtiene en BIN_ALTO y BIN_BAJO
ESPERA
ORG
CALL
GOTO
0
PRODUCTO_2
ESPERA
OTRO_BIT
btfsc
incf
movf
addwf
decfsz
goto
return
A_ROTAR bcf
rlf
rlf
goto
FACTOR1,W
SUMA_BAJO
FACTOR2
;Rotamos a la derecha para comprobar
STATUS,C ;en el carry el bit que "toque"
OTRO_BIT ;si el carry qued a 0 es que no hay que sumar
SUMA_BAJO,W
;si qued a 1 es que hay que sumar
BIN_BAJO,F
;la parte baja del acumulador con el sumando
;que corresponde al FACTOR1 desplazado a la izq.
STATUS,C ;comprobamos si hubo acarreo en esa suma
BIN_ALTO ;si hubo, sumamos 1 al siguiente byte
SUMA_ALTO,W
;sumamos la parte alta del acumulador con
BIN_ALTO,F
;el FACTOR1 desplazado
CONTADOR,F
A_ROTAR
END
Subprograma BINBCD
Se encarga de tomar los 16 bits almacenados en las posiciones BIN_ALTO y
BIN_BAJO y devuelve los 5 dgitos BCD correspondientes a la representacin
decimal de ese valor que almacena en 3 posiciones de RAM:
;
;
;
;
;
;
;
;
;
; Esta versin realiza sucesivas restas por diez mil, mil, cien y diez
; hasta que el resultado sea inferior a estos valores para ir obteniendo
; los sucesivos dgitos decimales
;
; Posiciones Auxiliares:
CBLOCK 0x20
MINU_ALTO
MINU_BAJO
SUSTRA_ALTO
SUSTRA_BAJO
RESTO_ALTO
RESTO_BAJO
AUXILIAR
BIN_ALTO
BIN_BAJO
BCD2, BCD1, BCD0
ENDC
list p=16f877
include "p16f877.inc"
;Microcontrolador PIC16f877
;Fichero de inclusin
ORG
CALL
GOTO
BIN16BCDv2
ESPERA
;Llamamos al subprograma
;y nos quedamos esperando a la vuelta
ORG
BIN16BCDv2
clrf
clrf
clrf
0x100
BCD2
BCD1
BCD0
;Pongo a cero
;las posiciones finales
;donde irn a parar los dgitos decimales
DEC_MIL movf
movwf
movf
movwf
BIN_ALTO,W
MINU_ALTO
BIN_BAJO,W
MINU_BAJO
0x27
SUSTRA_ALTO
0x10
SUSTRA_BAJO
ESPERA
movlw
movwf
movlw
movwf
RESTADM call
btfss
goto
incf
movf
movwf
movf
movwf
goto
RESTA16
;Llamamos al subprograma que hace la resta de dos bytes
STATUS,C ;Si carry queda a 1 es que el resultado es >= 0
UN_MIL
;si no, vamos a obtener las unidades de mil
BCD2
;si era positivo incrementamos decenas de mil y seguimos
RESTO_ALTO,W
;Paso el resultado al minuendo
MINU_ALTO
;en su parte alta
RESTO_BAJO,W
;y tambin en su parte baja
MINU_BAJO
RESTADM
;Volvemos a restar ya que el resultado es mayor de d'10000'
UN_MIL
0x03
SUSTRA_ALTO
0xE8
SUSTRA_BAJO
movlw
movwf
movlw
movwf
RESTAUM call
btfss
goto
movlw
addwf
movf
movwf
movf
movwf
goto
RESTA16
;Llamamos al subprograma de resta de dos bytes
STATUS,C ;Si carry queda a 1 es que el resultado es >= 0
CENTENAS ;si no, vamos a las CENTENAS
0x10
;si era positivo incrementamos unidades de mil y seguimos
BCD1
RESTO_ALTO,W
;Cargo el resultado en el minuendo para repetir la resta
MINU_ALTO
RESTO_BAJO,W
MINU_BAJO
RESTAUM
;Volvemos a restar porque el resultado es mayor que d'1000'
CENTENAS
clrf
movlw
movwf
RESTACN call
btfss
goto
incf
movf
movwf
movf
movwf
goto
RESTA16
;Resta de dos bytes de nuevo
STATUS,C ;Si carry queda a 1 es que el resultado es >= 0
DECENAS
;si no, vamos a las DECENAS
BCD1
;si era positivo incrementamos centenas y seguimos
RESTO_ALTO,W
;Cargamos el resultado en el minuendo para otra resta
MINU_ALTO
RESTO_BAJO,W
MINU_BAJO
RESTACN
;Repetimos por ser el resultado mayor que d'100'
DECENAS movlw
subwf
0x0A
MINU_BAJO,W
btfss
goto
movwf
movlw
addwf
goto
FINAL
movf
MINU_BAJO,W
;Lo que qued son ya unidades
addwf
BCD0,F
;que situamos en BCD0
return
;***************************************************************************************
; Subprograma que realiza la resta en 16 bits:
; Resta minuendo(16 bits) menos sustraendo(16 bits) y el resultado va al resto (16 bits)
;
(MINU_ALTO & MINU_BAJO)-(SUSTRA_ALTO & SUSTRA_BAJO) -> (RESTO_ALTO & RESTO_BAJO)
;***************************************************************************************
RESTA16 MOVF
SUSTRA_ALTO,W
;Cargamos parte alta del SUSTRAENDO en posicin AUXILIAR
MOVWF
AUXILIAR
MOVF
SUSTRA_BAJO,W
;Cargo la parte baja del sustraendo en W
SUBWF
MINU_BAJO,W
;y hago la resta de parte baja
BTFSS
STATUS,C ;observo cmo qued el Carry
INCF
AUXILIAR ;Si qued a 0 es que "debo" una a la parte
;alta del minuendo y corrijo sumando 1 a la parte alta
;del sustraendo
MOVWF
RESTO_BAJO
;Guardo la parte baja del resultado
MOVF
SUBWF
AUXILIAR,W
MINU_ALTO,W
MOVWF
RESTO_ALTO
;El resultado lo guardo en la parte alta del resto
RETURN
;********************************************************************************
END
Algoritmo utilizado:
INICIALIZACIN
Puertos: PORTD de entrada en sus 4 lneas altas e inicialmente de salida
en sus 4 lneas ms bajas para enviar datos y comandos al LCD, aunque
ser de entrada en algunos intervalos para leer estado del LCD (flag BF por
ejemplo)
PORTA ser de salida en 3 de sus bits (RA1, RA2 y RA3) para manejar las
lneas de control del LCD (RS,R/W y E), son salidas permanentemente. Resto
de lneas del PORTA de entrada
Definimos todas entradas como digitales en el PORTA . Aunque RA1, RA2 y
RA3 vayan a ser lneas de salida, se van a utilizar instrucciones del tipo BSF
y BCF sobre ellas. Estas instrucciones leen primero todo el puerto y
vuelven a sacar valores: modifican el bit al que afecta la instruccin y el
resto de los bits vuelven a salir con el valor que se ha ledo. Si estn activas
las entradas como analgicas, stas sern ledas siempre como ceros
(vase esquema del PORTA) y saldrn siempre como tales ceros en los bits
del PORTA no afectados por la instruccin