Contador de 0 a 99 con PIC

se refiere algo así:

Código:
list      p=16f84a
    #include <p16f84a.inc>
 
    __config   _cp_off & _wdt_off & _pwrte_on & _xt_osc

;contador de 4 digitos.

Indo    equ     00h             ;registro de indireccion
pc      equ     02h             ;contador de programa
status  equ     03h             ;registro de estado
fsr     equ     04h             ;registro de seleccion
ptoa    equ     05h             ;puerto a
ptob    equ     06h             ;puerto b
rota    equ     0fh             ;variable para desplazamiento de display
trisa   equ     85h             ;configuracion puerto a
trisb   equ     86h             ;configuracion puerto b
dig1    equ     10h             ;acumulador miles
dig2    equ     11h             ;acumulador centenas
dig3    equ     12h             ;acumulador decenas
dig4    equ     13h             ;acumulador unidades
loops   equ     1dh             ;variables usadas en retardos
loops2  equ     1eh
z       equ     02h             ;flag de cero
ram     equ     05h             ;bit de seleccion de pagina de memoria
c       equ     00h             ;flag de acarreo
w       equ     00h             ;bit de destino a variable de trabajo

reset   org     00
        goto    inicio
        org     05h

retardo                         ;subrutina de retardo 
        movwf   loops           ;la variable de trabajo contiene la cant.
Top2    movlw   d'110'          ;de ms a demorar
        movwf   loops2
top     nop
        nop
        nop
        nop
        nop
        nop
        decfsz  loops2          ;controla si termina 1ms
        goto    top
        decfsz  loops           ;controla si termina el retardo completo
        goto    top2
        retlw   0

s1000                           ;rutina de incremento x 1000
        clrf    dig2            ;pone a cero las centenas
        incf    dig1            ;incrementa el contador de miles   
        movf    dig1, w         ;carga en work el conteo de los miles   
        xorlw   0ah             ;si work era 10, entonces quedara en cero
        btfsc   status, z       ;si es cero, el flag z queda alto
        clrf    dig1            ;inicializa los miles   
        return
s100                            ;rutina de incremento x 100
        clrf    dig3            ;pone a cero las decenas 
        incf    dig2            ;incrementa el contador de centenas
        movf    dig2, w         ;carga en work el conteo de las centenas
        xorlw   0ah             ;si work era 10, entonces quedara en cero
        btfsc   status, z       ;si es cero, el flag z queda alto
        call    s1000           ;incrementa los miles   
        return

s10                             ;rutina de incremento x 10
        clrf    dig4            ;pone a cero las unidades
        incf    dig3            ;incrementa el contador de decenas
        movf    dig3, w         ;carga en work el conteo de las decenas
        xorlw   0ah             ;si work era 10, entonces quedara en cero
        btfsc   status, z       ;si es cero, el flag z queda alto
        call    s100            ;incrementa las centenas
        return

subir                           ;rutina de incremento
        incf    dig4            ;incrementa el contador de unidades
        movf    dig4, w         ;carga en work el conteo de las unidades
        xorlw   0ah             ;si work era 10, entonces quedara en cero
        btfsc   status, z       ;si es cero, el flag z queda alto
        call    s10             ;incrementa las decenas
        movlw   d'250'          ;retardo de 100ms
        call    retardo
        return

tabla                           ;genera los numeros sobre el display
        addwf   pc              ;agrega al cont. Programa el valor de work
        retlw   b'00111111'     ;genera el 0
        retlw   b'00011000'     ;genera el 1
        retlw   b'01110110'     ;genera el 2
        retlw   b'01111100'     ;genera el 3
        retlw   b'01011001'     ;genera el 4
        retlw   b'01101101'     ;genera el 5
        retlw   b'01101111'     ;genera el 6
        retlw   b'00111000'     ;genera el 7
        retlw   b'01111111'     ;genera el 8
        retlw   b'01111101'     ;genera el 9

inicio                          ;programa principal
        bsf     status, ram     ;selecciona el banco de memoria alto
        movlw   b'00010000'     ;configura el puerto a
        movwf   trisa           ;bit 4 entrada, demas bits salidas.
        Movlw   00h             ;configura el puerto b
        movwf   trisb           ;como salidas
        bcf     status, ram     ;selecciona el banco de memoria bajo
        clrf    dig1            ;inicializa acumuladores
        clrf    dig2
        clrf    dig3
        clrf    dig4
        movlw   00              ;envia ceros a los transistores para apagar
        movwf   ptoa            ;todos los displays

empe    btfss   ptoa, 4         ;chequea el pulsador
        call    subir           ;llama la rutina de incremento
        movlw   08h             ;iniciar un 1 en el registro de rotacion
        movwf   rota            
        movlw   dig1            ;con el registro selector (fsr) se apunta
        movwf   fsr             ;al primer dato que se va a mostrar
disp    movlw   00h             ;colocar en cero el dato del display
        movwf   ptob            ;para apagarlos
        movf    rota, w         ;pasa rotacion del 1 a la variable work
        movwf   ptoa            ;enciende el transistor (display)
        movf    indo, w         ;lee el dato del registro apuntado por fsr
        call    tabla           ;genera el digito de 7 segmentos
        movwf   ptob            ;envia el digito al puerto b
        movlw   03h             ;retardo de 3ms para visualizacion
        call    retardo
        btfsc   rota, 0         ;controla si terminaron las cuatro rotaciones
        goto    empe            ;si termino, vuelve desde el comienzo
        bcf     status, c       ;carry en cero para no afectar las rotaciones
        rrf     rota            ;desplaza el 1 que enciende los displays
        incf    fsr             ;incrementa el puntero. Apunta el proximo
        goto    disp            ;digito a mostrar

        end

ya lo probe, muchas gracias, ahora solo me falta ponerle q cuente automaticamente ;)
 
Entonces el de pablito funciona bien y se conecta esactamente como la imagen en amarillo?? asi con sus transistores y todo ?

espero la respuesta, gracias.

(tengo que hacer un contador con pic)
 
Hola Comunidad, soy nuevo por aquí y necesito la ayuda de alguien, paso a contarles.
Tengo que hacer un contador usando el pic 16F84A de 4 dígitos que cuente de 0000 a 9999. Uso el MPLAB para compilar y el Proteus para simular, tengo la idea de hacer que comience a contar al darle con un pulsador una señal y luego siga automático, se me había ocurrido hacer unos registros y usar el flag de Z para hacer una resta del decimal 10 y el registro para que Z se levante y asi se le sume 1 al siguiente registro y así seguir hasta 9999 pero no se como hacerlo.. hice un frecuencímetro y de ahí saque la idea pero me trabo y no puedo hacerlo.
Acá lo dejo.
Código:
    LIST        P=16F84A
    INCLUDE        <P16F84A.INC>
    __CONFIG    _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC   ;PALABRA de configuracion (byte)


CBLOCK    0X0C                         ;creo registros de proposito general. Desde la primera direccion
    UNIDAD                            ;el registro UNIDAD es el que guarde en la primera direccion (0x0C)
    DECENA
    CENTENA
    UDEMIL
    DESBORDES
ENDC

ORG    0                                 ;donde inicia el programa
GOTO    INICIO

ORG    4                                 ;vector de interrupt
GOTO    INTERRUPCION
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
INICIO
    BSF        STATUS,RP0                ;ingresa al bco 1
    CLRF     TRISB                    ;pone en cero todo el tris b (portb como salida)
    MOVLW    b\'00011101\'             ;porta como entrada
    MOVWF    TRISA            
    MOVLW    b\'00000101\'                ;configuro registro option para decirle que use un prescaler de 64
    MOVWF    OPTION_REG        
    BCF        STATUS,RP0                ;configuracion de registro intcon se hace en bco 0
    MOVLW    b\'10100000\'                 ;configura el gie y la interrupcion de desbordamiento del timer0
    MOVWF    INTCON            
    CLRF    PORTA                    ;pongo a cero porta y portb para asegurarme de que esten limpios
    CLRF    PORTB
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRINCIPAL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    BTFSS    PORTA,0                    ;pregunta por 1 y por 0 (la señal de entrada comienza "low")
    GOTO    PRINCIPAL                ;detecto el pulso 
PREGUNTA
    BTFSC    PORTA,0        
    GOTO    PREGUNTA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
UNIDADES    
    INCF    UNIDAD                    ;una vez detectado el pulso, incremento el registro UNIDAD
    MOVLW    b\'00001010\'                ;cargo el decimal 10 a W
    SUBWF    UNIDAD,W                ;resto W a UNIDAD 
    BTFSS    STATUS,Z                ;compruebo que UNIDAD llego a 10
    GOTO    PRINCIPAL 
    CLRF    UNIDAD

DECENAS
    INCF    DECENA
    MOVLW    b\'00001010\'        
    SUBWF    DECENA,W            
    BTFSS    STATUS,Z        
    GOTO    PRINCIPAL
    CLRF    DECENA

CENTENAS
    INCF    CENTENA        
    MOVLW    b\'00001010\'        
    SUBWF    CENTENA,W            
    BTFSS    STATUS,Z        
    GOTO    PRINCIPAL
    CLRF    CENTENA

UNIDADES_DE_MIL
    INCF    UDEMIL
    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    GOTO PRINCIPAL


INTERRUPCION
    BSF        PORTA,1
    INCF    DESBORDES    
    MOVLW    b\'00111101\'                    ;debe desbordar 61 veces para que el tiempo sea de 1s
    SUBWF    DESBORDES,W        
    BTFSS    STATUS,Z
    GOTO    SALIR                        ;PARA QUE ENTRE AL MUESTREO TIENE QUE SUMAR HASTA 61, 

MUESTREO
    CLRF    PORTB
    MOVF    UNIDAD,W                    ;hago el latcheo de los 4511
    IORLW    b\'11100000\'
    MOVWF    PORTB            
    MOVF    DECENA,W
    IORLW    b\'11010000\'        
    MOVWF    PORTB            
    MOVF    CENTENA,W
    IORLW    b\'10110000\'        
    MOVWF    PORTB            
    MOVF    UDEMIL,W
    IORLW    b\'01110000\'        
    MOVWF    PORTB    
    CLRF    DESBORDES                    ;limpio los registros para volver a utilizarlos
    CLRF    UNIDAD
    CLRF    DECENA
    CLRF    CENTENA
    CLRF    UDEMIL
SALIR
    MOVLW    b\'10100000\' 
    MOVWF    INTCON    
    CLRF    TMR0    
RETFIE
END

Simulación:
edit


en la imagen se ve el pic y 4 4511 que son los que uso para convertir el dato a los displays 7 segmentos.

Desde ya muchas gracias a quien me pueda ayudar o me de alguna opinión.
Saludos.
 
proba el que te puse ese cuenta 0001 0002 0003 0004 0005 0006 0007 0008 0009 0010 asi hasta 9999


Hola garzon estuve mirando esto y la verdad que esta muy bueno, lo probe y funciona tal cual decís. Quisiera saber si podrías ayudarme con algo similar, trabajo en lenguaje assembler, tengo el MPLAB paracompilar y el Proteus para probar y tendria que cambiar algunas cosas de esto que te vo a dejar para que me funcione como tu contador, el tema es que no puedo hacerlo funcionar como contador, he intentado modificarlo pero me cuenta todo desordenado y salteado, te dejo mi circuito y programa original, el que debo modificar.Necesito usar esa misma placa con el pic16F84A, muchas gracias de antemano y espero no molestar, soy nuevo en el foro. nuevamente Gracias

FJH dijo:
Hola garzon estuve mirando esto y la verdad que esta muy bueno, lo probe y funciona tal cual decís. Quisiera saber si podrías ayudarme con algo similar, trabajo en lenguaje assembler, tengo el MPLAB paracompilar y el Proteus para probar y tendria que cambiar algunas cosas de esto que te vo a dejar para que me funcione como tu contador, el tema es que no puedo hacerlo funcionar como contador, he intentado modificarlo pero me cuenta todo desordenado y salteado, te dejo mi circuito y programa original, el que debo modificar.Necesito usar esa misma placa con el pic16F84A, muchas gracias de antemano y espero no molestar, soy nuevo en el foro. nuevamente Gracias

Perdón, me olvide de cargar el archivo :LOL:
 

Adjuntos

  • frecuencimetro.rar
    18.3 KB · Visitas: 18
Última edición:
Hola. Tengo un asm bajado de pablin.com.ar de un contador de 4 dígitos.
Funciona muy bien, pero al mantener oprimido el pulsador sigue contando.
Necesito que cuente a cada pulso del pulsador, si se queda pegado el pulsador que mantenga el último número.
¿Alguien me puede dar una mano?
Adjunto asm
Código:
;Contador de 4 digitos.

indo    equ     00h             ;registro de indireccion
pc      equ     02h             ;contador de programa
status  equ     03h             ;registro de estado
fsr     equ     04h             ;registro de seleccion
ptoa    equ     05h             ;puerto a
ptob    equ     06h             ;puerto b
rota    equ     0fh             ;variable para desplazamiento de display
trisa   equ     85h             ;configuracion puerto a
trisb   equ     86h             ;configuracion puerto b
dig1    equ     10h             ;acumulador miles
dig2    equ     11h             ;acumulador centenas
dig3    equ     12h             ;acumulador decenas
dig4    equ     13h             ;acumulador unidades
loops   equ     1dh             ;variables usadas en retardos
loops2  equ     1eh
z       equ     02h             ;flag de cero
ram     equ     05h             ;bit de seleccion de pagina de memoria
c       equ     00h             ;flag de acarreo
w       equ     00h             ;bit de destino a variable de trabajo

reset   org     00
        goto    inicio
        org     05h

retardo                         ;subrutina de retardo 
        movwf   loops           ;la variable de trabajo contiene la cant.
top2    movlw   d\'110\'          ;de ms a demorar
        movwf   loops2
top     nop
        nop
        nop
        nop
        nop
        nop
        decfsz  loops2          ;controla si termina 1mS
        goto    top
        decfsz  loops           ;controla si termina el retardo completo
        goto    top2
        retlw   0

s1000                           ;rutina de incremento x 1000
        clrf    dig2            ;pone a cero las centenas
        incf    dig1            ;incrementa el contador de miles   
        movf    dig1, w         ;carga en work el conteo de los miles   
        xorlw   0ah             ;si work era 10, entonces quedara en cero
        btfsc   status, z       ;si es cero, el flag z queda alto
        clrf    dig1            ;inicializa los miles   
        return
s100                            ;rutina de incremento x 100
        clrf    dig3            ;pone a cero las decenas 
        incf    dig2            ;incrementa el contador de centenas
        movf    dig2, w         ;carga en work el conteo de las centenas
        xorlw   0ah             ;si work era 10, entonces quedara en cero
        btfsc   status, z       ;si es cero, el flag z queda alto
        call    s1000           ;incrementa los miles   
        return

s10                             ;rutina de incremento x 10
        clrf    dig4            ;pone a cero las unidades
        incf    dig3            ;incrementa el contador de decenas
        movf    dig3, w         ;carga en work el conteo de las decenas
        xorlw   0ah             ;si work era 10, entonces quedara en cero
        btfsc   status, z       ;si es cero, el flag z queda alto
        call    s100            ;incrementa las centenas
        return

subir                           ;rutina de incremento
        incf    dig4            ;incrementa el contador de unidades
        movf    dig4, w         ;carga en work el conteo de las unidades
        xorlw   0ah             ;si work era 10, entonces quedara en cero
        btfsc   status, z       ;si es cero, el flag z queda alto
        call    s10             ;incrementa las decenas
        movlw   d\'250\'          ;retardo de 100ms
        call    retardo
        return

tabla                           ;genera los numeros sobre el display
        addwf   pc              ;agrega al cont. programa el valor de work
        retlw   b\'00111111\'     ;genera el 0
        retlw   b\'00011000\'     ;genera el 1
        retlw   b\'01110110\'     ;genera el 2
        retlw   b\'01111100\'     ;genera el 3
        retlw   b\'01011001\'     ;genera el 4
        retlw   b\'01101101\'     ;genera el 5
        retlw   b\'01101111\'     ;genera el 6
        retlw   b\'00111000\'     ;genera el 7
        retlw   b\'01111111\'     ;genera el 8
        retlw   b\'01111101\'     ;genera el 9

inicio                          ;programa principal
        bsf     status, ram     ;selecciona el banco de memoria alto
        movlw   b\'00010000\'     ;configura el puerto a
        movwf   trisa           ;bit 4 entrada, demas bits salidas.
        movlw   00h             ;configura el puerto b
        movwf   trisb           ;como salidas
        bcf     status, ram     ;selecciona el banco de memoria bajo
        clrf    dig1            ;inicializa acumuladores
        clrf    dig2
        clrf    dig3
        clrf    dig4
        movlw   00              ;envia ceros a los transistores para apagar
        movwf   ptoa            ;todos los displays

empe    btfss   ptoa, 4         ;chequea el pulsador
        call    subir           ;llama la rutina de incremento
        movlw   08h             ;iniciar un 1 en el registro de rotacion
        movwf   rota            
        movlw   dig1            ;con el registro selector (fsr) se apunta
        movwf   fsr             ;al primer dato que se va a mostrar
disp    movlw   00h             ;colocar en cero el dato del display
        movwf   ptob            ;para apagarlos
        movf    rota, w         ;pasa rotacion del 1 a la variable work
        movwf   ptoa            ;enciende el transistor (display)
        movf    indo, w         ;lee el dato del registro apuntado por fsr
        call    tabla           ;genera el digito de 7 segmentos
        movwf   ptob            ;envia el digito al puerto b
        movlw   03h             ;retardo de 3ms para visualizacion
        call    retardo
        btfsc   rota, 0         ;controla si terminaron las cuatro rotaciones
        goto    empe            ;si termino, vuelve desde el comienzo
        bcf     status, c       ;carry en cero para no afectar las rotaciones
        rrf     rota            ;desplaza el 1 que enciende los displays
        incf    fsr             ;incrementa el puntero. Apunta el proximo
        goto    disp            ;digito a mostrar

        end
 
Justo al final del programa, después de mostrar el número, hay que esperar a que el pulsador se levante.

La línea
PHP:
        goto    disp
la cambiamos por
PHP:
espe    btfsc   ptoa, 4     ; si sigue pulsado (0), saltamos una instrucción
        goto    disp        ; si no está pulsado (1), volvemos al bucle principal
        goto    espe        ; esperamos que el botón se levante
 
hola estoy programando un contador de 00 a 99 en mikrobasic pero no puedo programar que al accionar un swith vaya en forma decendente si me pueden aconsejar que hacer se los agradeceria
tengo esto asta el momento
program EXAMEN
dim suma as byte
dim DECENAS as byte
dim UNIDADES as byte
main:

trisb=0
trisd=0
trisa=1
portb=0
portd=0
suma=0

while 1=1

decenas = suma/10
unidades = suma mod 10
select case unidades
case 0
portd=63
case 1
portd=6
case 2
portd=91
case 3
portd=79
case 4
portd=102
case 5
portd=109
case 6
portd=125
case 7
portd=7
case 8
portd=127
case 9
portd=111
end select
select case decenas
case 0
portb=63
case 1
portb=6
case 2
portb=91
case 3
portb=79
case 4
portb=102
case 5
portb=109
case 6
portb=125
case 7
portb=7
case 8
portb=127
case 9
portb=111
end select
suma = suma + 1
delay_ms(5)
if suma =100 then
suma =0
end if
wend

end.
1583430468887.png
 
No está mal, está pésimo ese programa, es lo peor que he visto para hacer un simple contador.
Me parece que tu "profesor" no conoce los arreglos ni los bucles for.
no puedo programar que al accionar un swith vaya en forma decendente
En esta parte es donde debes hacer el cambio para que sume o reste.
Código:
suma = suma + 1
delay_ms(5)
if suma = 100 then suma = 0
Si no les enseñó a restar, deberían pedir un cambio de profesor y que en lugar de Basic les enseñe C.
 
También yo pondría

If suma >= 100 then suma = 0

por que si tienes un "rebote" en el pulsador cuando esta en 99 y debería sumar 1 y legar a 100 y en ves de eso suma 2 o 3, jamás el contador suma se limpiara.
 
No uso mikroBasic porque nunca me gustó el entorno, pero es muy sencillo.
Por ejemplo:

Código:
    If PORTAbits_RA0 = 1 Then
        suma = suma + 1
        If suma = 100 Then suma = 0
    Else
        suma = suma - 1
        If suma = 0 Then suma = 100
    End If
   
    Delay_MS (500)
Si usas el puerto A, recuerda que el PIC16F877A tiene conversor AD y tendrás que usarlo como digital. (Registro ADCON0)
O optar por usar el pin sobrante (RB7) del puerto B, declarar TRISB como 0b10000000 y hasta usar las resistencias pull-up internas. (Registro CMCON)
 
Código:
    If PORTAbits_RA0 = 1 Then
        suma = suma + 1
        If suma = 100 Then suma = 0
    Else
        suma = suma - 1
        If suma = 0 Then suma = 99
    End If

    Delay_MS (500)

99 Dark, por que es hasta o desde 99.

Por otro lado, me sorprende lo poco que interpretan las cosas, y lo poco que se acuerdan de la primaria.
Sumas, restas, multiplicacion, division, cosas basicas.
A leer e interpretar las cosas por favor.

@anthonyj por favor, usa la etiqueta de codigo la proxima vez.
Lee por aqui [TUTO] ¿Cómo subir archivos? (XenForo)
 
Nadie entiende sutilezas en este Foro
1583447698900.png
1) Si el interesado fue quién creó el programa le debería ser muy fácil lograr que el programa decremente la cuenta
2) El programa es horrible
 
Atrás
Arriba