Download - TMR0 Y RB0_INT
DISEÑE UN SISTEMA D
(PROCESO PRINCIPAL Y PROCESOS PARALELOS O SECUNDARIOS)
El Sistema funcionará de la siguiente manera:
1. Al presionarse “MARCHA”, el motor de la cinta transportadora (MC) se activa, hasta que el
sensor detector de lata (DLATA) se active.
2. El motor de la cinta transportadora se apaga, se abre la válvula de llenado (VLL)
el sensor de llenado (SLL) se activa, procediendo a cerrar la válvula de llenado.
3. Se activa la cinta transportadora (MC), hasta que el sensor detector de lata (DLATA) se
active, luego se repite el punto 2 y el 3 de manera continua.
4. Si han pasado 5 segundos sin que se detecte una lata, el sistema se detiene
automáticamente, apagando todos los actuadores y se va al paso 1, a la espera que se
presione “MARCHA”, además de activar un led de
5. Si han pasado 5 segundos sin que se llene la lata, el sistema se detiene automáticamente
cerrando la válvula de llenado (VLL) y se va a paso 1, a la espera que se presione
“MARCHA”, además de activar un led de alarma (ALARMA).
El sistema tiene los siguientes procesos adicionales:
a. Se monitorea cada 50 ms:
DISEÑE UN SISTEMA DE LLENADO Y ENVASADO AUTOMÁTICO
(PROCESO PRINCIPAL Y PROCESOS PARALELOS O SECUNDARIOS)
El Sistema funcionará de la siguiente manera:
Al presionarse “MARCHA”, el motor de la cinta transportadora (MC) se activa, hasta que el
sensor detector de lata (DLATA) se active.
transportadora se apaga, se abre la válvula de llenado (VLL)
el sensor de llenado (SLL) se activa, procediendo a cerrar la válvula de llenado.
Se activa la cinta transportadora (MC), hasta que el sensor detector de lata (DLATA) se
se repite el punto 2 y el 3 de manera continua.
Si han pasado 5 segundos sin que se detecte una lata, el sistema se detiene
automáticamente, apagando todos los actuadores y se va al paso 1, a la espera que se
presione “MARCHA”, además de activar un led de alarma (ALARMA).
Si han pasado 5 segundos sin que se llene la lata, el sistema se detiene automáticamente
cerrando la válvula de llenado (VLL) y se va a paso 1, a la espera que se presione
“MARCHA”, además de activar un led de alarma (ALARMA).
tiene los siguientes procesos adicionales:
Se monitorea cada 50 ms:
E LLENADO Y ENVASADO AUTOMÁTICO
(PROCESO PRINCIPAL Y PROCESOS PARALELOS O SECUNDARIOS)
Al presionarse “MARCHA”, el motor de la cinta transportadora (MC) se activa, hasta que el
transportadora se apaga, se abre la válvula de llenado (VLL), hasta que
el sensor de llenado (SLL) se activa, procediendo a cerrar la válvula de llenado.
Se activa la cinta transportadora (MC), hasta que el sensor detector de lata (DLATA) se
Si han pasado 5 segundos sin que se detecte una lata, el sistema se detiene
automáticamente, apagando todos los actuadores y se va al paso 1, a la espera que se
Si han pasado 5 segundos sin que se llene la lata, el sistema se detiene automáticamente
cerrando la válvula de llenado (VLL) y se va a paso 1, a la espera que se presione
a.1. El nivel del tanque (T1), si el nivel esta en mínimo (NMIN) se activa la bomba 1 (B1)
hasta que se llegue al nivel máximo (NMAX), desactivándose la bomba 1 (B1).
a.2. El peso en el pistón de envasado con el sensor de peso (SPESO), si se ha activado, el
pistón se activa bajando, se activa el pistón empujador a los 3 segundos, y luego de de 3
segundos más, se desactivan el pistón empujador y desactivándose el pistón de envasado,
subiendo para recibir más latas de pintura.
Nota: Cuando se activa la secuencia de los pistones, se debe completar para no dañar el
funcionamiento de los mismos. Por seguridad, B1=VLL=MC= se desactivan y al finalizar la
secuencia, se deben dejar como estaban antes de entrar en esta secuencia y se debe
continuar con el proceso exactamente desde donde se detuvo para no afectar el normal
funcionamiento del sistema.
b. Si se presiona el botón “PARADA”, el sistema se detiene en su totalidad, es decir,
B1=VLL=MC= Desactivados, y se activa un led que indica que el proceso se encuentra
detenido (LED PARADA). Si se desea reactivar el proceso, se debe pulsar nuevamente el
botón “PARADA” y se debe continuar con el proceso exactamente desde donde se detuvo
para no afectar el normal funcionamiento del sistema.
c. Adicionalmente se llevará la cuenta de las latas que se han llenado y la cantidad de
envasados que se han realizado.
Tabla de asignación de Pines de entrada y salida:
ENTRADA ¿Qué pinAsignamos?
SALIDA ¿Qué pinAsignamos?
MARCHA RA0 Bomba B1 RB3Sensor Máximo (SMAX) RA1 Válvula llenado (VLL) RB1Sensor Mínimo (SMIN) RA2 Motor cinta
transportadora (MC)RB2
PARADA RB0/INT LED PARADA RB6Detector lata (DLATA) RA3 Pistón Envasado RB4Sensor llenado (SLL) RA4 Pistón empujador RB5Sensor de peso (SPESO) RA5 LED ALARMA RB7
DECODIFICADOR PORTCDISPLAY UNILATA RD0DISPLAY DECLATA RD1DISPLAY ENVASADO RD2
Conceptos teóricos a ser tomados en cuenta para las condiciones de trabajo
Puntos 1, 2 y 3. Automatizaciones sencillas, es decir, se presiona “MARCHA” y se
monitorean dos sensores (DLATA y SLLENO) para la activación y desactivación del motor de la cinta
transportadora (MC).
Para el punto 4 y 5, se considerará el “cerrojo automático”, que debe reiniciar el sistema si
han transcurrido 5 segundos sin detectar una lata, activando un led de alarma y enviando el
programa a esperar por presionarse “MARCHA” nuevamente. En el caso de que la lata se esté
llenando y transcurran 5 segundos sin que ésta se llene, se debe cerrar la válvula de llenado,
activando el led de alarma y va a esperar que se presione “MARCHA”.
Para el punto a, se debe configurar al TMR0 para que se desborde cada 50 ms y genere
una interrupción que irá a supervisar las condiciones a.1 y a.2, mediante la exploración simple de
los sensores correspondientes (NMAX y NMIN para a.1 actuando sobre la Bomba 1 y SPESO para
actuar sobre los pistones de envasado y empujador).
En el punto a.1 se deberían realizar los cálculos (ya se hicieron en la guía rápida del TMR0
e Interrupciones), por lo que nos ahorraremos este paso. a saber=
Temporización= 4 * 250 ns * (256 – 61 ) * 256 = 49.92 ms ≈ 50 ms, por lo que se carga en el TMR0
el número 61 y en el OPTION_REG=256
En el punto a.2 se utiliza una rutina simple generada por el PicDel de 3 segundos o llamar
una rutina de 1 segundo tres veces, como usted prefiera.
Para el punto b, se debe configurar una interrupción por cambio de nivel del pin RB0/INT
para que detenga todo el sistema, al ser una parada de emergencia de todo el proceso. El uso de
esta interrupción debe estar asociado a la rutina de “salvar el entorno” para que cuando se salga
de dicha rutina, el sistema siga trabajando exactamente como lo estaba haciendo al momento de
producirse la interrupción.
Los puntos a y b, estarán en la misma rutina de servicio de interrupción (RSI), y para
determinar cuál tarea se hará, se deben explorar los señalizadores de interrupciones (TOIF y INTF).
Cabe destacar que si la causa de la interrupción es la RB0/INT, se debe desactivar el permiso de
interrupción por desborde del TMR0 (TOIE=0) hasta que no se salga de la rutina de parada de
emergencia.
Para el punto c, se utilizarán las estructuras de contadores clásicos de 00 a 99 para las latas
y de 0 a 9 para la cantidad de envasados realizados. El contador de latas se incrementará cada vez
que se detecte que una lata se ha llenado totalmente y el contador de envasado se incrementará
cuando se termine la secuencia de manejo de los pistones que se ejecuta durante la interrupción
de desborde del TMR0 por activación del sensor de peso.
Los diagramas de flujo se dividirán en “PROGRAMA PRINCIPAL” y “RSI”, se dejarán
expresados los de retardos generados por el PicDel.
Teniendo en cuenta estos puntos teóricos, veamos los diagramas del flujo del sistema que
se pretende diseñar:
Programa Principal
Rutina de servicio de interrupción (Parte 1)
RSI
Salvar entorno
¿RB0/INT=0?
SI
NO
DeshabilitarInterrupciones
¿INTF=1?
SI
NOTESTEO
Restaurar entorno
SALIR
Habilitar InterrupcionesINTE=1 TOIE=1
INTF=0 TOIF=0
retfie
LED PARADA OFF
MCINTA=OFFVLL=OFFB1=OFF
PENVASADO=OFFPEMPUJADOR=OFF
LED PARADA=ONLED ALARMA=OFF
INTE=0TOIE=0
¿TOIF=1?
NO
SI
SALIR
¿La causa es porRB0/INT?
¿La causa es pordesborde del
TMR0?
Rutina de servicio de interrupción (Parte 2)
Y después de tener un buen diagrama de flujo, lo demás es carpintería:
Lenguaje ensamblador:
;********************************************************************************
;**********EJEMPLO DE MANEJO DE INTERRUPCIONES POR DESBORDE DE TMR0 Y************
;*********************CAMBIO DE NIVEL EN PIN RB0/INT*****************************
;************DURANTE EL DESBORDE DEL TMR0 (50mS), CONTROLA EL LLENADO************
;****************DEL TANQUE 1 Y EL PESO EN EL PISTÓN DE ENVASADO*****************
;*************************PROF. LUIS ZURITA. 14/04/13****************************
;*********ADICIONAL A ESTO SE MUESTRA EL NÚMERO DE LATAS LLENADAS****************
;****************Y LA CANTIDAD DE ENVASADOS REALIZADOS***************************
LIST P=16F877A
INCLUDE P16F877A.INC
;************ZONA DE DECLARACIONES DE REGISTROS*******************
CONTACERR EQU 20H ;REGISTRO PARA CERROJO AUTOMÁTICO
PDel0 EQU 21H ;REGISTRO PARA DELAY05S
PDel1 EQU 22H ;REGISTRO PARA DELAY05S
PDel00 EQU 23H ;REGISTRO PARA DELAY5mS
PDel11 EQU 24H ;REGISTRO PARA DELAY5mS
W_TEMP EQU 25H ;REGISTRO PARA SALVAR A W
STATUS_TEMP EQU 26H ;REGISTRO PARA SALVAR A STATUS
PORTB_TEMP EQU 27H ;REGISTRO PARA SALVAR A PORTB
PORTC_TEMP EQU 28H ;REGISTRO PARA SALVAR A PORTC
PORTD_TEMP EQU 29H ;REGISTRO PARA SALVAR A PORTD
CONTASEG EQU 2AH ;REGISTRO PARA DELAY 3 SEGUNDOS
UNI EQU 2BH
DEC EQU 2CH
UNIEN EQU 2DH
UNI_TEMP EQU 2EH
DEC_TEMP EQU 2FH
UNIEN_TEMP EQU 30H
;*******************ZONA DE VECTORES******************************
ORG 00H
GOTO INICIO ;VECTOR DE PROGRAMA PRINCIPAL
ORG 04H
GOTO RSI ;VECTOR DE RUTINA DE INTERRUPCIÓN
;******************************************************************
;*******************RUTINA DE INTERRUPCIÓN*************************
;******************************************************************
RSI BCF INTCON,7 ;GIE=0, ATIENDE UNA INTERRUPCIÓN
BTFSS INTCON,1 ;INTF=1? CAUSADA POR RB0/INT?
GOTO INTMR0 ;NO. EXPLORAR SI ES DESBORDE DE TMR0
;********REALIZA LA PARADA DE EMERGENCIA (PUNTO b DEL EJEMPLO)**********
CALL PUSH ;SI. VA A SALVAR ENTORNO
CALL DELAY05S ;ANTIREBOTE PARA RB0/INT
REINICIAR BTFSC PORTB,0 ;SE PRESIONO RB0 PARA REINICIAR?
GOTO REINICIAR ;NO. ESPERA
AQUI CALL DELAY15MS ;SI. COLOCAMOS ANTIREBOTE
BTFSS PORTB,0 ;PARA EVITAR FALSOS DISPAROS
GOTO AQUI ;ESPERA A QUE SE PRESIONE RB0
CALL POP ;RESTAURA EL ENTORNO
;**********ESTO SE HACE ANTES DE SALIR DE LA INTERRUPCIÓN***************
SALIR BSF INTCON,7 ;GIE=1
BCF INTCON,1 ;SE BORRAN SEÑALIZADORES INTF=0
;Y TOIF PARA EVITAR FALSOS DISPAROS
BCF INTCON,2
BSF INTCON,4 ;SE ACTIVA INTE=1
BSF INTCON,5 ;SE ACTIVA TOIE=1
RETFIE ;SALE DE LA INTERRUPCIÓN
;**EXPLORA SI LA CAUSA DE LA INTERRUPCIÓN HA SIDO POR DESBORDE DEL TMR0**
INTMR0 BTFSS INTCON,2 ;INTF=1? CAUSADA POR DESBORDE DE TMR0?
GOTO SALIR ;NO. SALE DE INTERRUPCIÓN
;*******************************************************************************
;******SI ES POR DESBORDE DEL TMR0, MONITOREA EL CONTROL DE NIVEL DE TANQUE1******
;**************************** (PUNTO a.1 DEL EJEMPLO)*****************************
TESTEO BCF INTCON,5 ;SI. TOIE=0.
BTFSC PORTA,2 ;SI. NIVEL MÍNIMO DE TANQUE1?
GOTO NMAXIMO ;NO. TESTEAR NIVEL MÁXIMO DE TANQUE1
BSF PORTB,3 ;SI. ACTIVA BOMBA1
GOTO CARGA ;VA A PREGUNTAR POR PESO DE PISTON
NMAXIMO BTFSC PORTA,1 ;NIVEL MÁXIMO DE TANQUE 1?
GOTO CARGA ;NO. TESTEAR CARGA EN PISTON DE EMPAQUETAR
BCF PORTB,3 ;SI. DESACTIVA BOMBA1
GOTO CARGA ;VA A PREGUNTAR POR PESO DE PISTON
;********************************************************************************
;*************LUEGO DE CONTROLAR EL NIVEL DEL TANQUE 1, VA A EXPLORAR**************
;***********************EL PESO EN PISTON DE ENVASADO****************************
;**************************** (PUNTO a.2 DEL EJEMPLO)*****************************
CARGA BTFSC PORTA,5 ;PESO COMPLETO EN PISTON DE EMPAQUETAR?
GOTO CARGARTMR0 ;NO. VA A CARGAR TMR0 ANTES DE SALIR
CALL PUSH ;VA A SALVAR ENTORNO
BSF PORTB,4 ;SI. ACTIVA SECUENCIA DE EMPAQUETAR
CALL DELAY3S ;ESPERA 3 SEGUNDOS MIENTRAS BAJA PISTON1
BSF PORTB,5 ;ACTIVA PISTON DE EMPUJE
CALL DELAY3S ;ESPERA 3 SEGUNDS MIENTRAS SE
;EMPUJAN LAS LATAS
BCF PORTB,5 ;RETORNA PISTON DE EMPUJE
CALL DELAY3S ;ESPERA 3 SEGUNDOS
BCF PORTB,4 ;RETORNA PISTON DE EMPAQUETAR Y VA
;A CARGAR TMR0
CALL CONTAENV
CALL POP ;VA A RESTAURAR ENTORNO
CARGARTMR0 MOVLW .61 ;CARGA VALOR DE TMR0 PARA NUEVA
MOVWF TMR0 ;TEMPORIZACIÓN DE 50mS
GOTO SALIR ;SALE DE INTERRUPCIÓN
;***********************************************************************
;*********FIN DE RUTINA DE INTERRUPCIÓN POR DESBORDE DEL TMR0***********
;***********************************************************************
;***********************************************************************
;***************************PROGRAMA PRINCIPAL**************************
;************************ZONA DE CONFIGURACIONES************************
;***********************************************************************
INICIO BCF STATUS,6 ;SELECCIONAMOS
BSF STATUS,5 ;EL BANCO 1
MOVLW B'00000110' ;CONFIGURAMOS PORTA COMO ENTRADA
MOVWF ADCON1 ;O SALIDA DIGITAL
MOVLW 0FFH
MOVWF TRISA ;CONFIGURAMOS PORTA COMO ENTRADA
MOVLW B'00000001' ;CONFIGURAMOS PORTB
MOVWF TRISB ;(RB0=ENTRADA, RESTO SALIDA)
CLRF TRISC
CLRF TRISD
MOVLW B'00000111' ;CONFIGURAMOS TMR0 COMO TEMPORIZADOR
MOVWF OPTION_REG ;CON PRESCALER DE 256
MOVLW B'10000000' ;HABILITAMOS LA INTERRUPCIÓN GLOBAL
MOVWF INTCON ;GIE=1
BCF STATUS,5 ;REGRESAMOS AL BANCO 0
CLRF UNI
CLRF DEC
CLRF UNIEN
CLRF PORTB ;TODOS LOS ACTUADORES DESACTIVADOS
CLRF PORTD
MARCHA CALL MOSTRAR
BCF PORTB,2 ;MCINTA OFF
BTFSC PORTA,0 ;MARCHA?
GOTO MARCHA ;NO. ESPERAMOS A QUE SE PRESIONE
BCF PORTB,7 ;LED ALARMA OFF
BSF PORTB,2 ;MCINTA ON
CLRF CONTACERR ;CONTACERR=0
CICLO BTFSC PORTA,3 ;DLATA?
GOTO CERROJO ;NO. VA A CERROJO AUTOMÁTICO
GOTO SIGUEPRO ;SI. VA A INICIAR PROCESO
CERROJO MOVF CONTACERR,0
SUBLW .200
BTFSS STATUS,2 ;CONTACERR=200?
GOTO SUBECERR ;NO. INCREMENTA CONTACERR
BSF PORTB,7 ;SI. HA PASADO 3 SEGUNDOS.LED ALARMA ON
MOVLW .61 ;CARGA VALOR DE TMR0 PARA
MOVWF TMR0 ;TEMPORIZACIÓN DE 50mS
BCF INTCON,5 ;TOIE=0
BCF INTCON,4 ;INTE=0
GOTO MARCHA ;VA A ESPERAR QUE SE PRESIONE MARCHA
SUBECERR INCF CONTACERR,1 ;CONTACERR=CONTACERR+1
CALL MOSTRAR ;DELAY15MS ;15mS*200= 3 SEGUNDOS
CALL MOSTRAR
GOTO CICLO ;ESPERAMOS A QUE SE DETECTE LATA
SIGUEPRO CLRF CONTACERR ;AL DETECTARSE LATA SIGUE EL PROCESO
BCF PORTB,2 ;MCINTA OFF
BSF PORTB,1 ;VLL ON
BSF INTCON,5 ;TOIE=1
BSF INTCON,4 ;INTE=1
;***
SLLENO BTFSC PORTA,4 ;SLL=0? SE LLENO LA LATA?
GOTO CERROJO2 ;NO. VA A CERROJO AUTOMÁTICO
BCF PORTB,1 ;VLLENADO OFF
BSF PORTB,2 ;MCINTA ON
CALL CONTADOR ;INCREMENTA NRO DE LATAS LLENADAS
GOTO CICLO ;VA A REPETIR PROCESO NUEVAMENTE
CERROJO2 MOVF CONTACERR,0
SUBLW .200
BTFSS STATUS,2 ;CONTACERR=200?
GOTO SUBECERR2 ;NO. INCREMENTA CONTACERR
BSF PORTB,7 ;SI. HA PASADO 3 SEGUNDOS.LED ALARMA ON
BCF PORTB,1 ;VLL OFF
BCF INTCON,5 ;TOIE=0
BCF INTCON,4 ;INTE=0
GOTO MARCHA ;VA A ESPERAR QUE SE PRESIONE MARCHA
SUBECERR2 INCF CONTACERR,1 ;CONTACERR=CONTACERR+1
CALL MOSTRAR ;DELAY15MS ;15mS*200= 3 SEGUNDOS
GOTO SLLENO ;ESPERAMOS A QUE SE LLENE LATA
;***
;**********************************************************************
;**************************RUTINA DE 15mS******************************
;**********************************************************************
DELAY15MS CLRF CONTASEG
ESPERA3 CALL DELAY5MS
MOVF CONTASEG,0
SUBLW .3
BTFSS STATUS,2
GOTO SUBESEG3
RETURN
SUBESEG3 INCF CONTASEG,1
GOTO ESPERA3
;**********************************************************************
;************************RUTINA DE 3SEGUNDOS***************************
;**********************************************************************
DELAY3S CLRF CONTASEG
ESPERA6 CALL DELAY05S
MOVF CONTASEG,0
SUBLW .6
BTFSS STATUS,2
GOTO SUBESEG
RETURN
SUBESEG INCF CONTASEG,1
GOTO ESPERA6
;**********************************************************************
;********RUTINA PARA SALVAR EL ENTORNO DURANTE INTERRUPCIÓN************
;**********************************************************************
PUSH BCF INTCON,5 ;TOIE=0.
BCF INTCON,4 ;INTE=0.
MOVWF W_TEMP
MOVF STATUS,0
MOVWF STATUS_TEMP
MOVF PORTB,0
MOVWF PORTB_TEMP
MOVF PORTC,0
MOVWF PORTC_TEMP
MOVF PORTD,0
MOVWF PORTD_TEMP
MOVF UNI,0
MOVWF UNI_TEMP
MOVF DEC,0
MOVWF DEC_TEMP
APAGADO CLRF PORTD ;DISPLAYS OFF
BCF PORTB,1 ;VLL OFF
BCF PORTB,2 ;MCINTA OFF
BCF PORTB,3 ;B1 OFF
BCF PORTB,4 ;PENVASADO OFF
BCF PORTB,5 ;PEMPUJADOR OFF
BSF PORTB,6 ;LED PARADA ON
BCF PORTB,7 ;LED ALARMA OFF
RETURN
;**********************************************************************
;*******RUTINA PARA RESTAURAR EL ENTORNO DURANTE INTERRUPCIÓN**********
;**********************************************************************
POP MOVF UNI_TEMP,0
MOVWF UNI
MOVF DEC_TEMP,0
MOVWF DEC
MOVF PORTB_TEMP,0
MOVWF PORTB
MOVF PORTC_TEMP,0
MOVWF PORTC
MOVF PORTD_TEMP,0
MOVWF PORTD
MOVF STATUS_TEMP,0
MOVWF STATUS
MOVF W_TEMP,0
RETURN
;**********************************************************************
;***************************RUTINA DE 5mS******************************
;**********************GENERADA POR EL PICDEL**************************
DELAY5MS movlw .6 ; 1 set numero de repeticion (B)
movwf PDel00 ; 1 |
PLoop11 movlw .207 ; 1 set numero de repeticion (A)
movwf PDel11 ; 1 |
PLoop22 clrwdt ; 1 clear watchdog
decfsz PDel11, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop22 ; 2 no, loop
decfsz PDel00, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop11 ; 2 no, loop
PDelL11 goto PDelL22 ; 2 ciclos delay
PDelL22 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
;**********************************************************************
;***************************RUTINA DE 0.5S*****************************
;**********************GENERADA POR EL PICDEL**************************
DELAY05S movlw .239 ; 1 set numero de repeticion (B)
movwf PDel0 ; 1 |
PLoop1 movlw .232 ; 1 set numero de repeticion (A)
movwf PDel1 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 goto PDelL3 ; 2 ciclos delay
PDelL3 clrwdt ; 1 ciclo delay
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
PDelL4 goto PDelL5 ; 2 ciclos delay
PDelL5 goto PDelL6 ; 2 ciclos delay
PDelL6 goto PDelL7 ; 2 ciclos delay
PDelL7 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
;****************************
;CONTADOR CLÁSICO DE 00 A 99
;****************************
CONTADOR MOVF UNI,0 ;UNI A W
SUBLW .9
BTFSS STATUS,2 ;Z=1? UNI=9?
GOTO SUBEUNI
GOTO DECENA
SUBEUNI INCF UNI,1 ;UNI=UNI+1
RETURN
DECENA CLRF UNI
MOVF DEC,0 ;DEC A W
SUBLW .9
BTFSS STATUS,2 ;Z=1? DEC=9?
GOTO SUBEDEC
CLRF DEC
CLRF UNI
RETURN
SUBEDEC INCF DEC,1 ;DEC=DEC+1
RETURN
;****************************
;CONTADOR CLÁSICO DE 0 A 9
;****************************
CONTAENV MOVF UNIEN,0 ;UNI A W
SUBLW .9
BTFSS STATUS,2 ;Z=1? UNI=9?
GOTO SUBEUNIEN
CLRF UNIEN
RETURN
SUBEUNIEN INCF UNIEN,1 ;UNI=UNI+1
RETURN
;**************************************************
;RUTINA MOSTRAR
;**************************************************
MOSTRAR BCF PORTD,2 ;DISPLAY UNIEN OFF
BCF PORTD,1 ;DISPLAY DEC OFF
BSF PORTD,0 ;DISPLAY UNI ON
MOVF UNI,0 ;UNI A W
MOVWF PORTC ;UNI ES SACADO HACIA PORTC
CALL DELAY5MS
BCF PORTD,2 ;DISPLAY UNIEN OFF
BSF PORTD,1 ;DISPLAY DEC ON
BCF PORTD,0 ;DISPLAY UNI OFF
MOVF DEC,0 ;DEC A W
MOVWF PORTC ;DEC ES SACADO HACIA PORTC
CALL DELAY5MS
BSF PORTD,2 ;DISPLAY UNIEN ON
BCF PORTD,1 ;DISPLAY DEC OFF
BCF PORTD,0 ;DISPLAY UNI OFF
MOVF UNIEN,0 ;UNIEN A W
MOVWF PORTC ;UNIEN ES SACADO HACIA PORTC
CALL DELAY5MS
RETURN
END ;FIN DEL PROGRAMA