Home


2 Digit Up/Down Counter with PIC12F628
and prototype PC board $25.00 plus $5.00 postage.
To order the kit,  send an email to us and we will reply with the details of how to order etc.

P1 2 digit Up/Down Counter using PIC16F628
P2 
adding Dice and Random Number (PIC16F628)
P3 
2 digit Up/Down Counter using PIC12F629
P4
  adding RF Link to PIC12F629 version
P5
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.
Dice.asm
Dice.txt (asm)
Dice.hex
Dice-h.txt (.hex)
 

;****************************************************************
;*     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:

UpDwnDiceRandom.asm
UpDwnDiceRandom.hex
UpDwnDiceRandom.txt
UpDwnDiceRandom-h.txt

;****************************************************************
;*     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
	

 

P1   P2  P3  P4(RF Link) P5
 

 


  20/6/09