Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

07/09/2010 #1

Avatar de Meta

Temporizador para insoladora
Hola:

Quiero hacer un temporizador para una insoladora. Me he puesto con el famoso PIC16F84A pero tiene sus limitaciones.



Usa vez que lo usas sólo puedes ejecutar la cuenta atrás como máximo 4:15. (4 minutos, 15 segundos). Usa el Timer de 8 Bits. He pensarlo en adaptarlo del 16F84A al 16F88 ya que tiene un Timer de 16 bit que significa mejor tiempo.

Quiero saber ya que saben mucho más que yo en temas de temporizadores, si el Timer de 16 bits puede lograr algo. Por ejemplo: Quiero saber cuánto tiempo máximo me deja poner en el LCD y que funcione. Prefiero algo así: 99:99. Con 20 minutos está bien. Que lo vaya a usar para insoladora es mucho tiempo, el mismo circuito lo montaré para otras cosas, por eso quiero saber lo del temporizador.

Estaba pensando es unsar un reloj-calendario en tiempo real llamado DS1307. Muy preciso, pero lleva más electrónica, más caro y complicado de usar en asm.

Código:
; Programa de control para un temporizador digital de precisión. La programación del tiempo
; de temporización se realiza mediante dos pulsadores: "AJUSTE" y "ON/INCREM". Funcionamiento:
;     -    En estado de reposo la salida del temporizador está apagada y el pantalla aparece el
;        tiempo deseado para la próxima temporización.
;     - Si se pulsa "ON/INCREM" comienza la temporización.
;     - Cuando acaba la temporización pasa otra vez a reposo.
;     -    Si pulsa "AJUSTE" antes que haya acabado el tiempo de temporización actúa como pulsador
;        de paro: interrumpe la temporización, apaga la carga y pasa al estado de reposo.
;
; Para ajustar la temporización al tiempo deseado.
;     -    Pulsa "AJUSTE" y ajusta el tiempo deseado mediante el pulsador "ON/INCREM".
;     -    Se vuelve a pulsar "AJUSTE" y pasa a modo de reposo.
;
; Al apagar el sistema debe conservar el tiempo de temporización deseado para la próxima vez
; que se encienda.
;
; ZONA DE DATOS **********************************************************************

    LIST        P=16F84A
    INCLUDE        <P16F84A.INC>
    __CONFIG    _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

    CBLOCK  0x0C
    TiempoDeseado                ; El tiempo deseado de temporización.
    Tiempo                        ; Tiempo que resta de temporización.
    FlagsModos                    ; Guarda los flags con los diferentes
    ENDC                        ; modos de funcionamiento.

    ORG    0x2100                    ; Corresponde a la dirección 0 de la zona
                                ; EEPROM de datos. Aquí se va a guardar el
    DE    0x00                    ; tiempo de temporización deseado.

#DEFINE  F_Temporizador_ON        FlagsModos,2
#DEFINE  F_Temporizador_Ajuste    FlagsModos,1
#DEFINE  F_Temporizador_OFF        FlagsModos,0

#DEFINE  SalidaTemporizador     PORTB,1        ; Salida donde se conecta la carga.
#DEFINE  Zumbador                 PORTB,2        ; Salida donde se conecta el zumbador.
#DEFINE  AjustePulsador            PORTB,7        ; Los pulsadores están conectados a estas
#DEFINE  IncrementarPulsador    PORTB,6        ; líneas del Puerto B.

; ZONA DE CÓDIGOS ********************************************************************

    ORG     0
    goto    Inicio
    ORG    4
    goto    ServicioInterrupcion

Mensajes
    addwf    PCL,F
Mensaje_ON
    DT "   En MARCHA", 0x00
Mensaje_Ajuste
    DT "Tiempo  deseado:", 0x00
Mensaje_OFF
    DT "     PARADO", 0x00

; Instrucciones de inicialización. ------------------------------------------------------
;
Inicio
    call    LCD_Inicializa
    bsf        STATUS,RP0
    movlw    b'10000111'                    ; Prescaler de 256 asignado al TMR0.
    movwf    OPTION_REG
    bsf        AjustePulsador                ; Configurados como entradas.
    bsf        IncrementarPulsador
    bcf        SalidaTemporizador            ; Configurados como salidas.
    bcf        Zumbador
    bcf        STATUS,RP0
    clrw                                ; Lee la posición 0x00 de memoria EEPROM de datos
    call    EEPROM_LeeDato                ; donde se guarda el tiempo deseado de la última vez
    movwf    TiempoDeseado                ; que se ajustó.
    call    ModoTemporizador_OFF        ; Modo de funcionamiento inicial.
    movlw    b'10001000'                    ; Activa interrupciones RBI.
    movwf    INTCON
Principal
    goto    Principal

; Subrutina "ServicioInterrupcion" ------------------------------------------------------
;
; Detecta qué ha producido la interrupción y ejecuta la subrutina de atención correspondiente.

ServicioInterrupcion
    btfsc    INTCON,T0IF
    call    Temporizador
    btfss    INTCON,RBIF                    ; Si es una interrupción RBI lee los pulsadores.
    goto    FinInterrupcion
    btfss    AjustePulsador                ; ¿Está presionado el pulsador de "AJUSTE"?.
    call    CambiarModo                    ; Sí, pues salta a la subrutina correspondiente.
    btfsc    IncrementarPulsador            ; ¿Pulsado "ON/INCREM"?.
    goto    FinInterrupcion                ; No, pues salta al final y sale.
;
    call    Retardo_20ms                ; Espera que se estabilice el nivel de tensión.
    btfsc    IncrementarPulsador            ; Si es un rebote del pulsador "ON/INCREM" sale fuera.
    goto    FinInterrupcion
    btfsc    F_Temporizador_OFF            ; ¿Estaba en reposo cuando pulsó "ON/INCREM"?
    call    ModoTemporizador_ON            ; Sí, pues comienza la temporización.
    btfsc    F_Temporizador_Ajuste        ; ¿Estaba ajustando tiempo?
    call    IncrementarTiempoDeseado    ; Sí, pues pasa a incrementar el tiempo deseado.
FinInterrupcion
    bcf        INTCON,RBIF                    ; Limpia los flags de reconocimiento.
    bcf        INTCON,T0IF
    retfie

; Subrutinas "CambiarModo" y todas las de MODO de funcionamiento ------------------------
;
; Subrutina de atención a la interrupción producida al presionar el pulsador "AJUSTE" que
; cambia el modo de funcionamiento.

; Hay identificados tres modos de funcionamiento que se diferencian mediante los tres flags:
;    A)    Modo "Temporizador_OFF" o estado inicial. A él se pasa en el estado inicial cada vez
;        que termina una temporización o cuando se aborta la temporización sin esperar a que
;        finalice. Reconocido por el flag F_Temporizador_OFF, bit 0 del registro FlagsModos.
;         una temporización  o cada vez que se aborta la temporización sin esperar a que finalice.
;    B)    Modo "Temporizador_Ajuste", donde se ajusta la temporización deseada cuando funcione
;        como temporizador. Reconocido por el flag F_Temporizador_Ajuste, bit 1 del FlagsModos.
;    C)    Modo "Temporizador_ON", la salida está activada mientras dure la temporización.
;        Reconocido por el flag F_Temporización_ON, que es el bit 2 del registro FlagsModos.
;
; El programa consigue que esté activado uno sólo de los flags anteriores.

; El contenido del registro (FlagsModos) diferencia los siguientes modos de funcionamiento:
; - (FlagsModos)=b'00000001'. Está en el modo "Temporizador_OFF", en reposo.
; - (FlagsModos)=b'00000010'. Está en el modo "Temporizador_Ajuste", ajustando tiempo deseado.
; - (FlagsModos)=b'00000100'. Está en el modo "Temporizador_ON", activa la carga y temporizador.
;
; Al pulsar "AJUSTE" pueden darse tres casos:
; - Si estaba en modo "Temporizador_OFF", pasa a modo "Temporizador_Ajuste".
; - Si estaba en modo "Temporizador_Ajuste", pasa a modo "Temporizador_OFF", pero antes salva
;   el tiempo de temporización deseado en la EEPROM de datos.      
; - Si estaba en modo "Temporizador_ON", pasa a modo "Temporizador_OFF". (Interrumpe la
;   temporización).

CambiarModo
    call    PitidoCorto                    ; Cada vez que pulsa origina un pitido.
    btfsc    AjustePulsador                ; Si es un rebote sale fuera.
    goto    EsperaDejePulsar
    btfsc    F_Temporizador_OFF            ; ¿Está en reposo?
    goto    ModoTemporizador_Ajuste        ; Sí, pues pasa a ajustar la temporización.
    btfss    F_Temporizador_Ajuste        ; ¿Está ajustando?
    goto    ModoTemporizador_OFF        ; No, pues pasa a reposo.
                                        ; Sí, pues antes de pasar a reposo salva en la
    clrw                                ; posición 00h de memoria EEPROM de datos el tiempo
    movwf    EEADR                        ; de temporización deseado. Se conserva aunque se
    movf    TiempoDeseado,W                ; apague la alimentación.
    call    EEPROM_EscribeDato
ModoTemporizador_OFF
    bcf        SalidaTemporizador            ; Apaga la carga y resetea tiempo deseado.
    call    Pitido
    movlw    b'00000001'                ; Actualiza el registro FlagsModos pasando al
    movwf    FlagsModos                ; modo inicial "Temporizador_OFF".
    bcf        INTCON,T0IE                ; Prohíbe las interrupciones del TMR0.
    movf    TiempoDeseado,W            ; Repone otra vez el tiempo que se desea para la
    movwf    Tiempo                    ; próxima temporización.
    call    LCD_Borra                ; Borra la pantalla.
    movlw    Mensaje_OFF                ; En pantalla el mensaje correspondiente.
    goto    FinCambiarModo

ModoTemporizador_Ajuste
    bcf        SalidaTemporizador        ; Apaga la carga
    movlw    b'00000010'                ; Actualiza el registro FlagsModos pasando al
    movwf    FlagsModos                ; modo "Temporizador_Ajuste".
    clrf    Tiempo                    ; Resetea el tiempo.
    clrf    TiempoDeseado
    bcf        INTCON,T0IE                ; Prohíbe las interrupciones del TMR0.
    call    LCD_Borra
    movlw    Mensaje_Ajuste            ; En pantalla el mensaje correspondiente.
    goto    FinCambiarModo

ModoTemporizador_ON
    movf    TiempoDeseado,W            ; Si el tiempo deseado es cero pasa a modo
    btfsc    STATUS,Z                ; de trabajo "Temporizador_OFF".
    goto    ModoTemporizador_OFF
    movwf    Tiempo
    call    PitidoCorto
    movlw    b'00000100'                ; Actualiza el registro FlagsModos pasando al
    movwf    FlagsModos                ; modo "Temporizador_ON".
    movlw    TMR0_Carga50ms            ; Carga el TMR0.
    movwf    TMR0
    movlw    CARGA_1s                ; Y el registro cuyo decremento contará los
    movwf    Registro50ms            ; segundos.
    bsf        INTCON,T0IE                ; Autoriza las interrupciones de TMR0.
    call    LCD_Borra
    bsf        SalidaTemporizador        ; Enciende la carga.
    movlw    Mensaje_ON                ; En pantalla el mensaje correspondiente.
FinCambiarModo
    call    LCD_Mensaje
    call    VisualizaTiempo
EsperaDejePulsar
    btfss    AjustePulsador            ; Espera deje de pulsar.
    goto    EsperaDejePulsar
    return

; Subrutina "Temporizador" ----------------------------------------------------------------
;
; Esta subrutina va decrementando el tiempo de temporización y visualizándolo en la pantalla.
; Se ejecuta debido a la petición de interrupción del Timer 0 cada 50 ms exactos, comprobado
; experimentalmente con la ventana "Stopwatch" del simulador del MPLAB.

    CBLOCK
    Registro50ms                    ; Guarda los incrementos cada 50 ms.
    ENDC

TMR0_Carga50ms    EQU    d'256'-d'195'            ; Para conseguir la interrupción cada 50 ms.
CARGA_1s        EQU    d'20'            ; Leerá cada segundo (20 x 50ms = 1000 ms).   

Temporizador
    call    Retardo_50micros        ; Ajuste fino de 71 microsegundos para
    call    Retardo_20micros        ; ajustar a 50 milisegundos exactos.
    nop
      movlw    TMR0_Carga50ms            ; Carga el Timer0.
    movwf    TMR0
    decfsz    Registro50ms,F            ; Decrementa el contador.
    goto    FinTemporizador            ; No ha pasado 1 segundo y por tanto sale.
    movlw    CARGA_1s                ; Repone el contador nuevamente.
    movwf    Registro50ms
    btfss    F_Temporizador_ON        ; Si no está en modo "Temporizador_ON" sale
    goto    FinTemporizador            ; fuera.
    decfsz    Tiempo,F
    goto    VisualizaContador        ; Visualiza el tiempo restante.
    bcf        SalidaTemporizador        ; Apaga la salida
    call    VisualizaTiempo            ; Visualiza cero segundos en la pantalla.
    call    Pitido                    ; Tres pitidos indican final de la temporización.
    call    Retardo_500ms
    call    Pitido
    call    Retardo_500ms
    call    PitidoLargo
    call    Retardo_500ms
    call    ModoTemporizador_OFF    ; Acabó la temporización.
    goto    FinTemporizador
VisualizaContador
    call    VisualizaTiempo
FinTemporizador
    return

; Subrutina "VisualizaTiempo" -----------------------------------------------------------------
;
; Visualiza el registro Tiempo en formato "Minutos:Segundos". Así por ejemplo, si
; (Tiempo)=124 segundos en la segunda línea de la pantalla visualiza " 2:04", ya que 124
; segundos es igual a 2 minutos más 4 segundos.
;
VisualizaTiempo
    movlw    .5                        ; Para centrar visualización en la
    call    LCD_PosicionLinea2        ; segunda línea.
    movf    Tiempo,W                ; Convierte el tiempo deseado (y expresado sólo en
    call    MinutosSegundos            ; segundos) a minutos y segundos.
    movf    TemporizadorMinutos,W    ; Visualiza los minutos.
    call    BIN_a_BCD                ; Lo pasa a BCD.
    call    LCD_Byte
    movlw    ':'                        ; Visualiza dos puntos.
    call    LCD_Caracter
    movf    TemporizadorSegundos,W    ; Visualiza los segundos.
    call    BIN_a_BCD                ; Lo pasa a BCD.
    goto    LCD_ByteCompleto
    return

; Subrutina "MinutosSegundos" -----------------------------------------------------------
;
; Una cantidad expresada exclusivamente en segundos y contenida en el registro W es
; convertida a minutos y segundos. El resultado se guarda en dos posiciones de memoria
; llamadas TemporizadorMinutos y TemporizadorSegundos.
;
; El máximo número a convertir será el 255 que es el máximo valor que puede adquirir el
; número binario de entrada de 8 bits. (255 segundos = 4 minutos + 15 segundos)
;
; El procedimiento utilizado es mediante restas de 60 tal como se explica en el siguiente
; ejemplo que trata de la conversión del 124 segundos a minutos y segundos.
; 124 segundos = 2 minutos + 4 segundos.
;
; Minutos        Segundos     ¿(Segundos)<60?
; -------        --------    ------------------------------------------------
;     0              124        NO. Resta 60 a (Segundos) e incrementa (Minutos).
;     1               64         NO. Resta 60 e (Segundos) e incrementa (Minutos).
;     2                4        Sí, se acabó.
;
; Entrada:    En el registro W el número de segundos a convertir.
; Salidas:    En (TemporizadorMinutos) y (TemporizadorSegundos) el resultado.

    CBLOCK
    TemporizadorMinutos
    TemporizadorSegundos
    ENDC
;
MinutosSegundos
    movwf    TemporizadorSegundos    ; Carga el número de segundos a convertir.
    clrf    TemporizadorMinutos        ; Carga los registros con el resultado inicial.
Resta60
    movlw    .60                        ; Resta 60 en cada pasada.
    subwf    TemporizadorSegundos,W    ; (W)=(TemporizadorSegundos)-60.
    btfss    STATUS,C                ; ¿(W) positivo?, ¿(TemporizadorSegundos)>=60?.
    goto     FinMinutosSegundos        ; No, es menor de 60. Acabó.
    movwf    TemporizadorSegundos    ; Sí, por tanto, recupera lo que queda por restar.
    incf    TemporizadorMinutos,F    ; Incrementa los minutos.
    goto    Resta60                    ; Y vuelve a dar otra pasada.
FinMinutosSegundos
    return

; Subrutina "IncrementarTiempoDeseado" --------------------------------------------------
;
; Subrutina de atención a la interrupción por cambio de la línea RB6 a la cual se ha
; conectado el pulsador "INCREMENTAR".
; Estando en el modo "Temporizador_Ajustar" incrementa el valor del tiempo deseado
; expresado en segundos en intervalos de 5 segundos y hasta un máximo de 255 segundos.
;
SALTO_INCR    EQU    .5

IncrementarTiempoDeseado
    call    PitidoCorto                ; Cada vez que pulsa se oye un pitido.
    movlw    SALTO_INCR                ; Incrementa el tiempo deseado de temporización
    addwf    Tiempo,F                ; saltos de SALTO_INCR segundos.
    btfsc    STATUS,C                ; Si pasa del valor máximo lo inicializa.
    clrf    Tiempo
    call    VisualizaTiempo            ; Visualiza mientras espera que deje de pulsar.
    call    Retardo_200ms
    btfss    IncrementarPulsador        ; Mientras permanezca pulsado,
    goto    IncrementarTiempoDeseado ; incrementa el dígito.
    movf    Tiempo,W                ; Actualiza el tiempo deseado.
    movwf    TiempoDeseado            ; Este es el tiempo deseado.
    return
   
; Subrutinas "PitidoLargo", "Pitido" y "PitidoCorto" -------------------------------------
;
PitidoLargo
    bsf        Zumbador
    call    Retardo_500ms
Pitido
    bsf        Zumbador
    call    Retardo_200ms
PitidoCorto
    bsf        Zumbador
    call    Retardo_20ms
    bcf        Zumbador
    return
;
    INCLUDE  <RETARDOS.INC>
    INCLUDE  <BIN_BCD.INC>
    INCLUDE  <LCD_4BIT.INC>
    INCLUDE  <LCD_MENS.INC>
    INCLUDE  <EEPROM.INC>
    END
Un cordial saludo.
08/09/2010 #2


Respuesta: Temporizador para insoladora
con cualquier temporizador se puede lograr cualquier tiempo, es decir, para una frecuencia de 4 MHz, con un temporizador de 8 bits, y un preescalar de 1:256 necesitarias que el temporizador desbordara 91552 veces, con un oscilador de 1MHz necesitarias que desbordara 22888 veces, eso para 5 minutos. con mas bits, 16 en tu caso, lo que consigues es redcir el numero de desbordes (interrupciones) que has de esperar, de hecho con 16 bits,m para 5 minutos con el mismo preescalar los desbordes del temporizador que te hacen falta son 357, bastantes menos pero solo es cuestion de esperar mas o menos desbordes del temporizador.
de todas formas yo no haria que temporizara el temporizador todo el tiempo, por ejemplo yo haria un temporizador de 30s, y a partir de ahi contaria, o incluso un temporizador de un segundo, para asi en cada desborde puedes descontar uno en el lcd.

un saludo
08/09/2010 #3

Avatar de Meta

Respuesta: Temporizador para insoladora
Buenas:

¿Sabes el método para que se vea 99:99 y pueda escoger el tiempo deseado? En los botones del PIC puede elegir el tiempo deseado, sólo marca 4:15. Al menos quiero uno de 30:00 aunque sea. En realidad para insolar placas son mucho menos minutos dependiendo el tipo de luz a radiar, la altura y el tipo de PCB.

Quiero hacerlo funcionar, cuando lo consiga ya puedo fabricar el circuito impreso. Les mostraré como un manual. He encontrado este ejemplo pero no entiendo ni papa.

Código:
; Este programa lo único que hace es contar desde 20 minutos hasta 0,
; es decir, no puede ajustarse, a menos que se edite el programa.
 
	LIST	P=16F84A
	INCLUDE "P16F84A.INC"
 
	CBLOCK	0CH
		Reg_50ms, Tiempo_H, Tiempo_L
	ENDC
 
; Ojo: En vez de usar una variable llamada TIEMPO debes usar dos:
  ; - Una para almacenar el byte alto de la cantidad de segundos,
;	llamada Tiempo_H.
; - Una para almacenar el byte bajo de la cantidad de segundos,
;	llamada Tiempo_L.
;
; ¿Por qué 2 bytes? Pues porque para temporizar hasta 20 minutos se
; requieren hasta 20 x 60 = 1200 segundos. La cantidad 1200 se representa
; con mínimo 2 bytes.
 
	#DEFINE	Alarma		PORTB,0
 
	ORG 00H
	goto	Inicio
 
	ORG 04H
	goto	Interrupcion
 
Inicio
	bcf		Alarma
	bsf		STATUS,RP0
	movlw	b'11000111'
	movwf	OPTION_REG
	bcf		Alarma
	bcf		STATUS,RP0
 
	call	LCD_Inicializa
	movlw	high(.1200) ; Carga el byte alto del tiempo en la variable
	movwf	Tiempo_H	; Tiempo_H.
	movlw	low(.1200) ; Carga el byte bajo del tiempo en la variable
	movwf	Tiempo_L	; Tiempo_L.
	call	Visualiza_Tiempo	; Visualiza el tiempo en la pantalla.
 
	movlw	.20 ; Se prepara para temporizar.
	movwf	Reg_50ms
	movlw	.60
	movwf	TMR0
	bcf		INTCON,T0IF
	bsf		INTCON,T0IE
	bsf		INTCON,GIE		; Habilita interrupciones.
 
Ciclo
	goto	Ciclo
 
; Rutina de servicio a la interrupción.
Interrupcion
	movlw	.60
	movwf	TMR0	; Recarga el TMR0.
	decfsz	Reg_50ms	; ¿Ya pasó 1 segundo?
	goto	Fin_Interrupcion
 
	movlw	.20 ; Sí, entonces recarga el registro.
	movwf	Reg_50ms
 
; Ojo: Aquí se va a realizar el decremento del tiempo, pero
; es un decremento de 16 bits.
	decf	Tiempo_L,F	; Decrementa en 1 el byte bajo.
	movlw	0xFF
	subwf	Tiempo_L,W	
	btfsc	STATUS,Z	; ¿El resultado es negativo?
	decf	Tiempo_H,F	; Sí, entonces decrementa en 1 el byte alto.
 
	call	Visualiza_Tiempo	; Visualiza el tiempo en la pantalla.
 
; Atención: Anteriormente sólo decrementamos el tiempo, pero NO
; verificamos si llegó al valor 0. Aquí se realiza esto. Si los
; dos bytes del tiempo valen 0 significa que el tiempo terminó.
	movf	Tiempo_H,F
	btfss	STATUS,Z	; ¿Vale 0 el byte alto?
	goto	Fin_Interrupcion	; No, pues sale de la interrupción.
	movf	Tiempo_L,F
	btfss	STATUS,Z	; ¿Vale 0 el byte bajo?
	goto	Fin_Interrupcion	; No, pues sale de la interrupción.
 
; Llegamos aquí porque los dos bytes valen 0, es decir, el tiempo terminó.
	bsf		Alarma		; Activa la alarma
	call	Retardo_2s	; durante un corto tiempo.
	bcf		Alarma
 
	bcf		INTCON,T0IE	; Prohibe la interrupción del TMR0
						; Para que detener el conteo.
 
Fin_Interrupcion
	bcf		INTCON,T0IF	; Borra la bandera de interrupción
	retfie				; y retorna.
 
; Subrutina Visualiza_Tiempo.
;
; Observa que antes sólo se hacía:
;
;	movf	TIEMPO,W
;	call	MinutosSegundos
;
; Pues ahora el tiempo es de dos bytes y debe hacerse como sigue.
Visualiza_Tiempo
	call	LCD_Borra
; Debes hacerlo así para que funcione. La rutina MinutosSegundos
; modificada maneja los registros MinutosSegundos_TiempoH y
; MinutosSegundos_TiempoL.
	movf	Tiempo_H,W
	movwf	MinutosSegundos_TiempoH
	movf	Tiempo_L,W
	movwf	MinutosSegundos_TiempoL
	call 	MinutosSegundos ; Convierte de segundos a minutos y
							; segundos.
	movf	Minutos,W
	call	BIN_BCD
	call	LCD_ByteCompleto
	movlw	':'
	call	LCD_Caracter
	movf	Segundos,W
	call	BIN_BCD
	call	LCD_ByteCompleto
	return
 
; La rutina BIN_BCD yo la hice, pero puedes usar la que tú tienes.
; Lo que pasa es que la hice porque no la tengo.
; Insisto, puedes usar la que tú tienes.
BIN_BCD
	CBLOCK
		Unidades, Decenas, Centenas
	ENDC
 
	movwf	Unidades
	clrf	Decenas
	clrf	Centenas
BIN_BCD_Resta10
	movlw	.10
	subwf	Unidades,F
	btfss	STATUS,C
	goto	Fin_BIN_BCD
 
	incf	Decenas,F
	movlw	.10
	subwf	Decenas,W
	btfss	STATUS,C
	goto	BIN_BCD_Resta10
 
	clrf	Decenas
	incf	Centenas,F
	goto	BIN_BCD_Resta10
 
Fin_BIN_BCD
	movlw	.10
	addwf	Unidades,F
	movf	Unidades,W
	swapf	Decenas,F
	iorwf	Decenas,W
	swapf	Decenas,F
	return
 
; Aquí está la subrutina MinutosSegundos modificada para manejar
; números de 2 bytes. Ésta sí úsala en lugar de la otra.
MinutosSegundos
	CBLOCK
		Segundos, Minutos
		MinutosSegundos_TiempoH
		MinutosSegundos_TiempoL
	ENDC
 
	clrf	Minutos		; Borra los minutos.
; Le resta 60 al tiempo que está almacenado en las variables
; MinutosSegundos_TiempoH y MinutosSegundos_TiempoL.
MinutosSegundos_Resta60
	movlw	.60
	subwf	MinutosSegundos_TiempoL,F	; Resta 60 del byte bajo.
	btfss	STATUS,C ; ¿Es negativo?
	decf	MinutosSegundos_TiempoH,F	; Sí, entonces decrementa en
										; 1 el byte alto.
	btfsc	MinutosSegundos_TiempoH,7 ; ¿El resultado es negativo?
	goto	Fin_MinutosSegundos		; Sí, pues ya terminamos de convertir.
 
	incf	Minutos,F		; Incrementa en 1 la cantidad de minutos.
	goto	MinutosSegundos_Resta60	; Sigue revisando si hay más minutos.
 
Fin_MinutosSegundos
	movlw	.60 ; Le suma 60 a la cantidad de tiempo ya que 
					; previamente se le restó 60 y el resultado
					; fue negativo.
	addwf	MinutosSegundos_TiempoL,W
	movwf	Segundos
	return
 
	INCLUDE "LCD_4BIT.INC"
	INCLUDE "RETARDOS.INC"
 
	END
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.