Skip to content

Instantly share code, notes, and snippets.

@jerivas
Last active December 21, 2015 20:00
Show Gist options
  • Save jerivas/6358628 to your computer and use it in GitHub Desktop.
Save jerivas/6358628 to your computer and use it in GitHub Desktop.
Contador de personas
;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