TODOPIC

Otros Microcontroladores / Dispositivos programables => ** PROYECTOS ** => Mensaje iniciado por: jdj en 10 de Diciembre de 2004, 02:39:00

Título: Regulación de la ventilación de una granja
Publicado por: jdj en 10 de Diciembre de 2004, 02:39:00
Hola estoy realizando mi proyecto final de carrera y estoy diseñando un regulador de ventilación para controlarlo desde un ordenador. Lo que me piden a parte del diseño del regulador, es: - Que controle la temperatura actual de la sala.
- temperatura de calefacción.
- ventilación %.
-temperatura en la placa de los gorrines.
Habrá unas ventanas automáticas que abran o cierren según la tª que se necesite en la sala, y también un ventilador que se active cuando haga falta.
Me habían aconsejado utilizar el PIC16F873 y el protocolo de comunicación RS485 pero necesito con urgencia un programa que me controle estos parámetros.
Si alguien puede aportarme algo le estaré muy agradecido, gracias!!!!
mi E-maiL: jdj_valt@hotmail.comNavidad
Título: RE: Regulación de la ventilación de una granja
Publicado por: el_dardo2004 en 05 de Mayo de 2005, 10:06:00
Buenas k tal
Respecto a tu proyecto del protocolo rs485 no tengo nada pero si te sirve de algo, tengo el programa de comunicacion con el rs232.
Tambien para el control de temperatura i para controlar el ventilador. Estos dos ultimos se utilitza el pic que tu has comentado.
Pero la comunicacion rs232 utiliza el pic 16f84
Haver si te sirve de ayuda
Saludos

Ejemplo para MicroPIC Trainer y Trainer PLUS. Comunicación serie gestionada por software.
;
;Haciendo uso de las rutinas incluidas en el fichero RS232LOW.INC, se trata de utilizar el
;canal RS232 de la Trainer PLUS para comunicar vía serie con diferentes periféricos. En los
;ejemplos aquí propuestos se utilizará un PC para que, con el software TERMINAL.EXE, actue
;como un simple terminal de comunicaciones. El usuario deberá preparar los cables de comuni-
;cación entre la Trainer PLUS y el PC, teniendo en cuenta de cruzar la señal de Transmisión
;(TxD) con la de recepción (RxD) y viceversa.
;
;Este ejemplo es similar al anterior. Propone esperar a recibir un carácter desde el ter-
;minal para, inmediatamente, retransmitirlo al mismo a modo de ECO y visualizarlo sobre la
;pantalla LCD de la uPIC Trainer.

      List   p=16F84      ;Tipo de procesador
      include   "P16F84.INC"   ;Definiciones de registros internos

CLKIN      equ   .4000000   ;Frecuencia de trabajo
BAUDIOS      equ   .9600      ;Velocidad de comunicación
T_MODO      equ   1      ;Transmite primero bit LSB
R_MODO      equ   1      ;Recibir primero bit LSB
T_Nbit      equ   8      ;Transmite caracteres de 8 bits
R_Nbit      equ   8      ;Recibe caracteres de 8 bits
Sbit      equ   2      ;Transmite 2 bits de stop
                 
Lcd_var      equ   0x0c      ;Inicio de las variables para rutinas LCD
Rs232_var   equ   0x0e      ;Inicio de las variables para rutinas RS232
Lineas      equ   0x13      ;Contador de líneas
Caracteres   equ   0x14      ;Contador de caracteres
               
      org   0x00      ;Vector de reset
      goto   Inicio
      org   0x05      ;Salvar el vector de interrupción   
               
      include   "RS232LOW.INC"   ;Incluir rutinas de comunicación
      include "LCD_CXX.INC"   ;Incluir rutinas LCD                     

Inicio:      bsf   STATUS,RP0   ;Selecciona página 1 de datos
      movlw   b"10001111"   ;Preescaler de 128 para el WDT. Pull_Up Off
      movwf   OPTION_REG   
      movlw   b"11101111"
      movwf   TRISB      ;RB5 entrada y RB4 salida
      bcf   STATUS,RP0   ;Selecciona página 0 de datos   

      call   UP_LCD      ;Inicia E/S para el módulo LCD
      call   LCD_INI      ;Inicialización del módulo LCD
      movlw   b"00001111"
      call   LCD_REG      ;LCD on, Cursor On y Blink On

LCD_HOME   movlw   b"00000001"
      call   LCD_REG      ;Borra LCD y Home
      movlw   .16
      movwf   Caracteres   ;Inicia contador de caracteres
      movlw   .2
      movwf   Lineas      ;Inicia contador de líneas
            
Loop      clrwdt
      bsf   STATUS,RP0   ;Selecciona página 1
      movlw   b"11101111"
      movwf   TRISB      ;RB5 entrada y RB4 salida
      bcf   STATUS,RP0

      bsf   Txd_pin      ;Línea de transmisión a "1"
      bsf   Rxd_pin      ;Línea de recepción a "1"

      call   RxD      ;Espera a recibir un carácter
      movf   Rxdreg,W   ;Lee el carácter recibido
      movwf   Txdreg
      call   TxD      ;Retransmite carácter recibido (ECO)
      call   UP_LCD      ;Reconfigura E/S para el LCD
      movlw   .13
      subwf   Rxdreg,W   ;Mira si carácter recibido es CR
      btfsc   STATUS,Z   ;No
      goto   LCD_HOME   ;Si, borra LCD
      movf   Rxdreg,W
      call   LCD_DATO   ;Visualiza carácter en el LCD

      decfsz   Caracteres,F   ;Decrementa contador de caracteres
      goto   Loop

      movlw   .16
      movwf   Caracteres   ;Inicia contador de caracteres
      movlw   0xc0
      call   LCD_REG      ;Selecciona segunda línea del LCD
      decfsz   Lineas,F   ;Se han completado 2 líneas ??
      goto   Loop      ;No      
      goto   LCD_HOME   ;Si, borrar pantalla

      end         ;Fin del programa fuente
;**************************************************************
Ejemplo MicroPIC Trainer y Micro"PIC I/O
;
;El módulo conversor ADC. Medida de temperatura ambiente.
;
;Los dispositivos PIC16F87X disponen de un convertidor A/D de 10 bits de resolución y 5 u 8
;canales de entrada analógica. La tensión de referencia determina la resolución por bit:
;(Res. = Vref/1024). Con 5 Vref=4.86 mV/Bit; con 2.5 Vref=2.43 mV/Bit
;
;El sensor de tª de la tarjeta Micro"PIC I/O proporciona una tensión analógica de 10mV/ºC,
;que se aplica al canal ADC RA5/AN4. El ADC trabaja con una tensión de referencia externa de
;2.5V que se obtiene desde la tarjeta Micro"PIC I/O y se aplica en RA3/Vref. Aproximadamente
;se toma una muestra de la temperatura actúal cada segundo
;
;La pantalla LCD visualiza la temperatura.

      List   p=16F873   ;Tipo de procesador
      include   "P16F873.INC"   ;Definiciones de registros internos

Lcd_var      equ   0x20      ;Variables para las rutinas del LCD
DatoA_H      equ   0x22
DatoA_L      equ   0x23      ;Multiplicando de 16 bits
DatoB_H      equ   0x24
DatoB_L      equ   0x25      ;Multiplicador de 16 bits
DatoD_H      equ   0x26
DatoD_L      equ   0x27
DatoC_H      equ   0x28
DatoC_L      equ   0x29      ;Resultado de 32 bits
Contador   equ   0x2a      ;Variable contadora
BCD_2      equ   0x2b
BCD_1      equ   0x2c
BCD_0      equ   0x2d      ;Variables BCD
Temporal   equ   0x2e      ;Variable temporal
Delay      equ   0x2f      ;Variable de temporización

      org   0x00      ;Vector de Reset
      goto   Inicio

      org   0x05      ;Salva el vector de interrupción
      
      include "LCD_CXX.INC"   ;Incluye rutinas de manejo del LCD

;Mul16x16: Esta rutina multiplica sin signo dos números de 16 bits (DatoB_HMuchas risasatoB_L *
;DatoA_HMuchas risasatoA_L) el resultado de 32 bits se deposita en (DatoD_HMuchas risasatoD_L y DatoC_HMuchas risasatoC_L)

Mul16x16   movlw   .16
      movwf   Contador   ;Inicia contador
      clrf   DatoD_H
      clrf   DatoD_L      ;Borra parte alta del resultado

Mul_Loop   rrf   DatoB_H,F
      rrf   DatoB_L,F
      btfss   STATUS,C   ;El bit LSB es "1" ?
      goto   No_suma      ;No
      movf   DatoA_L,W
      addwf   DatoD_L,F   ;Suma octeto de menos peso
      btfsc   STATUS,C
      incf   DatoD_H,F
      movf   DatoA_H,W
      addwf   DatoD_H,F   ;Suma octeto de más peso
No_suma      rrf   DatoD_H,F
      rrf   DatoD_L,F
      rrf   DatoC_H,F
      rrf   DatoC_L,F
      decfsz   Contador,F
      goto   Mul_Loop
      return

;16Bits_BCD: Esta rutina convierte un número binario de 16 bits situado en DatoC_H y
;DatoC_L en 5 dígitos BCD que se depositan en las variables BCD_0, BCD_1 y BCD_2, siendo
;esta última la de menos peso. Está presentada en la nota de aplicación AN544 de MICROCHIP
;y adaptada por Microsystems Engineering

Bits16_BCD   bcf   STATUS,C
      clrf   Contador   
      bsf   Contador,4   ;Carga el contador con 16      
      clrf   BCD_0
      clrf   BCD_1
      clrf   BCD_2      ;Puesta a 0 inicial

Loop_16      rlf   DatoC_L,F
      rlf   DatoC_H,F
      rlf   BCD_2,F
      rlf   BCD_1,F
      rlf   BCD_0,F      ;Desplaza a izda. (multiplica por 2)
      decfsz   Contador,F
      goto   Ajuste
      return

Ajuste      movlw   BCD_2
      movwf   FSR      ;Inicia el índice
      call   Ajuste_BCD   ;Ajusta el primer byte
      incf   FSR,F
      call   Ajuste_BCD   ;Ajusta el segundo byte
      incf   FSR,F
      call   Ajuste_BCD
      goto   Loop_16

Ajuste_BCD   movf   INDF,W      
      addlw   0x03
      movwf   Temporal   
      btfsc   Temporal,3   ;Mayor de 7 el nibble de menos peso ??
      movwf   INDF      ;Si, lo acumula
      movf   INDF,W      
      addlw   0x30
      movwf   Temporal
      btfsc   Temporal,7   ;Mayor de 7 el nibble de menos peso ??
      movwf   INDF      ;Si, lo acumula
      return

;Programa principal

Inicio           clrf   PORTA
      clrf   PORTB
      bsf   STATUS,RP0   ;Selecciona banco 1
      movlw   b"00000110"
      movwf   ADCON1      ;Puerta A digital
      clrf   TRISB      ;Puerta B se configura como salida
      clrf   TRISA      ;RA4-RA0 salidas
      movlw   b"11000111"
      movwf   OPTION_REG   ;Preescaler de 128 asociado al TMR0
      bcf   STATUS,RP0   ;Selecciona banco 0

      call   UP_LCD      ;Configuración de E/S para el LCD
      call   LCD_INI      ;Inicialización del LCD
      movlw   b"00001100"
      call   LCD_REG      ;LCD On, cursor y Blink Off

Loop      bsf   STATUS,RP0   ;Selecciona página 1
      movlw   b"00101000"
      movwf   TRISA      ;RA3 y RA5 entradas
      movlw   b"10000001"   ;Justificación dcha. RA5/AN4 entrada analógica
      movwf   ADCON1      ;RA3/Vref entrada de tensión de referencia
      bcf   STATUS,RP0   ;Selecciona página 0

;ADC en On con frecuencia de Fosc/32 y seleción del canal RA5/AN4

      movlw   b"10100001"
      movwf   ADCON0

;Temporizar 1 segundo mediante el TMR0. Este, con un preescaler de 256, evoluciona cada
;256uS. Se carga con 195 para realizar una temporización de 50mS. Los 50 mS se repiten 20
;veces para conseguir un segundo. Seguidamente se toma una muestra de la temperatura.

      movlw   .20
      movwf   Delay
Delay_1      movlw   ~.195
      movwf   TMR0      ;Inicia el TMR0
      bcf   INTCON,T0IF   ;Restaura el flag del TMR0
Delay_2      clrwdt
      btfss   INTCON,T0IF   ;Han pasado 50 mS ??
      goto   Delay_2      ;Todavía no
      decfsz   Delay,F      ;Se ha repetido 20 veces ??
      goto   Delay_1      ;No

      bcf   PIR1,ADIF   ;Restaurar el flag del ADC
      bsf   ADCON0,GO   ;Inicio de conversión
ADC_Wait   btfss   PIR1,ADIF   ;Fin de conversión ??
      goto   ADC_Wait   ;Todavía no, esperar

;Al resultado de la conversión se le multiplica por 243 (2.43) que es la resolución por bit.
;P.Ej. La Tª es de 25.6º, como el sensor proporciona 10mV/ºC la tensión a convertir será de
;256 mV. Siendo la resolución de 2.43mV/bit el resultado de la conversión dará 0x69 (105)
;que, multiplicado por 0xf3 (243) queda un resultado de 0x63ab (25515). Se desplaza la coma
;tres posiciones a la izda. y queda finalmente 25.5º (un error de +/- 1 bit)

      bsf   STATUS,RP0   ;Banco 1
      movf   ADRESL,W
      bcf   STATUS,RP0
      movwf   DatoB_L
      movf   ADRESH,W
      movwf   DatoB_H      ;Carga el multiplicando (valor de conversión)
      movlw   .243
      movwf   DatoA_L
      clrf   DatoA_H      ;Carga el multiplicador (243)

      call   Mul16x16   ;Multiplica
      call   Bits16_BCD   ;Convierte a BCD
      
;Visualiza el resultado sobre la pantalla LCD. La pantalla LCD se actualiza por tanto a cada
;segundo
      
      bsf   STATUS,RP0   ;Selecciona banco 1
      movlw   b"00000110"
      movwf   ADCON1      ;Puerta A digital
      bcf   STATUS,RP0   ;Selecciona banco 0
      call   UP_LCD      ;Reconfigura puertos para el LCD
      movlw   0x80
      call   LCD_REG      ;Posiciona el cursor
      movf   BCD_0,W
      andlw   0x0f
      iorlw   0x30
      call   LCD_DATO   ;Visualiza decenas de grado
      swapf   BCD_1,W
      andlw   0x0f
      iorlw   0x30
      call   LCD_DATO   ;Visualiza unidades de grado
      movlw   "."
      call   LCD_DATO   ;Visualiza punto decimal
      movf   BCD_1,W
      andlw   0x0f
      iorlw   0x30
      call   LCD_DATO   ;Visualiza décimas de grado
      movlw   " "
      call   LCD_DATO   ;Visualiza un " "
      movlw   0xdf
      call   LCD_DATO   ;Visualiza símbolo º
      movlw   "C"
      call   LCD_DATO   ;Visualiza C
      goto   Loop

      end         ;Fin del programa fuente
;**************************************************************
Ejemplo MicroPIC Trainer y Micro"PIC I/O
;
;El módulo conversor ADC. Variando la velocidad de un motor. Medir las rpm
;
;Los dispositivos PIC16F87X disponen de un convertidor A/D de 10 bits de resolución y 5 u 8
;canales de entrada analógica. La tensión de referencia determina la resolución por bit:
;(Res. = Vref/1024). Con 5 Vref=4.8 mV/Bit; con 2.5 Vref=2.4 mV/Bit
;
;Se propone la regulación de velocidad del motor CC de la tarjeta Micro"PIC I/O mediante
;PWM. Para ello, el potenciómetro AN3 de la Micro"PIC Trainer conectado a la línea RA3/AN3,
;determina la duración de la anchura del pulso. El valor de dicho potenciómetro es leído
;cada 50 mS.
;
;La salida PWM en RC2/CCP1 se conecta a la señal Enable del motor. RC7 y RC6 determinan el
;sentido de giro. La salida del encoder se conecta a RC0/T1CKI para contar el número de
;pasos dado por el motor, durante un lapsus de 1 segundo.
;
;En la pantalla LCD se visualizará las rpm a las que gira el motor.

      List   p=16F873   ;Tipo de procesador
      include   "P16F873.INC"   ;Definiciones de registros internos

Lcd_var      equ   0x20      ;Variables para las rutinas del LCD
Duty_H      equ   0x22
Duty_L      equ   0x23      ;Variable para la anchura de pulso
DatoA_H      equ   0x24
DatoA_L      equ   0x25      ;Multiplicando de 16 bits
DatoB_H      equ   0x26
DatoB_L      equ   0x27      ;Multiplicador de 16 bits
DatoD_H      equ   0x28
DatoD_L      equ   0x29
DatoC_H      equ   0x2A
DatoC_L      equ   0x2B      ;Resultado de 32 bits
Contador   equ   0x2c      ;Variable contadora
BCD_2      equ   0x2d
BCD_1      equ   0x2e
BCD_0      equ   0x2f      ;Variables BCD
Temporal   equ   0x30      ;Variable temporal
Delay      equ   0x31      ;Variable de temporización

      org   0x00      ;Vector de Reset
      goto   Inicio

      org   0x05      ;Salva el vector de interrupción
      
      include "LCD_CXX.INC"   ;Incluye rutinas de manejo del LCD

;Mul16x16: Esta rutina multiplica sin signo dos números de 16 bits (DatoB_HMuchas risasatoB_L *
;DatoA_HMuchas risasatoA_L) el resultado de 32 bits se deposita en (DatoD_HMuchas risasatoD_L y DatoC_HMuchas risasatoC_L)

Mul16x16   movlw   .16
      movwf   Contador   ;Inicia contador
      clrf   DatoD_H
      clrf   DatoD_L      ;Borra parte alta del resultado

Mul_Loop   rrf   DatoB_H,F
      rrf   DatoB_L,F
      btfss   STATUS,C   ;El bit LSB es "1" ?
      goto   No_suma      ;No
      movf   DatoA_L,W
      addwf   DatoD_L,F   ;Suma octeto de menos peso
      btfsc   STATUS,C
      incf   DatoD_H,F
      movf   DatoA_H,W
      addwf   DatoD_H,F   ;Suma octeto de más peso
No_suma      rrf   DatoD_H,F
      rrf   DatoD_L,F
      rrf   DatoC_H,F
      rrf   DatoC_L,F
      decfsz   Contador,F
      goto   Mul_Loop
      return

;Visualizar: Visualiza sobre la pantalla LCD los cinco dígitos situados en las variables
;BCD_0, BC_1 y BCD_2, seguido de la inscripción "rpm"

Visualizar   movlw   0x80
      call   LCD_REG      ;Posiciona el cursor
      movlw   3
      movwf   Contador   ;Inicia contador de bytes a convertir
      movlw   BCD_0
      movwf   FSR      ;Inicia puntero índice
Visual_loop   swapf   INDF,W
      andlw   0x0f
      iorlw   0x30      ;Convierte a ASCII el nible de más peso
      call   LCD_DATO   ;Lo visualiza
      movf   INDF,W
      andlw   0x0f
      iorlw   0x30      ;Convierte a ASCII el nible de menos peso
      call   LCD_DATO   ;Lo visualiza
      decf   FSR,F      ;Siguiente byte
      decfsz   Contador,F
      goto   Visual_loop
      movlw   " "
      call   LCD_DATO
      movlw   "r"
      call   LCD_DATO
      movlw   "p"
      call   LCD_DATO
      movlw   "m"
      call   LCD_DATO   ;Visualiza "rpm"
      return

;16Bits_BCD: Esta rutina convierte un número binario de 16 bits situado en DatoC_H y
;DatoC_L en 5 dígitos BCD que se depositan en las variables BCD_0, BCD_1 y BCD_2, siendo
;esta última la de menos peso. Está presentada en la nota de aplicación AN544 de MICROCHIP
;y adaptada por Microsystems Engineering

Bits16_BCD   bcf   STATUS,C
      clrf   Contador   
      bsf   Contador,4   ;Carga el contador con 16      
      clrf   BCD_0
      clrf   BCD_1
      clrf   BCD_2      ;Puesta a 0 inicial

Loop_16      rlf   DatoC_L,F
      rlf   DatoC_H,F
      rlf   BCD_2,F
      rlf   BCD_1,F
      rlf   BCD_0,F      ;Desplaza a izda. (multiplica por 2)
      decfsz   Contador,F
      goto   Ajuste
      return

Ajuste      movlw   BCD_2
      movwf   FSR      ;Inicia el índice
      call   Ajuste_BCD   ;Ajusta el primer byte
      incf   FSR,F
      call   Ajuste_BCD   ;Ajusta el segundo byte
      incf   FSR,F
      call   Ajuste_BCD
      goto   Loop_16

Ajuste_BCD   movf   INDF,W      
      addlw   0x03
      movwf   Temporal   
      btfsc   Temporal,3   ;Mayor de 7 el nibble de menos peso ??
      movwf   INDF      ;Si, lo acumula
      movf   INDF,W      
      addlw   0x30
      movwf   Temporal
      btfsc   Temporal,7   ;Mayor de 7 el nibble de menos peso ??
      movwf   INDF      ;Si, lo acumula
      return

;ADC: Se activa el ADC y se selecciona el canal RA3/AN3. Frecuencia de trabajo Fosc/32.
;Finalizada la conversión, se actualiza el valor de la anchura de pulso

ADC      bsf   STATUS,RP0   ;Selecciona banco 1
      clrf   ADCON1      ;Puerta A analógica
      bcf   STATUS,RP0   ;Selecciona banco 0
      movlw   b"10011001"
      movwf   ADCON0      ;Módulo ADC en On
      bcf   PIR1,ADIF   ;Restaurar el flag del ADC
      nop
      bsf   ADCON0,GO   ;Inicio de conversión
ADC_Wait   btfss   PIR1,ADIF   ;Fin de conversión ??
      goto   ADC_Wait   ;Todavía no, esperar
      movf   ADRESH,W
      movwf   CCPR1L      ;Carga los 8 bits de más peso para el PWM
      bsf   STATUS,RP0   ;Selecciona banco 1
      rrf   ADRESL,F
      rrf   ADRESL,W
      
;El módulo CCP1 actúa en el modo PWM con salida por RC2/CCP1.

      andlw   b"00110000"
      iorlw   b"00001100"
      bcf   STATUS,RP0   ;Selecciona banco 0
      movwf   CCP1CON      ;CCP1 en modo PWM
      return

;Programa principal

Inicio           clrf   PORTA
      clrf   PORTB
      clrf    PORTC
      bsf   STATUS,RP0   ;Selecciona banco 1
      movlw   b"00000110"
      movwf   ADCON1      ;Puerta A digital
      clrf   TRISB      ;Puerta B se configura como salida
      clrf   TRISA      ;RA4-RA0 salidas
      movlw   b"00111011"
      movwf   TRISC      ;RC2/CCP1, RC6 y RC7 salidas, RC0/T1CKI entrada
      movlw   b"11000111"
      movwf   OPTION_REG   ;Preescaler de 256 asociado al TMR0
      movlw   .250
      movwf   PR2      ;Periodo del PWM de 4 mS
      bcf   STATUS,RP0   ;Selecciona banco 0

      call   UP_LCD      ;Configuración de E/S para el LCD
      call   LCD_INI      ;Inicialización del LCD
      movlw   b"00001100"
      call   LCD_REG      ;LCD On, cursor y Blink Off

;El TMR2 emplea un preescaler de 1:16. Evoluciona cada 16 uS

      call   ADC      ;Conversión y ajuste PWM inicial
      movlw   b"00000110"
      movwf   T2CON      ;TMR2 en On

;El TMR1 actua como contador externo con entrada por RC0/T1CKI y preescaler 1:1

Loop      movlw   b"00000010"
      movwf   T1CON      ;TMR1 en Off
      clrf   TMR1H
      clrf   TMR1L      ;Inicia el TMR1

      bsf   PORTC,6      ;Motor en On, giro horario
      bsf   T1CON,TMR1ON   ;TMR1 en On

;Temporizar 1 segundo mediante el TMR0. Este, con un preescaler de 256, evoluciona cada
;256uS. Se carga con 195 para realizar una temporización de 50mS. Transcurridos esos 50mS
;se lee el valor del potenciómetro RA3/AN3 para actualizar el PWM. Los 50 mS se repiten 20
;veces para conseguir un segundo. Transcurrido este lapsus se captura el contenido del TMR1.

      movlw   .20
      movwf   Delay
Delay_1      movlw   ~.195
      movwf   TMR0      ;Inicia el TMR0
      bcf   INTCON,T0IF   ;Restaura el flag del TMR0
      call   ADC      ;Conversión y ajuste PWM
Delay_2      clrwdt
      btfss   INTCON,T0IF   ;Han pasado 50 mS ??
      goto   Delay_2      ;Todavía no
      decfsz   Delay,F      ;Se ha repetido 20 veces ??
      goto   Delay_1      ;No
      
      bcf   T1CON,TMR1ON   ;Desconecta el TMR1
      
;Si el encoder empleado dispone de 4 ranuras, al valor capturado se divide entre 4 para
;determinar el nº de vueltas por segundo y se multiplica por 60 para obtener el nº de vueltas
;por minuto. Ello es equivalente a multiplicar el valor del TMR1 por 15. Se puede apreciar
;error de +/- 15 rpm

      clrf   DatoA_H
      movlw   .15
      movwf   DatoA_L      ;Inicia el multiplicador
      movf   TMR1H,W
      movwf   DatoB_H
      movf   TMR1L,W
      movwf   DatoB_L      ;Carga el multiplicando
      call   Mul16x16   ;Multiplica 2 números de 16 bits
      call   Bits16_BCD   ;Convierte a BCD el resultado

;Visualiza el resultado sobre la pantalla LCD. La pantalla LCD se actualiza por tanto a cada
;segundo
      
      bsf   STATUS,RP0   ;Selecciona banco 1
      movlw   b"00000110"
      movwf   ADCON1      ;Puerta A digital
      bcf   STATUS,RP0   ;Selecciona banco 0
      call   UP_LCD      ;Reconfigura puertos para el LCD
      call   Visualizar   ;Visualiza sobre pantalla
      goto   Loop

      end         ;Fin del programa fuente
;***************************************************************