HomeArticlesProjectsBlogContact
Articles
2-Digit up/down Counter
Colin Mitchell
Colin Mitchell
June 20, 2009
Make sure to subscribe to our newsletter and be the first to know the news.

2 Digit Up/Down Counter with PIC12F628 and prototype PC board $25.00 plus $5.00 postage.
To order the kit, [send an email](mailto:colin@elechelp.com?Subject=Buying components for the 2 Digit Up/Down counter&Body=Please e-mail the cost of components for the 2 Digit Up/Down counter on prototype PC board for $25.00 plus postage by air mail to my country:**___**** and send details of how I can pay for it. My name is:____)** to us and we will reply with the details of how to order etc.

  • Page 1 2 digit Up/Down Counter using PIC16F628P2 adding Dice and Random Number (PIC16F628)
  • P2
  • Page 3 2 digit Up/Down Counter using PIC12F629
  • Page 4 adding RF Link to PIC12F629 version
  • Page 5 Car Gears Up/Down counter

Adding DICE and Random Number

Any number of features can be added to the program to produce additional “effects” or features.
The first is DICE.
This is accessed by pressing UP button while the project is turned on.
The micro then goes to sub-routine AAA and displays D I C E on the left-hand display.
When button is released the micro goes to “Dice” sub-routine.
A register is incremented to 6 when in a loop, waiting for button A to be pressed. When it reaches 6, it is cleared and incremented before the button is detected.
This value is then used to obtain a display-value from the table and displayed on the right-hand display.

;****************************************************************
;*     Started 18/6/2009
;2 Digit UP / Down Counter with FastCount after 2secs
;Buttons "Up" and "Down" recognised at the instant project turned on.
;Button A goes to DICE
;Port B drives 7 segment display
;Up sw on RA2   Down on RA3
;Units drive on RA0   Tens drive on RA1             *
;*                              *
;****************************************************************

    list P = 16F628     ;microcontroller
    include     ;registers for F628


    __Config    _cp_off & _lvp_off & _pwrte_on
        & _wdt_off & _intRC_osc_noclkout & _mclre_off

;code protection - off
;low-voltage programming - off
;power-up timer -  on
;watchdog timer - off
;use internal RC for 4MHz - all pins for in-out


;****************************************************************
; variables - names and files
;****************************************************************


        ;Files for F628 start at 20h


temp1     equ 20h   ;for delay
temp2     equ 21h   ;for delay
temp3     equ 22h   ;for delay
SwUp      equ 23h   ;
SwDwn     equ 24h   ;
units     equ 25h   ;
tens      equ 26h   ;
Sw_Flag   equ 27h   ;
FastCount equ 28h   ;

;****************************************************************
;Equates
;****************************************************************
status  equ 0x03
cmcon   equ 0x1F
rp1 equ 0x06
rp0 equ 0x05
portA   equ 0x05
portB   equ 0x06


;****************************************************************
;Beginning of program
;****************************************************************
reset   org 00  ;reset vector address
    goto    SetUp   ;goto SetUp


table   addwf   PCL,F           ;02h,1  add W to program counter
        retlw   b'00111111'     ; "0"   -|F|E|D|C|B|A
        retlw   b'00000110'     ; "1"   -|-|-|-|C|B|-
        retlw   b'01011011'     ; "2"   G|-|E|D|-|B|A
        retlw   b'01001111'     ; "3"   G|-|-|D|C|B|A
        retlw   b'01100110'     ; "4"   G|F|-|-|C|B|-
        retlw   b'01101101'     ; "5"   G|F|-|D|C|-|A
        retlw   b'01111101'     ; "6"   G|F|E|D|C|-|A
        retlw   b'00000111'     ; "7"   -|-|-|-|C|B|A
        retlw   b'01111111'     ; "8"   G|F|E|D|C|B|A
        retlw   b'01101111'     ; "9"   G|F|-|D|C|B|A


;****************************************************************
;* port A and B initialisation
;Button Up  and Button Down recognised when project turned on.
;****************************************************************

SetUp   bsf status,rp0
    movlw   b'00001100' ;Make RA0,1 out RA2 in(Up),RA3 in(Down)
    movwf   05h     ;trisA
    clrf    06h     ;trisB   Make all RB output
    bcf status,rp0  ;select programming area - bank0
    movlw   b'10000000' ;Turn off T0CKI, prescale for TMR0 = 1:
    movwf   option_reg
    clrf    portB       ;Clear Port B of junk
    clrf    units       ;zero the units file
    clrf    tens        ;zero the tens file
    clrf    Sw_Flag
    movlw   07h     ;turn comparators off and enable
    movwf   cmcon       ;    pins for I/O functions
    btfss   portA,2
    goto    AAA     ;Button A detected for DICE(detects LOW)
    ;btfss  portA,3
    ;goto   Random      ;Button B detected (see next program)
    goto    Main

AAA call    D_250mS
    btfsc   portA,2
    goto    Dice
    movlw   b'00000010' ;Make RA1 HIGH for left display
    movwf   portA
    movlw   b'01011110' ; "d"   G|-|E|D|C|B|-
    movwf   portB
    call    D_250mS
    movlw   b'00000110' ; "I"   -|-|-|-|C|B|-
    movwf   portB
    call    D_250mS
    movlw   b'00111001' ; "C"   -|F|E|D|-|-|A
    movwf   portB
    call    D_250mS
    movlw   b'01111001' ; "E"   G|F|E|D|-|-|A
    movwf   portB
    call    D_250mS
    clrf    portB
    goto    AAA


;****************************************************************
;* Delay 10mS       10 x 1,000uS            *
;****************************************************************



D_10mS  movlw   0Ah
    movwf   temp2
D_a nop
    decfsz  temp1,1
    goto    D_a
    decfsz  temp2,1
    goto    D_a
    retlw   00



D_100mS movlw   d'100'
    movwf   temp2
D_b nop
    decfsz  temp1,1
    goto    D_b
    decfsz  temp2,1
    goto    D_b
    retlw   00

D_250mS movlw   d'250'
    movwf   temp2
D_c nop
    decfsz  temp1,1
    goto    D_c
    decfsz  temp2,1
    goto    D_c
    retlw   00


D_3Sec  movlw   d'15'
    movwf   temp3
D_d nop
    decfsz  temp1,1
    goto    D_d
    decfsz  temp2,1
    goto    D_d
    decfsz  temp3,1
    goto    D_d
    retlw   00



FastUp  btfss   Sw_Flag,2   ;First time through loop?
    goto    FU_2        ;yes
    btfsc   Sw_Flag,7   ;Has 5Hz bit been set?
    goto    FU_3
FU_1    incfsz  FastCount,1 ;Increment FastCount
    movlw   d'100'
    xorwf   FastCount,0
    btfss   status,2    ;reached 100 loops?
    retlw   00
    clrf    FastCount
    bsf Sw_Flag,7   ;set bit for 5Hz incrementing



FU_2    bsf Sw_Flag,2   ;Up button has been pressed
    incf    units,1
    movlw   0Ah     ;put 10 into w
    xorwf   units,0     ;compare units file with 10
    btfss   status,2    ;zero flag in status file. Set if units is 10
    retlw   00
    clrf    units
    incf    tens,1
    movlw   0Ah     ;put 10 into w
    xorwf   tens,0      ;compare units file with 10
    btfsc   status,2    ;zero flag in status file. Set if tens is 10
    clrf    tens
    retlw   00      ;display passes 99 but not below 0


FU_3    incfsz  FastCount,1 ;Increment FastCount
    movlw   d'5'
    xorwf   FastCount,0
    btfss   status,2    ;reached 5 loops?
    retlw   00
    clrf    FastCount
    goto    FU_2


Dwn btfsc   Sw_Flag,3
    retlw   00
    bsf Sw_Flag,3
    decf    units,1
    movlw   0FFh        ;put FFh into w
    xorwf   units,0     ;compare units file with FFh
    btfss   status,2    ;zero flag in status file. Set if units is 10
    retlw   00
    movlw   09
    movwf   units       ;put 9 into units file
    decf    tens,1
    movlw   0FFh        ;put 0FFh into w
    xorwf   tens,0      ;compare tens file with 0FFh
    btfsc   status,2    ;zero flag in status file. Set if tens is 0FFh
    goto    $+2     ;tens file is 0FFh
    retlw   00
    clrf    tens
    clrf    units
    retlw   00          ;display  not below 0


;****************************************************************
;* Dice     Produces a random number from 1 to 6 on display
;  The display flashes before settling on a number - called attract mode.
;Program detects timing of button-push to generate number       *
;****************************************************************

Dice    incf    units,f
    btfss   portA,2     ;look for button-push
    goto    Start       ;button A pushed
    movf    units,w
    xorlw   06
    btfss   status,2
    goto    Dice
    clrf    units
    goto    Dice

Start   movlw   08
    movwf   temp3
    call    Attract
    decfsz  temp3,f
    goto    $-2
    goto    Show        ;


Attract movlw   b'00000001' ;Make RA0 HIGH for right-hand display
    movwf   portA
    movlw   b'00001000' ;
    movwf   portB
    call    D_100mS

    movlw   b'01000000' ;
    movwf   portB
    call    D_100mS

    movlw   b'00001000' ;
    movwf   portB
    call    D_100mS
    movlw   b'00000001' ;
    movwf   portB
    call    D_100mS

    retlw   00

Show    movf    units,w
    call    table
    movwf   portB
Show1   call    D_250mS
    btfss   portA,2     ;look for button not pushed
    goto    Show1
    goto    Dice


;****************************************************************
;* Main                             *
;****************************************************************

Main    btfss   portA,2     ;test switch-press for UP
    call    FastUp      ;UP switch pressed
    btfss   portA,3     ;test switch-press for Down
    call    Dwn     ;Down switch pressed
    movlw   b'00000001' ;Make RA0 HIGH for units drive
    movwf   portA
    movf    units,0     ;copy unit value into w
    call    table       ;unit display value will return in w
    movwf   portB       ;output units value
    call    D_10mS      ;call delay
    clrf    portB       ;clear display
    movlw   b'00000010' ;Make RA1 HIGH for tens drive
    movwf   portA
    movf    tens,0      ;copy tens value into w
    call    table       ;tens display value will return in w
    movwf   portB       ;output tens value
    call    D_10mS      ;call delay
    clrf    portB       ;clear display
    btfsc   portA,3     ;bit will be zero when sw is pressed
    bcf Sw_Flag,3   ;button not pressed. Clear down flag
    btfss   portA,2     ;bit will be zero when sw is pressed
    goto    Main
    bcf Sw_Flag,2   ;button not pressed. Clear Up flag
    bcf Sw_Flag,7   ;Clear Up repeat flag
    clrf    FastCount
    goto    Main

    END

Adding Random Number

The Random Number program is accessed by pushing button B while turning the project ON. The random number is generated when the micro is displaying a value on the two displays. The Count file is incremented to 100. The display-time has been decreased to 2mS so the count file is incremented very quickly so you cannot predict the ext random number. If the display-time was long, the next number to appear could be predicted as Count file would only increment a small amount.
Button UP is pressed to generate the Random Number.

The relevant files for burning a PIC16F628 chip:

;****************************************************************
;*     Started 18/6/2009
;2 Digit UP / Down Counter with FastCount after 2secs
;No buttons pressed - goes to Up/Down Counter
;Buttons "Up" and "Down" recognised when project turned on.
;Button A goes to DICE
;Button B goes to Random Number 00 to 99
;Port B drives 7 segment display
;Up sw on RA2   Down on RA3
;Units drive on RA0   Tens drive on RA1
;*                              *
;****************************************************************

    list P = 16F628     ;microcontroller
    include ;registers for F628


    __Config    _cp_off & _lvp_off & _pwrte_on
            & _wdt_off & _intRC_osc_noclkout & _mclre_off

;code protection - off
;low-voltage programming - off
;power-up timer -  on
;watchdog timer - off
;use internal RC for 4MHz - all pins for in-out


;****************************************************************
; variables - names and files
;****************************************************************


        ;Files for F628 start at 20h


temp1       equ 20h ;for delay
temp2       equ 21h ;for delay
temp3       equ 22h ;for delay
SwUp        equ 23h ;
SwDwn       equ 24h ;
units       equ 25h ;
tens        equ 26h ;
Sw_Flag     equ 27h ;
FastCount   equ 28h ;
Count       equ 29h ; counting 00 to 99

;****************************************************************
;Equates
;****************************************************************
status      equ 0x03
cmcon       equ 0x1F
rp1     equ 0x06
rp0     equ 0x05
portA       equ 0x05
portB       equ 0x06


;****************************************************************
;Beginning of program
;****************************************************************
reset   org 00  ;reset vector address
    goto    SetUp   ;goto SetUp


table   addwf   PCL,F           ;02h,1  add W to program counter
        retlw   b'00111111'     ; "0"   -|F|E|D|C|B|A
        retlw   b'00000110'     ; "1"   -|-|-|-|C|B|-
        retlw   b'01011011'     ; "2"   G|-|E|D|-|B|A
        retlw   b'01001111'     ; "3"   G|-|-|D|C|B|A
        retlw   b'01100110'     ; "4"   G|F|-|-|C|B|-
        retlw   b'01101101'     ; "5"   G|F|-|D|C|-|A
        retlw   b'01111101'     ; "6"   G|F|E|D|C|-|A
        retlw   b'00000111'     ; "7"   -|-|-|-|C|B|A
        retlw   b'01111111'     ; "8"   G|F|E|D|C|B|A
        retlw   b'01101111'     ; "9"   G|F|-|D|C|B|A


;****************************************************************
;* port A and B initialisation
;Button Up  and Button Down recognised when project turned on.
;****************************************************************

SetUp   bsf status,rp0
    movlw   b'00001100' ;Make RA0,1 out RA2 in(Up),RA3 in(Down)
    movwf   05h     ;trisA
    clrf    06h     ;trisB   Make all RB output
    bcf status,rp0  ;select programming area - bank0
    movlw   b'10000000' ;Turn off T0CKI, prescale for TMR0 = 1:
    movwf   option_reg
    clrf    portB       ;Clear Port B of junk
    clrf    units       ;zero the units file
    clrf    tens        ;zero the tens file
    clrf    Sw_Flag
    movlw   07h     ;turn comparators off and enable
    movwf   cmcon       ;    pins for I/O functions
    btfss   portA,2
    goto    AAA     ;Button A detected (detects LOW)
    btfsc   portA,3
    goto    Main
    clrf    Count
    goto    Random      ;Button B detected


AAA call    D_250mS
    btfsc   portA,2
    goto    Dice
    movlw   b'00000010' ;Make RA1 HIGH for left display
    movwf   portA
    movlw   b'01011110' ; "d"   G|-|E|D|C|B|-
    movwf   portB
    call    D_250mS
    movlw   b'00000110' ; "I"   -|-|-|-|C|B|-
    movwf   portB
    call    D_250mS
    movlw   b'00111001' ; "C"   -|F|E|D|-|-|A
    movwf   portB
    call    D_250mS
    movlw   b'01111001' ; "E"   G|F|E|D|-|-|A
    movwf   portB
    call    D_250mS
    clrf    portB
    goto    AAA


;****************************************************************
;* Delay 10mS       10 x 1,000uS            *
;****************************************************************

D_2mS   movlw   02h
    movwf   temp2
D_e nop
    decfsz  temp1,1
    goto    D_e
    decfsz  temp2,1
    goto    D_e
    retlw   00


D_10mS  movlw   0Ah
    movwf   temp2
D_a nop
    decfsz  temp1,1
    goto    D_a
    decfsz  temp2,1
    goto    D_a
    retlw   00


D_100mS movlw   d'100'
    movwf   temp2
D_b nop
    decfsz  temp1,1
    goto    D_b
    decfsz  temp2,1
    goto    D_b
    retlw   00

D_250mS movlw   d'250'
    movwf   temp2
D_c nop
    decfsz  temp1,1
    goto    D_c
    decfsz  temp2,1
    goto    D_c
    retlw   00


D_3Sec  movlw   d'15'
    movwf   temp3
D_d nop
    decfsz  temp1,1
    goto    D_d
    decfsz  temp2,1
    goto    D_d
    decfsz  temp3,1
    goto    D_d
    retlw   00


FastUp  btfss   Sw_Flag,2   ;First time through loop?
    goto    FU_2        ;yes
    btfsc   Sw_Flag,7   ;Has 5Hz bit been set?
    goto    FU_3
FU_1    incfsz  FastCount,1 ;Increment FastCount
    movlw   d'100'
    xorwf   FastCount,0
    btfss   status,2    ;reached 100 loops?
    retlw   00
    clrf    FastCount
    bsf Sw_Flag,7   ;set bit for 5Hz incrementing


FU_2    bsf Sw_Flag,2   ;Up button has been pressed
    incf    units,1
    movlw   0Ah     ;put 10 into w
    xorwf   units,0     ;compare units file with 10
    btfss   status,2    ;zero flag in status file. Set if units is 10
    retlw   00
    clrf    units
    incf    tens,1
    movlw   0Ah     ;put 10 into w
    xorwf   tens,0      ;compare units file with 10
    btfsc   status,2    ;zero flag in status file. Set if tens is 10
    clrf    tens
    retlw   00      ;display passes 99 but not below 0

FU_3    incfsz  FastCount,1 ;Increment FastCount
    movlw   d'5'
    xorwf   FastCount,0
    btfss   status,2    ;reached 5 loops?
    retlw   00
    clrf    FastCount
    goto    FU_2



Dwn btfsc   Sw_Flag,3
    retlw   00
    bsf Sw_Flag,3
    decf    units,1
    movlw   0FFh        ;put FFh into w
    xorwf   units,0     ;compare units file with FFh
    btfss   status,2    ;zero flag in status file. Set if units is 10
    retlw   00
    movlw   09
    movwf   units       ;put 9 into units file
    decf    tens,1
    movlw   0FFh        ;put 0FFh into w
    xorwf   tens,0      ;compare tens file with 0FFh
    btfsc   status,2    ;zero flag in status file. Set if tens is 0FFh
    goto    $+2     ;tens file is 0FFh
    retlw   00
    clrf    tens
    clrf    units
    retlw   00      ;display  not below 0


;****************************************************************
;* Dice     Produces a random number from 1 to 6 on display
;  The display flashes before settling on a number - called attract mode.
;Program detects timing of button-push to generate number       *
;****************************************************************

Dice    incf    units,f
    btfss   portA,2     ;look for button-push
    goto    Start       ;button A pushed
    movf    units,w
    xorlw   06
    btfss   status,2
    goto    Dice
    clrf    units
    goto    Dice

Start   movlw   08
    movwf   temp3
    call    Attract
    decfsz  temp3,f
    goto    $-2
    goto    Show        ;


Attract movlw   b'00000001' ;Make RA0 HIGH for right-hand display
    movwf   portA
    movlw   b'00001000' ;
    movwf   portB
    call    D_100mS
    movlw   b'01000000' ;
    movwf   portB
    call    D_100mS
    movlw   b'00001000' ;
    movwf   portB
    call    D_100mS
    movlw   b'00000001' ;
    movwf   portB
    call    D_100mS
    retlw   00

Show    movf    units,w
    call    table
    movwf   portB
Show1   call    D_250mS
    btfss   portA,2     ;look for button not pushed
    goto    Show1
    goto    Dice


;****************************************************************
;* Random - produces random numbers from 00 to 99       *
;****************************************************************

Random  movlw   08
    movwf   temp3
    call    Flash
    decfsz  temp3,f
    goto    $-2
    goto    Rand_1      ;


Flash   movlw   b'00000010' ;Make RA1 HIGH for left-hand display
    movwf   portA
    movlw   b'00001000' ;
    movwf   portB
    call    D_100mS
    movlw   b'00000001' ;Make RA0 HIGH for right-hand display
    movwf   portA
    movlw   b'00001000' ;
    movwf   portB
    call    D_100mS
    retlw   00


                ;convert Count to 0..99
Rand_1  movf    Count,w
    clrf    tens        ; W = 0x00..0x63, 0..99 input
    decf    tens,F      ; preset temp to -1
sub10   incf    tens,F      ; unconditionally
        addlw   -0Ah        ; subtract 10. borrow?
        btfsc   status,0        ; no, test carry bit
    goto    sub10
    addlw   0Ah
        movwf   units


Disp    movf    units,w
    call    table
    movwf   portB
    movlw   b'00000001' ;Make RA1 HIGH for right-hand display
    movwf   portA
    call    D_2mS
    movf    tens,w
    call    table
    movwf   portB
    movlw   b'00000010' ;Make RA1 HIGH for left-hand display
    movwf   portA
    call    D_2mS
    incf    Count,f
    movf    Count,w
    xorlw   d'100'
    btfsc   Status,2    ;test zero flag
    clrf    Count
    btfsc   portA,2     ;look for button pushed
    goto    Disp
    goto    Random


;****************************************************************
;* Main                             *
;****************************************************************

Main    btfss   portA,2     ;test switch-press for UP
    call    FastUp      ;UP switch pressed
    btfss   portA,3     ;test switch-press for Down
    call    Dwn     ;Down switch pressed
    movlw   b'00000001' ;Make RA0 HIGH for units drive
    movwf   portA
    movf    units,0     ;copy unit value into w
    call    table       ;unit display value will return in w
    movwf   portB       ;output units value
    call    D_10mS      ;call delay
    clrf    portB       ;clear display
    movlw   b'00000010' ;Make RA1 HIGH for tens drive
    movwf   portA
    movf    tens,0      ;copy tens value into w
    call    table       ;tens display value will return in w
    movwf   portB       ;output tens value
    call    D_10mS      ;call delay
    clrf    portB       ;clear display
    btfsc   portA,3     ;bit will be zero when sw is pressed
    bcf Sw_Flag,3   ;button not pressed. Clear down flag
    btfss   portA,2     ;bit will be zero when sw is pressed
    goto    Main
    bcf Sw_Flag,2   ;button not pressed. Clear Up flag
    bcf Sw_Flag,7   ;Clear Up repeat flag
    clrf    FastCount
    goto    Main

    END

Colin Mitchell

Colin Mitchell

Expertise

electronics
writing
PIC-Chips

Social Media

instagramtwitterwebsite

Related Posts

TODO
Transistor Test
© 2021, All Rights Reserved.

Quick Links

Advertise with usAbout UsContact Us

Social Media