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