# Contador ascendente/descendente con PIC



## Victor Usuga (Feb 20, 2010)

Primero que todo buenas tardes a todos. Estoy tratando de hacer un contador ascendente/descendente con el PIC16f873A.
Hasta el momento logré hacer que cuente de forma ascenderte, pero no he logrado hacer que cuente de forma descendente.
Agradezco si alguien sabe cómo hacerlo y que me de una mano.

Gracias de ante mano.

PD: adjunto el circuito en proteus y el proyecto en MPLAB


```
LIST P=16F873A
#INCLUDE <P16F873A.INC>
CONTADOR1 EQU 0X20
CONTADOR2 EQU 0X21

PDel0    EQU 0X22
PDel1    EQU 0X23

            ORG 00

            BANKSEL TRISB
            CLRF TRISB
            CLRF TRISC
            BSF TRISB,7; RB7 ENTRADA
            BSF TRISC,7; RC7 ENTRADA

            BANKSEL PORTB
INICIO:        CLRF CONTADOR1
            CLRF CONTADOR2

CUENTA1:    MOVF CONTADOR1,W
            CALL TABLA
            MOVWF PORTB

CUENTA:        MOVF CONTADOR2,W
            CALL TABLA
            MOVWF PORTC
             
            BTFSC PORTB,7
            GOTO $-1                         
                    BTFSS PORTB,7
                    GOTO $-1
              CALL ESPERA

            INCF CONTADOR2,1
        
            MOVF CONTADOR2,W
            XORLW .10

            BTFSS STATUS,Z
            GOTO CUENTA
 



            CLRF CONTADOR2

            INCF CONTADOR1,1
            
            MOVF CONTADOR1,W
            XORLW .10

            BTFSS STATUS,Z
            GOTO CUENTA1
            
            GOTO INICIO

ESPERA:
                      movlw     .8           
                          movwf     PDel0     
PLoop1                 movlw     .249      
                          movwf     PDel1     
PLoop2                 clrwdt                 
                          clrwdt                 
                          decfsz    PDel1, 1  
                           goto      PLoop2   
                          decfsz    PDel0,  1 
                          goto      PLoop1    
PDelL1                 goto      PDelL2     
PDelL2                 clrwdt                 
                         return                 

TABLA:
        ADDWF PCL,1
        RETLW B'1000000'        
        RETLW B'1111001'
        RETLW B'0100100'
        RETLW B'0110000'
        RETLW B'0011001'
        RETLW B'0010010'
        RETLW B'0000011'
        RETLW B'1111000'
        RETLW B'0000000'
        RETLW B'0011000'


        END
```


----------



## DOA (Feb 21, 2010)

Para el conteo descendente debes restar 1 excepto cuando sea 0 en ese caso debes convertirlo en un 9 y restar 1 al siguiente digito mas significativo


----------



## Victor Usuga (Feb 22, 2010)

Bueno ya logre que cuente en modo desendente, claro que me toco cabiar bastante el codigo. pero no logro hacer que cuando decremente hasta 00 se quede hay.


```
LIST P=16F873A
#INCLUDE <P16F873A.INC>
CONTADOR1 EQU 0X20
CONTADOR2 EQU 0X21

PDel0    EQU 0X22
PDel1    EQU 0X23

            ORG 00
;-----COMFIGURACION DE PUERTOS
            BANKSEL TRISB
            CLRF    TRISB
            CLRF    TRISC
            BSF     TRISB,7; RB7 ENTRADA
            BSF     TRISC,7; RC7 ENTRADA            
            BANKSEL PORTB
;_______________________________
INICIO:        CLRF  CONTADOR1
            CLRF  CONTADOR2

CUENTA1:    MOVF  CONTADOR1,W
            CALL  TABLA
            MOVWF PORTB

CUENTA:        MOVF  CONTADOR2,W
            CALL  TABLA
            MOVWF PORTC
;_________________________________
 
ATRAS:
            BTFSC PORTB,7
            GOTO  ANTERIOR
            CALL  ESPERA
            GOTO  ATRAS1

ANTERIOR:    BTFSC PORTC,7
            GOTO  ATRAS
            CALL  ESPERA
            GOTO  SIGUIENTE

ATRAS1:      BTFSS PORTB,7
            GOTO  ATRAS1
            GOTO  INCREMENTO

SIGUIENTE:  BTFSS PORTC,7
            GOTO  SIGUIENTE
            GOTO  DECREM
;_________________________________ 
INCREMENTO:

            INCF  CONTADOR2,1
              MOVF  CONTADOR2,W
            XORLW .10

             BTFSS STATUS,Z
            GOTO  CUENTA
            

            CLRF  CONTADOR2
            INCF  CONTADOR1,1
            MOVF  CONTADOR1,W
            XORLW .10

            BTFSS STATUS,Z
            GOTO  CUENTA1            
            GOTO  INICIO
;__________________________________
DECREMENTO:
    
            MOVFW  CONTADOR2
            XORLW  .0
            BTFSS  STATUS,Z
            GOTO   ADELANTE
    

                 CONTADOR1
            XORLW    .0
            BTFSS    STATUS,Z
            GOTO    ADELANTE_1
            MOVLW    .10
            MOVWF    CONTADOR1
    

ADELANTE_1  DECF    CONTADOR1
            MOVLW    .10
            MOVWF    CONTADOR2
            GOTO    CUENTA1

ADELANTE    DECF    CONTADOR2,1
            MOVLW   .0
            XORWF   CONTADOR2,0
            BTFSS   STATUS,Z
            GOTO    CUENTA
    
            MOVLW   .0
            MOVWF   CONTADOR2
:___________________________________           
            MOVLW   CONTADOR2
             XORLW   .0
            BTFSS    STATUS,Z
            GOTO    CUENTA
            CLRF    CONTADOR1
            CLRF    CONTADOR2
            GOTO    $-1
            GOTO    CUENTA    
;____________________________________

ESPERA:
        movlw     .8        ; 1 set numero de repeticion  (B)
        movwf     PDel0     ; 1 |
PLoop1  movlw     .249      ; 1 set numero de repeticion  (A)
        movwf     PDel1     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
        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
PDelL1  goto      PDelL2    ; 2 ciclos delay
PDelL2  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.

TABLA:
        ADDWF PCL,1
        RETLW B'1000000'        
        RETLW B'1111001'
        RETLW B'0100100'
        RETLW B'0110000'
        RETLW B'0011001'
        RETLW B'0010010'
        RETLW B'0000011'
        RETLW B'1111000'
        RETLW B'0000000'
        RETLW B'0011000'


        END
```


----------



## Victor Usuga (Feb 25, 2010)

bueno compañeros se me presento una duda con una visualizasion dinamica la idea es hacer un contador asendente/desendente de 0000 a 9999, hasta el momento solo logro que cuente de 00 a 99 pero solamente asendete , si alguien sabe como hacer para que funcionen los 4 display sin parpadeo hasta 9999 le estare muy agredecido adjunto el proyecto en MPLAB y el circuito en proteus.


----------



## ivanamado16 (May 14, 2012)

Alguien que me pudiera decir en que programa pongo el codigo para el PIC ? se puede en el mismo en donde codificas un GAL ?


----------



## miller931017 (Mar 26, 2015)

Buenas noches. Tengo una inquietud. Hice un programa en ensamblador que debería contar en binario Arriba/Abajo, según las pulsaciones en los puertos A0 y A1, pero el programa no hace nada.
Se queda con un led encendido en el puerto B0. Lo curioso es que el programa compila pero no sé que tendré mal en el código que hace que no funcione.

Acá envío adjunto el código para ver de que forma pueden ayudarme. (estoy trabajando con un PIC18F452 )

Agradecería mucho sus respuesta puesto que soy un principiante en el tema de ensamblador.

Gracias.

```
;-------------------------------------------------------------------------------------------------------------------- 
list p = 18F452              ; Define el tipo de procesador a emplear
#include<p18F452.inc>  

    
    cblock    0x20
    ret1,ret2,ret3            ; Variables para retardo
    endc

org 0x00 ; Origen de programa
rcall CONF_PUERTOS
rcall BORRAR_BASURA
rcall SUMA_RESTA
rcall RETARDO

;-------------------------------------------------------------------------------------------------------------------- 

CONF_PUERTOS
; Esta rutina se emplea para configurar los pines del microcontrolador que se van a emplear.
; Los pines que se configuran con CERO (0) son salidas. Los pines que se configuran con UNO (1) son entradas
;76543210
movlw b\'00000011\' ;Defino A0 y A1 como entradas
movwf TRISA
clrf  TRISB ; Configura Todo el puerto B de Salida
return

;--------------------------------------------------------------------------------------------------------------------


BORRAR_BASURA
; Esta rutina garantiza que los registros que se van a emplear inicien en Cero
clrf PORTB
return

;-------------------------------------------------------------------------------------------------------------------- 

SUMA_RESTA

sumar
    btfsc    PORTA,1            ; Comprobar si RA1 es 0
    goto    restar            ; No es 0, ir a rutina restar
    incf    PORTB,f            ; RA1 es 0, incrementar los bits del puerto B
    call    retardo.5        ; Retardo de 500Ms.
restar
    btfsc    PORTA,0            ; Comprobar si RA0 es 0
    goto    sumar            ; No es 0, ir a rutina sumar
    decf    PORTB,f            ; RA0 es 0, decrementar los bits del puerto B
    call    retardo.5        ; retardo de 500Ms.
    goto    sumar            ; Ir a rutina sumar para hacer un bucle

;-------------------------------------------------------------------------------------------------------------------- 
; Subrutina de retardo de 500Ms @ 4MHz.
RETARDO

retardo.5
    movlw    0x03
    movwf    ret1
    movlw    0x18
    movwf    ret2
    movlw    0x02
    movwf    ret3
retardo.5_0
    decfsz    ret1,f
    goto    $+2
    decfsz    ret2,f
    goto    $+2
    decfsz    ret3,f
    goto    retardo.5_0
    goto    $+1
    return
  
;-------------------------------------------------------------------------------------------------------------------- 
end
```


----------



## D@rkbytes (Mar 26, 2015)

Te hace falta la palabra de configuración y debes establecer que los pines que estás usando para los pulsadores sean digitales, porque por defecto RA0 y RA1 son de entrada análoga para los conversores AD.

En los PIC18 esa rutina para el retardo no te va a funcionar si no la modificas.
En el *goto $+1*, el compilador te dará una advertencia sobre: "Destination address must be word aligned"
Puedes usar etiquetas para redirigir el destino o usar PDEL (PIC Delayer) para generar la rutina de retardo.
También es conveniente usar los registros LATX para las salidas en vez de los PORTX.

PD:
No olvides leer la hoja de datos.
Esas rutinas son de un programa de ejemplo que subí alguna vez al Foro. 
Así que funcionan, sólo tienes problemas de configuración y en la rutina de retardo.


----------



## miller931017 (Mar 26, 2015)

Ya logré hacer el código, y el montaje no me funcionaba en el circuito porque estaba deshabilitada la opción ON y MCLR del pickit2  :cabezon:
Aunque aun tengo la duda de por que no me funciona el MCLR del pic 
Acá dejo la simulación y el código en MPLAB para quien lo necesite (Perdón por el nombre de ADC , en realidad estoy haciendo un DAC  )

Gracias a D@rkbytes por la ayuda


----------



## D@rkbytes (Mar 26, 2015)

El montaje no te funcionaría por las razones que cité anteriormente.
Ahora cambiaste los pines de los pulsadores a un puerto sin ADC.

Comentas que la configuración de fuses la haces con el PICkit 2, pero te recomiendo que leas los archivos *.INC, pues en ellos se encuentran los fuses para cada PIC y todos los registros.
Ahí verás que el PIC18F452 no tiene el fuse MCLR, por lo tanto ese pin únicamente debe funcionar como reset.
En tu simulación funciona, y físicamente también lo debe hacer.

PD:
La nueva rutina de retardo que agregaste no está realizando un retardo de 500 ms.

Los cambios para que el programa anterior funcionara, serían éstos:

```
;-------------------------------------------------------------------------------------------------------------------- 
    list p = 18F452    ; Define el tipo de microcontrolador a emplear
    include p18F452.inc  
    CONFIG    OSC = XT, PWRT = ON, WDT = OFF, LVP = OFF

    cblock    0x80
    PDel0,PDel1,PDel2,PDel3    ; Variables para el retardo
    endc

    org    0x00 ; Vector de reset.
;-------------------------------------------------------------------------------------------------------------------- 
; Configurar el puerto A como Digital I/O
    movlw    0x07
    movwf    ADCON1
; Esta rutina se emplea para configurar los pines del microcontrolador que se van a emplear.
; Los pines que se configuran con CERO (0) son salidas. Los pines que se configuran con UNO (1) son entradas
;76543210
    clrf     TRISB ; Configura Todo el puerto B como salidas.
; Esta rutina garantiza que los registros que se van a emplear inicien en cero
    clrf    PORTB
;-------------------------------------------------------------------------------------------------------------------- 
sumar
    btfsc    PORTA,1            ; Comprobar si RA1 es 0
    goto    restar            ; No es 0, ir a rutina restar
    incf    LATB,f            ; RA1 es 0, incrementar los bits del puerto B
    call    retardo.5        ; Retardo de 500Ms.
restar
    btfsc    PORTA,0            ; Comprobar si RA0 es 0
    goto    sumar            ; No es 0, ir a rutina sumar
    decf    LATB,f            ; RA0 es 0, decrementar los bits del puerto B
    call    retardo.5        ; retardo de 500Ms.
    goto    sumar            ; Ir a rutina sumar para hacer un bucle

;-------------------------------------------------------------------------------------------------------------------- 
; Subrutina de retardo de 500Ms @ 4MHz.
retardo.5
        movlw    .239        ; 1 Establecer el número de repetición (B)
        movwf    PDel0        ; 1
PLoop1    movlw    .232        ; 1 Establecer el número de repetición (A)
        movwf    PDel1        ; 1
PLoop2    clrwdt                ; 1 Limpiar el 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.
;-------------------------------------------------------------------------------------------------------------------- 
    end
```


Suerte.


----------

