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.
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
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
Quick Links
Legal Stuff
Social Media