Last active
December 21, 2015 20:00
-
-
Save jerivas/6358628 to your computer and use it in GitHub Desktop.
Contador de personas
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;Contador de personas en una habitación | |
;José Eduardo Rivas Melgar RM100161 | |
;David Antonio Escobar Contreras EC100119 | |
;Angel Gerardo Moreno Galan MG070209 | |
;El contador de personas incrementa un contador cada vez que una persona entra | |
;a la habitación, y lo decrementa cuando una sale. El numero de personas se | |
;muestra en todo momento en dos displays a través del puerto D. Se usan dos | |
;sensores, uno de entrada y otro de salida, para saber cuando una persona ha | |
;pasado por la entrada o salida. | |
title "Contador de personas" | |
list p=18f4550 | |
#include <p18f4550.inc> | |
;Directivas para activar los bits de configuracion | |
config FOSC = INTOSCIO_EC ;Oscilador Interno, Puerto A RA6 activo, | |
config WDT = OFF ;Watchdog timer apagado | |
config PBADEN = OFF ;Parte baja del puerto B digitales | |
config MCLRE = ON ;MCLRE Disponible | |
config DEBUG = ON ;Modo de depuracion disponible | |
config LVP = OFF ;Fuente de ISCP apagada | |
;Definicion de constantes utiles | |
#define entry INTCON,INT0IF ;Sensor de entrada en PORTB0 | |
#define exit INTCON3,INT1IF ;Sensor de salida en PORTB1 | |
#define disp_1 LATB,4 ;Selector de display 1 en PORTB4 | |
#define disp_2 LATB,5 ;Selector de display 2 en PORTB5 | |
#define display LATD ;Codigo de 7 segmentos en PORTD | |
cblock ;Se reserva memoria para estas variables: | |
counter ;Contador en base 16 de las personas en la habitacion | |
MSD ;Dígito BCD más significativo = decenas | |
LSD ;Dígito BCD menos significativo = unidades | |
endc | |
;----------------------- | |
;RUTINAS DE INTERRUPCION | |
;----------------------- | |
org 0x08 ;Direccion 08 donde apunta el PC cuando hay interrupcion | |
bcf INTCON,GIE ;Inhabilitar interrupciones. Evita anidamiento | |
test_entry: | |
btfss entry ;Se activó el sensor de entrada? | |
goto test_exit ;No: Probar si fue el sensor de salida | |
movlw .99 ;Si: Mover 99 a W para comparar | |
cpfseq counter ;El contador llego a 99? | |
call inc_counter ;No: Incrementar el contador | |
goto back_to_main ;Si: No hacer nada, volver al programa principal | |
test_exit: | |
btfss exit ;Se activó el sensor de salida? | |
goto back_to_main ;No: No hacer nada, volver al programa principal | |
tstfsz counter ;Si: Probar, el contador llegó a cero? | |
call dec_counter ;No: Decrementar el contador | |
back_to_main: ;Si: Prepararse para volver al programa principal | |
bcf entry ;Limpiar la bandera de entrada | |
bcf exit ;Limpiar la bandera de salida | |
retfie ;Regresar de la interrupcion (tambien habilita GIE) | |
;-------------- | |
;INICIALIZACION | |
;-------------- | |
org 0 | |
goto .100 ;El código inicia en la dirección 100 | |
org .100 | |
clrf display ;Inicializar Puerto D | |
clrf TRISD ;Configurar todo el puerto D como salida | |
movlw b'00000011' | |
movwf TRISB ;PORTB0 y 1 son entradas, PORTB4 y 5 son salidas | |
bcf disp_1 ;Deshabilitar el display 1 | |
bcf disp_2 ;Deshabilitar el display 2 | |
clrf counter ;Limpiar el contador de personas. Se cuenta en base 16 | |
clrf LSD ;Limpiar las unidades | |
clrf MSD ;Limpiar las decenas | |
bsf INTCON2,INTEDG0 ;INT0 Activada en rising | |
bsf INTCON2,INTEDG1 ;INT1 Activada en rising | |
bsf INTCON,GIE ;Habilitar interrupciones globalmente | |
bsf INTCON,PEIE ;Habilitar interrupciones perifericas | |
bsf INTCON,INT0IE ;Habilitar interrupcion INT0 | |
bsf INTCON3,INT1IE ;Habilitar interrupcion INT1 | |
;----------------------------------------------------------------- | |
;Programa principal: | |
;Rutina que muestra el conteo actual en dos displays multiplexados | |
;----------------------------------------------------------------- | |
multiplex_displays: | |
movf LSD,W ;En W, obtener el LSD = unidades | |
call bin_to_seg ;Convertirlo a codigo 7 segmentos | |
bcf disp_2 ;Apagar el display 2 | |
movwf display ;Preparar el código a mostrar | |
bsf disp_1 ;Mostrarlo en display 1 | |
movlw .25 ;Cargar 25 en W | |
call delay ;Retardo proporcional a W | |
movf MSD,W ;En W, obtener el MSD = decenas | |
call bin_to_seg ;Convertirlo a codigo 7 segmentos | |
bcf disp_1 ;Apagar el display 1 | |
movwf display ;Preparar el código a mostrar | |
bsf disp_2 ;Mostrarlo en display 2 | |
movlw .25 ;Cargar 25 en W | |
call delay ;Retardo proporcional a W | |
goto multiplex_displays ;Repetir | |
;------------------ | |
;RUTINAS AUXILIARES | |
;------------------ | |
;----------------------------------------------------- | |
;Binario a 7 segmentos | |
;Convierte el valor binario en W en codigo 7 segmentos | |
;El codigo adecuado se retorna en W | |
;----------------------------------------------------- | |
bin_to_seg: | |
mullw .2 ;Multiplicar Wx2. El resultado se guarda en PROD | |
movf PRODL,W ;Copiar el resultado de PRODL a W | |
addwf PCL,F ;El puntero de programa se desplaza de acuerdo al valor | |
;que esta en W. Esto selecciona el cod. adecuado. | |
;Formato de bits del codigo 7 seg: xgfedcba | |
retlw b'00111111' ;0 | |
retlw b'00000110' ;1 | |
retlw b'01011011' ;2 | |
retlw b'01001111' ;3 | |
retlw b'01100110' ;4 | |
retlw b'01101101' ;5 | |
retlw b'01111101' ;6 | |
retlw b'00000111' ;7 | |
retlw b'01111111' ;8 | |
retlw b'01101111' ;9 | |
;------------------------------------------------------------ | |
;Delay: | |
;Crea una espera proporcional al valor de W cuando es llamado | |
;------------------------------------------------------------ | |
cblock | |
del0,del1,del2 ;Reservar memoria para tres variables | |
endc | |
delay: | |
movwf del2 ;del2 = W | |
ldel: | |
movlw .15 | |
movwf del1 ;del1 = 15 | |
movlw .207 | |
movwf del0 ;del0 = 207 | |
decfsz del0,F ;Decrementar. del0 = 0? | |
goto $ + 2 ;No: bajar dos lineas | |
decfsz del1,F ;Si: Decrementar. del1 = 0? | |
goto $ - 3 ;Subir tres lineas | |
decfsz del2,F ;Decrementar. del2 = 0? | |
goto ldel ;No: ir a ldel | |
return ;Si: Fin de subrutina | |
;----------------------------------------------------------------- | |
;Incrementar contador: | |
;Incrementa el contador y convierte el resultado a BCD empaquetado | |
;----------------------------------------------------------------- | |
inc_counter: | |
incf counter ;Incrementar el contador | |
goto bin8_bcd ;Convertir el conteo a BCD empaquetado | |
;----------------------------------------------------------------- | |
;Decrementa el contador: | |
;Decrementa el contador y convierte el resultado a BCD empaquetado | |
;Se base en restas iteradas para simular la división entre 10 | |
;----------------------------------------------------------------- | |
dec_counter: | |
decf counter ;Decrementar el contador | |
bin8_bcd: ;Convertir el conteo a BCD empaquetado | |
movf counter,W ;Copiar el valor del contador a W | |
clrf MSD ;Limpiar el digito mayor (decenas) | |
movwf LSD ;Copiar W al digito menor (unidades) | |
conv_bcd: | |
movlw .10 ;W = 10 | |
subwf LSD, W ;W = LSD - 10 | |
btfss STATUS,C ;La diferencia fue mayor que 0? LSD > 10? | |
goto conv_done ;No: Termina el proceso de conversión | |
movwf LSD ;Si: Actualizar LSD con el valor restado | |
incf MSD, F ;Aumentar en uno a MSD | |
goto conv_bcd ;Repetir | |
conv_done: | |
return | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment