nightbird
Newbie level 1
I am student 14 years old from Thailand.I am very new in MCU. I would like to use Pic 16f628 insted of 16F84.
Here is the code. Any body help me to change the code for 16F628.
Then I will look&lern how to do. Thank you. Kob kun Krub.
;----------------------------------------------------------------------;
; BINCLK4M.ASM A clock that displays in bcd numbers ;
;----------------------------------------------------------------------;
; .-----------.
; -|RA2 RA1|- V+ = 4.5 or 5 Volts
; -|RA3 RA0|- X = 4.096 MHz xtal
; -|RA4 OSC1|--|X|-||--- gnd 20 pf caps
; -{r}- = 470 ohm V+ ---|MCLR OSC2|--|X|-||--- gnd
; -|<- = LED gnd ---|Vss Vdd|--- V+
; gnd ---|<--{r}--|RB0 RB7|-
; gnd ---|<--{r}--|RB1 RB6|-
; gnd ---|<--{r}--|RB2 RB5|---[PB]--- gnd <- SET PB
; gnd ---|<--{r}--|RB3 RB4|---[PB]--- gnd <- SHOW PB
; '-----------'
; PIC16F84 -[PB]- pushbutton
LIST P=16F84 ; tells which processor is used
INCLUDE "p16f84.inc" ; defines various registers etc. Look
ERRORLEVEL -224 ; supress annoying message from tris
__CONFIG _PWRTE_ON & _XT_OSC & _WDT_OFF ; config. switches
CBLOCK 0CH
sec ; seconds digit
sec10 ; 10's of second digit
mins ; minutes digit
min10 ; 10's of minutes digit
hr ; hours digit
hr10 ; 10's of hours digit
w_temp ; holds W during interrupt
status_temp ; holds STATUS during interrupt
fsr_temp ; holds FSR during interrupt
digit ; holds digit position
cntmsec ; used to count milliseconds
counter ; used to stretch isr out to 1 sec
flashcnt ; counter for flashing LED
ENDC
;----------------------------------------------------------------------;
; Here are some DEFINEs which give 'names' to pushbutton port bits ;
;----------------------------------------------------------------------;
#DEFINE SHOWPB PORTB, 4
#DEFINE SETPB PORTB, 5
ORG 0 ; start at location 0
goto main ; jump over to main routine
ORG 4
goto isr ; jump to interrupt routine
;----------------------------------------------------------------------;
; High limit + 1 of digits at position W ;
;----------------------------------------------------------------------;
sethi:
addwf PCL, f
dt H'A',H'6',H'A',H'6',H'A',H'3'
;----------------------------------------------------------------------;
; time delay routines ;
;----------------------------------------------------------------------;
micro4 addlw H'FF' ; subtract 1 from 'W'
btfss STATUS,Z ; skip when you reach zero
goto micro4 ; more loops
return
msec250: movlw D'250' ; delay for 250 milliseconds
;*** N millisecond delay routine ***
nmsec: movwf cntmsec ; delay for N (in W) millisec
msecloop: movlw D'248' ; 1 usec for load
call micro4 ; this instruction is 995 usec
nop ; 1 usec
decfsz cntmsec,f ; 1 usec, (2 if skip taken)
goto msecloop ; 2 usec, loop = 995+5 = 1 msec
return
;----------------------------------------------------------------------;
; Delay for one second ;
;----------------------------------------------------------------------;
onesecond: ; a subroutine that delays for 1 seconds
call msec250
call msec250
call msec250
call msec250
return
;----------------------------------------------------------------------;
; Put value in W on LEDs for 1 second ;
;----------------------------------------------------------------------;
sendnbr:
btfsc STATUS, Z ; skip if not zero
movlw H'0F' ; else all on for a zero
movwf PORTB ; light LEDs
call onesecond ; wait 1 second
clrf PORTB ; clear the LEDs
movlw D'100' ; pause for 0.1 sec
call nmsec
return
;----------------------------------------------------------------------;
; Send the current time out LEDs ;
;----------------------------------------------------------------------;
disptime:
movf hr10, W
call sendnbr
movf hr, W
call sendnbr
movf min10, W
call sendnbr
movf mins, W
call sendnbr
return
;----------------------------------------------------------------------;
; Wait until set button is released ;
;----------------------------------------------------------------------;
waitsetup: ; wait for set pushbutton up
btfss SETPB ; skip if set button released
goto waitsetup
movlw D'10'
call nmsec ; wait 10 msec for debounce
btfss SETPB ; check again for release
goto waitsetup ; false alarm, start over
return ; yes, finished
;----------------------------------------------------------------------;
; Initialization Subroutine ;
;----------------------------------------------------------------------;
init:
movlw B'0000000' ; all outputs port A
tris PORTA
movlw B'00110000' ; RB4, RB5 inputs, others outputs
tris PORTB ; on port B
movlw H'0' ; all low (off)
movwf PORTB
movlw B'00000100' ; pull-ups enabled
; prescaler assigned to TMR0
; prescaler set to 1:16
; rolls over each 1/125 th second
option
movlw 0
movwf hr10
movlw H'9' ; initialize hrs, mins and secs
movwf hr ; Do this before interrupts are
movlw H'5' ; turned on because isr also acts
movwf min10 ; on these registers
movlw H'0'
movwf mins
movwf sec10
movwf sec
movlw D'125' ; initialize isr counter
movwf counter
movlw B'10100000' ; GIE & T0IE set, T0IF cleared
movwf INTCON
return
;----------------------------------------------------------------------;
; Interrupt routine, increments time by one second (BCD) ;
;----------------------------------------------------------------------;
isr:
movwf w_temp ; save W
swapf STATUS,W ; save status
movwf status_temp ; without changing flags
swapf FSR,W ; save FSR
movwf fsr_temp ; without changing flags
decfsz counter, f ; skip on 125th time thru
goto restore ; else exit
movlw D'125' ; reset interrupt counter
movwf counter
movlw sec ; point at sec register
movwf FSR
newdigit: incf INDF, f ; current digit up one
movlw sec ; get difference sec and FSR
subwf FSR, W
call sethi ; use to get high limit + 1
subwf INDF, W ; reached that number yet?
btfss STATUS, Z ; skip over if yes
goto restore ; else exit isr
clrf INDF ; set current digit to 0
incf FSR, f ; point at next digit
btfss hr10, 1 ; has hr10 reached 2?
goto newdigit ; no, increment the next digit
btfss hr, 2 ; has hr reached 4?
goto newdigit ; no
clrf hr ; yes, set hour to 00
clrf hr10 ; and hour 10
restore:
swapf status_temp,W ; get original status back
movwf STATUS ; into status register
swapf fsr_temp,W ; get original fsr back
movwf FSR ; into status register
swapf w_temp,f ; old no flags trick again
swapf w_temp,W ; to restore W
bcf INTCON,T0IF ; clear the TMR0 interrupt flag
retfie ; finished reset GIE
;----------------------------------------------------------------------;
; Increment and display digit pointed to by FSR ;
;----------------------------------------------------------------------;
updigit:
incf INDF, f ; selected digit up one
movlw mins ; set up to subtract mins address
subwf FSR, W ; from address of current digit
call sethi ; get maximum of digit + 1 into W
subwf INDF, W ; is it = to current digit value?
btfsc STATUS, Z ; gives zero if yes, skip if no
clrf INDF ; reset value of digit to zero
movf INDF, W ; get current value and ..
movwf PORTB ; display it
call onesecond ; pause for 1 second
return
;----------------------------------------------------------------------;
; flash LED representing digit position ;
;----------------------------------------------------------------------;
setnext:
movwf digit ; save digit position
flashloop:
clrf PORTB ; all LEDs off
movf digit, W ; restore digit position
btfss flashcnt, 0 ; leave off on odd #'s of counter
movwf PORTB ; flash digit on even #'s
movlw 50 ; delay for 50 msec
call nmsec
incf flashcnt, f ; flip LSB of flashcnt
btfss SHOWPB ; skip over if SHOW not pressed
call updigit ; else increment current digit
btfsc SETPB ; skip over if set pressed
goto flashloop ; continue until pressed again
incf FSR, f ; set up for next digit
call waitsetup ; wait for release
return
;----------------------------------------------------------------------;
; Increment and set digits ;
;----------------------------------------------------------------------;
setdigits:
bcf INTCON, GIE ; no interrupts while setting time
movlw mins ; point at minutes register
movwf FSR
call waitsetup ; wait on set pushbutton up
movlw B'00000001' ; light right LED (mins)
call setnext
movlw B'00000010' ; light min10 LED
call setnext
movlw B'00000100' ; light hr LED
call setnext
movlw B'00001000' ; hr10 LED on
call setnext
clrf PORTB ; clear LEDs
bsf INTCON, GIE ; enable interrupts again
return
;----------------------------------------------------------------------;
; The main routine ;
;----------------------------------------------------------------------;
main:
call init ; set up initial conditions
loop:
btfss SHOWPB ; check for show pushbutton
call disptime ; display the time
btfss SETPB ; check for setting of time
call setdigits
goto loop ; do forever
end
; Note: A 4.096 MHz xtal is needed for accurate timing over long
; periods. You press the SHOW pushbutton to show the time, digit by
; digit. Zeros are shown as all lights on. To set the time you press
; SET. The right most digit will blink indicating minutes are to
; be set. Pressing SET again chooses tens of minutes etc. After tens
; of hours, the LEDs blank and the clock is timing again. While any
; LED is blinking, pressing SHOW will display that digit value and
; increment it every second. Release SHOW when the digit value is what
; you want.
--------------------------------------------------------------------------------
file: /techref/piclist/cheapic/binclk4m.asm, 13KB (0 imgs) in 21.14s is 0KBps, updated: 2000/12/8 12:59, local time: 2010/3/17 16:49,
TOP NEW MORE HELP FIND: 118.174.30.90:LOG IN©2010 PLEASE DON'T RIP! DO: LINK / DIGG! / MAKE!
Here is the code. Any body help me to change the code for 16F628.
Then I will look&lern how to do. Thank you. Kob kun Krub.
;----------------------------------------------------------------------;
; BINCLK4M.ASM A clock that displays in bcd numbers ;
;----------------------------------------------------------------------;
; .-----------.
; -|RA2 RA1|- V+ = 4.5 or 5 Volts
; -|RA3 RA0|- X = 4.096 MHz xtal
; -|RA4 OSC1|--|X|-||--- gnd 20 pf caps
; -{r}- = 470 ohm V+ ---|MCLR OSC2|--|X|-||--- gnd
; -|<- = LED gnd ---|Vss Vdd|--- V+
; gnd ---|<--{r}--|RB0 RB7|-
; gnd ---|<--{r}--|RB1 RB6|-
; gnd ---|<--{r}--|RB2 RB5|---[PB]--- gnd <- SET PB
; gnd ---|<--{r}--|RB3 RB4|---[PB]--- gnd <- SHOW PB
; '-----------'
; PIC16F84 -[PB]- pushbutton
LIST P=16F84 ; tells which processor is used
INCLUDE "p16f84.inc" ; defines various registers etc. Look
ERRORLEVEL -224 ; supress annoying message from tris
__CONFIG _PWRTE_ON & _XT_OSC & _WDT_OFF ; config. switches
CBLOCK 0CH
sec ; seconds digit
sec10 ; 10's of second digit
mins ; minutes digit
min10 ; 10's of minutes digit
hr ; hours digit
hr10 ; 10's of hours digit
w_temp ; holds W during interrupt
status_temp ; holds STATUS during interrupt
fsr_temp ; holds FSR during interrupt
digit ; holds digit position
cntmsec ; used to count milliseconds
counter ; used to stretch isr out to 1 sec
flashcnt ; counter for flashing LED
ENDC
;----------------------------------------------------------------------;
; Here are some DEFINEs which give 'names' to pushbutton port bits ;
;----------------------------------------------------------------------;
#DEFINE SHOWPB PORTB, 4
#DEFINE SETPB PORTB, 5
ORG 0 ; start at location 0
goto main ; jump over to main routine
ORG 4
goto isr ; jump to interrupt routine
;----------------------------------------------------------------------;
; High limit + 1 of digits at position W ;
;----------------------------------------------------------------------;
sethi:
addwf PCL, f
dt H'A',H'6',H'A',H'6',H'A',H'3'
;----------------------------------------------------------------------;
; time delay routines ;
;----------------------------------------------------------------------;
micro4 addlw H'FF' ; subtract 1 from 'W'
btfss STATUS,Z ; skip when you reach zero
goto micro4 ; more loops
return
msec250: movlw D'250' ; delay for 250 milliseconds
;*** N millisecond delay routine ***
nmsec: movwf cntmsec ; delay for N (in W) millisec
msecloop: movlw D'248' ; 1 usec for load
call micro4 ; this instruction is 995 usec
nop ; 1 usec
decfsz cntmsec,f ; 1 usec, (2 if skip taken)
goto msecloop ; 2 usec, loop = 995+5 = 1 msec
return
;----------------------------------------------------------------------;
; Delay for one second ;
;----------------------------------------------------------------------;
onesecond: ; a subroutine that delays for 1 seconds
call msec250
call msec250
call msec250
call msec250
return
;----------------------------------------------------------------------;
; Put value in W on LEDs for 1 second ;
;----------------------------------------------------------------------;
sendnbr:
btfsc STATUS, Z ; skip if not zero
movlw H'0F' ; else all on for a zero
movwf PORTB ; light LEDs
call onesecond ; wait 1 second
clrf PORTB ; clear the LEDs
movlw D'100' ; pause for 0.1 sec
call nmsec
return
;----------------------------------------------------------------------;
; Send the current time out LEDs ;
;----------------------------------------------------------------------;
disptime:
movf hr10, W
call sendnbr
movf hr, W
call sendnbr
movf min10, W
call sendnbr
movf mins, W
call sendnbr
return
;----------------------------------------------------------------------;
; Wait until set button is released ;
;----------------------------------------------------------------------;
waitsetup: ; wait for set pushbutton up
btfss SETPB ; skip if set button released
goto waitsetup
movlw D'10'
call nmsec ; wait 10 msec for debounce
btfss SETPB ; check again for release
goto waitsetup ; false alarm, start over
return ; yes, finished
;----------------------------------------------------------------------;
; Initialization Subroutine ;
;----------------------------------------------------------------------;
init:
movlw B'0000000' ; all outputs port A
tris PORTA
movlw B'00110000' ; RB4, RB5 inputs, others outputs
tris PORTB ; on port B
movlw H'0' ; all low (off)
movwf PORTB
movlw B'00000100' ; pull-ups enabled
; prescaler assigned to TMR0
; prescaler set to 1:16
; rolls over each 1/125 th second
option
movlw 0
movwf hr10
movlw H'9' ; initialize hrs, mins and secs
movwf hr ; Do this before interrupts are
movlw H'5' ; turned on because isr also acts
movwf min10 ; on these registers
movlw H'0'
movwf mins
movwf sec10
movwf sec
movlw D'125' ; initialize isr counter
movwf counter
movlw B'10100000' ; GIE & T0IE set, T0IF cleared
movwf INTCON
return
;----------------------------------------------------------------------;
; Interrupt routine, increments time by one second (BCD) ;
;----------------------------------------------------------------------;
isr:
movwf w_temp ; save W
swapf STATUS,W ; save status
movwf status_temp ; without changing flags
swapf FSR,W ; save FSR
movwf fsr_temp ; without changing flags
decfsz counter, f ; skip on 125th time thru
goto restore ; else exit
movlw D'125' ; reset interrupt counter
movwf counter
movlw sec ; point at sec register
movwf FSR
newdigit: incf INDF, f ; current digit up one
movlw sec ; get difference sec and FSR
subwf FSR, W
call sethi ; use to get high limit + 1
subwf INDF, W ; reached that number yet?
btfss STATUS, Z ; skip over if yes
goto restore ; else exit isr
clrf INDF ; set current digit to 0
incf FSR, f ; point at next digit
btfss hr10, 1 ; has hr10 reached 2?
goto newdigit ; no, increment the next digit
btfss hr, 2 ; has hr reached 4?
goto newdigit ; no
clrf hr ; yes, set hour to 00
clrf hr10 ; and hour 10
restore:
swapf status_temp,W ; get original status back
movwf STATUS ; into status register
swapf fsr_temp,W ; get original fsr back
movwf FSR ; into status register
swapf w_temp,f ; old no flags trick again
swapf w_temp,W ; to restore W
bcf INTCON,T0IF ; clear the TMR0 interrupt flag
retfie ; finished reset GIE
;----------------------------------------------------------------------;
; Increment and display digit pointed to by FSR ;
;----------------------------------------------------------------------;
updigit:
incf INDF, f ; selected digit up one
movlw mins ; set up to subtract mins address
subwf FSR, W ; from address of current digit
call sethi ; get maximum of digit + 1 into W
subwf INDF, W ; is it = to current digit value?
btfsc STATUS, Z ; gives zero if yes, skip if no
clrf INDF ; reset value of digit to zero
movf INDF, W ; get current value and ..
movwf PORTB ; display it
call onesecond ; pause for 1 second
return
;----------------------------------------------------------------------;
; flash LED representing digit position ;
;----------------------------------------------------------------------;
setnext:
movwf digit ; save digit position
flashloop:
clrf PORTB ; all LEDs off
movf digit, W ; restore digit position
btfss flashcnt, 0 ; leave off on odd #'s of counter
movwf PORTB ; flash digit on even #'s
movlw 50 ; delay for 50 msec
call nmsec
incf flashcnt, f ; flip LSB of flashcnt
btfss SHOWPB ; skip over if SHOW not pressed
call updigit ; else increment current digit
btfsc SETPB ; skip over if set pressed
goto flashloop ; continue until pressed again
incf FSR, f ; set up for next digit
call waitsetup ; wait for release
return
;----------------------------------------------------------------------;
; Increment and set digits ;
;----------------------------------------------------------------------;
setdigits:
bcf INTCON, GIE ; no interrupts while setting time
movlw mins ; point at minutes register
movwf FSR
call waitsetup ; wait on set pushbutton up
movlw B'00000001' ; light right LED (mins)
call setnext
movlw B'00000010' ; light min10 LED
call setnext
movlw B'00000100' ; light hr LED
call setnext
movlw B'00001000' ; hr10 LED on
call setnext
clrf PORTB ; clear LEDs
bsf INTCON, GIE ; enable interrupts again
return
;----------------------------------------------------------------------;
; The main routine ;
;----------------------------------------------------------------------;
main:
call init ; set up initial conditions
loop:
btfss SHOWPB ; check for show pushbutton
call disptime ; display the time
btfss SETPB ; check for setting of time
call setdigits
goto loop ; do forever
end
; Note: A 4.096 MHz xtal is needed for accurate timing over long
; periods. You press the SHOW pushbutton to show the time, digit by
; digit. Zeros are shown as all lights on. To set the time you press
; SET. The right most digit will blink indicating minutes are to
; be set. Pressing SET again chooses tens of minutes etc. After tens
; of hours, the LEDs blank and the clock is timing again. While any
; LED is blinking, pressing SHOW will display that digit value and
; increment it every second. Release SHOW when the digit value is what
; you want.
--------------------------------------------------------------------------------
file: /techref/piclist/cheapic/binclk4m.asm, 13KB (0 imgs) in 21.14s is 0KBps, updated: 2000/12/8 12:59, local time: 2010/3/17 16:49,
TOP NEW MORE HELP FIND: 118.174.30.90:LOG IN©2010 PLEASE DON'T RIP! DO: LINK / DIGG! / MAKE!