Last active
December 21, 2015 19:59
-
-
Save jerivas/6358214 to your computer and use it in GitHub Desktop.
Contador de números primos.
This file contains 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 numeros primos | |
;Jose Eduardo Rivas Melgar RM100161 | |
;David Antonio Escobar Contreras EC100119 | |
;Ángel Gerardo Moreno Galán MG070209 | |
;El contador de numeros primos permite iterar sobre los numeros primos menores | |
;que 100 usando dos pushbuttons, uno para moverse de forma ascendente y otro | |
;para descendente. El resultado se muestra en dos displays de 7 segmentos | |
;multiplexados. | |
;En realidad, el programa itera sobre los datos que esten guardados en la | |
;direccion 200h a la 218h (25 en total). Para cargar los numeros primos en esa | |
;direccion, se recomienda importar el archivo MCH adjunto. | |
;Notese que los datos se deben guardar en formato BCD empaquetado. | |
title "Contador de numeros primos" | |
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 btn_next INTCON,INT0IF ;Botón ascendente en PORTB0 | |
#define btn_prev INTCON3,INT1IF ;Botón descendente en PORTB1 | |
#define disp_1 LATB,4 ;Habilitador de display 1 en PORTB4 | |
#define disp_2 LATB,5 ;Habilitador de display 2 en PORTB5 | |
#define display LATD ;Codigo de 7 segmentos en PORTD | |
cblock | |
tmp ;Reservar memoria para una variable temporal | |
endc | |
org 0 | |
goto init ;En RESET, ir a la rutina de inicialización | |
;----------------------- | |
;RUTINAS DE INTERRUPCION | |
;----------------------- | |
org 0x08 ;Direccion 08 donde apunta el PC cuando hay interrupcion | |
bcf INTCON,GIE ;Inhabilitar interrupciones. Evita anidamiento | |
test_next: | |
btfsc btn_next ;Se activó el botón de siguiente? | |
goto test_prev ;No: Probar si fue el botón de anterior | |
movlw .50 ;Si: Mover 50 a W | |
call delay ;Retardo proporcional a W | |
btfsc btn_next ;Sigue presionado el boton después del retardo? | |
goto back_to_main ;No: Fue rebote, no hacer nada | |
movlw 18 ;Si: Mover 18h a W para comparar | |
cpfseq FSR0L ;El puntero llego al último primo? | |
goto inc_FSR0 ;No: Incrementar puntero | |
clrf FSR0L ;Si: Apuntar el puntero al primer primo | |
goto back_to_main ;Volver al programa principal | |
test_prev: | |
btfsc btn_prev ;Se activó el botón de anterior? | |
goto back_to_main ;No: No hacer nada, volver al programa principal | |
call delay ;Retardo proporcional a W | |
btfsc btn_prev ;Sigue presionado el boton después del retardo? | |
goto back_to_main ;No: Fue rebote, no hacer nada | |
tstfsz FSR0L ;Si: Probar, el puntero llegó a cero? | |
goto dec_FSR0 ;No: Decrementar el puntero | |
lfsr FSR0,218 ;Si: Apuntar el puntero al último primo | |
back_to_main: | |
bcf btn_next ;Limpiar la bandera de botón siguiente | |
bcf btn_prev ;Limpiar la bandera de botón anterior | |
retfie ;Regresar de la interrupcion (tambien habilita GIE) | |
;-------------- | |
;INICIALIZACION | |
;-------------- | |
init: | |
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 | |
lfsr FSR0,200 ;Apuntar FSR0 a la direccion 200h donde estan los primos | |
bcf INTCON2,INTEDG0 ;INT0 Activada en flanco descendente | |
bcf INTCON2,INTEDG1 ;INT1 Activada en flanco descendente | |
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 INDF0,W ;En W, obtener el primo actual | |
movwf tmp ;Copiarlo a tmp | |
andlw 0x0F ;En W, obtener solo las 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 | |
swapf tmp ;Hacer swap en tmp de decenas y unidades | |
movf tmp,W ;En W, obtener el primo ya intercambiado | |
andlw 0x0F ;Discrimiar de nuevo, esta vez 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 | |
;------------------ | |
inc_FSR0: | |
incf FSR0L | |
goto back_to_main | |
dec_FSR0: | |
decf FSR0L | |
goto back_to_main | |
;----------------------------------------------------- | |
;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 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment