Ok I've been trying to get the code here
http://www.piclist.com/techref/piclist/cheapic/worktime.htm to work for my PIC 16f627.
I didn't change a lot just what PIC it was and which include file to use so my code is:
;-------------------------------------------------------------------------;
; WORKTIME.ASM Pushbutton toggles clock keeping track of time on LCD ;
;-------------------------------------------------------------------------;
; Note: must add additional time digit to run over 99 hrs.
LIST P=16F627 ; 16F84 Runs at 4 MHz
INCLUDE "p16f627.inc"
__CONFIG _PWRTE_ON & _LP_OSC & _WDT_OFF ; uses 32.768 kHz crystal
ERRORLEVEL -224 ; supress annoying message because of tris
; Define Information
#DEFINE RS PORTA, 0
#DEFINE E PORTA, 1
#DEFINE TOGGLESW PORTB, 4
; Macro
EStrobe MACRO ; Strobe the "E" Bit
bsf E
bcf E
ENDM
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
highlim ; high limit + 1 of digit
w_temp ; holds W during interrupt
status_temp ; holds STATUS during interrupt
fsr_temp ; holds FSR during interrupt
Dlay ; 8 Bit Delay Variable
working ; working flag 0 not working, 1 working
ptr ; used in displaying message
Temp ; a temporary variable
bin ; a temporary variable
oset ; offset of time register
oldtime ; holds last value of sec
ENDC
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'A'
;-------------------------------------------------------------------------;
; Data for message to be output ;
;-------------------------------------------------------------------------;
shomsg ; Message to Output
addwf PCL, f ; Output the Characters
dt "Working Time:", 0
;-------------------------------------------------------------------------;
; 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
movf working, f ; check working flag
btfsc STATUS, Z ; if not zero then increment time
goto restore ; else get out of interrupt routine
movlw sec ; point at sec register
movwf FSR
newdigit: incf INDF, f ; current digit up one
movlw sec ; get difference between 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
goto newdigit ; no, increment the next digit
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
;-------------------------------------------------------------------------;
; Initialize the ports ;
;-------------------------------------------------------------------------;
init:
clrf PORTA
clrf PORTB
movlw 0 ; Port A all outputs
tris PORTA
movlw B'00010000' ; RB4 input, others outputs
tris PORTB
movlw B'00000100' ; pull-ups enabled
; prescaler assigned to TMR0
; prescaler set to 1:32
; rolls over each second
option
movlw 0 ; zero out all registers
movwf hr10
movwf hr
movwf min10
movwf mins
movwf sec10
movwf sec
clrf working ; working flag to zero
movlw B'10100000' ; GIE set T0IE set, T0IF cleared
movwf INTCON
return
;-------------------------------------------------------------------------;
; Initialize the LCD ;
;-------------------------------------------------------------------------;
initlcd:
movlw D'40'
call nmsec ; Wait 40 msecs before Reset
bcf RS ; send an 8 bit instruction
movlw 0x03 ; Reset Command
call NybbleOut ; Send the Nybble
call Dlay5 ; Wait 5 msecs before Sending Again
EStrobe
nop
nop ; Wait 244 usecs before Sending the Second Time
EStrobe
nop
nop ; Wait 244 usecs before Sending the Third Time
bcf RS ; send an 8 bit instruction
movlw 0x02 ; Set 4 Bit Mode
call NybbleOut
nop
nop
movlw 0x028 ; 4 bit, 2 Line, 5x7 font
call SendINS
movlw 0x010 ; display shift off
call SendINS
movlw 0x001 ; Clear the Display RAM
call SendINS
call Dlay5 ; Note, Can take up to 4.1 msecs
movlw 0x006 ; increment cursor
call SendINS
movlw 0x00C ; display on cursor off
call SendINS
return
;-------------------------------------------------------------------------;
; Send the character in W out to the LCD ;
;-------------------------------------------------------------------------;
SendASCII
addlw '0' ; Send nbr as ASCII character
SendCHAR ; Send the Character to the LCD
movwf Temp ; Save the Temporary Value
swapf Temp, w ; Send the High Nybble
bsf RS ; RS = 1
call NybbleOut
movf Temp, w ; Send the Low Nybble
bsf RS
call NybbleOut
return
;-------------------------------------------------------------------------;
; Send an instruction in W out to the LCD ;
;-------------------------------------------------------------------------;
SendINS ; Send the Instruction to the LCD
movwf Temp ; Save the Temporary Value
swapf Temp, w ; Send the High Nybble
bcf RS ; RS = 0
call NybbleOut
movf Temp, w ; Send the Low Nybble
bcf RS
call NybbleOut
return
;-------------------------------------------------------------------------;
; Send the nibble in W out to the LCD ;
;-------------------------------------------------------------------------;
NybbleOut ; Send a Nybble to the LCD
movwf PORTB
EStrobe ; Strobe out the LCD Data
nop
nop
return
;-------------------------------------------------------------------------;
; Output the message on the LCD ;
;-------------------------------------------------------------------------;
OutMessage:
movwf FSR ; Point at first letter
OutLoop:
movf FSR, w ; Get pointer into W
incf FSR, f ; Set up for next letter
call shomsg ; Get character to output
iorlw 0 ; At the End of the Message?
btfsc STATUS, Z ; Skip if not at end
return ; Yes - Equal to Zero
call SendCHAR ; Output the ASCII Character
goto OutLoop ; Get the next character
;-------------------------------------------------------------------------;
; Wait until button is released ;
;-------------------------------------------------------------------------;
waitup:
btfss TOGGLESW ; test toggle switch
goto $ -1 ; ck again if pressed
movlw 20 ; wait 20 msec for debounce
call nmsec
btfss TOGGLESW ; check again, still up?
goto $ -4 ; no start over
return ; yes, finished
;-----------------------------------------------------------------------;
; Delay routine ;
;-----------------------------------------------------------------------;
Dlay5 movlw 5 ; delay for 5 milliseconds
nmsec: ; delay for # msec in W on entry
nop ; each nop is 0.122 milliseconds
nop
nop ; each total loop is 8 X 0.122 = 0.976 msec
nop
addlw H'FF' ; same as subtracting 1 from W
btfss STATUS, Z ; skip if result is zero
goto nmsec ; this is 2 X 0.122 msec
return ; back to calling point
;-------------------------------------------------------------------------;
; Display the Time ;
;-------------------------------------------------------------------------;
DispTime
MOVLW H'C0'
CALL SendINS
MOVF hr10, W
CALL SendASCII
MOVF hr, W
CALL SendASCII
MOVLW ":"
CALL SendCHAR
MOVF min10, W
CALL SendASCII
MOVF mins, W
CALL SendASCII
MOVLW ":"
CALL SendCHAR
MOVF sec10, W
CALL SendASCII
MOVF sec, W
CALL SendASCII
RETURN
;-------------------------------------------------------------------------;
; Toggle Work Flag ;
;-------------------------------------------------------------------------;
togglewk:
movf working, f ; set zero flag if zero
btfss STATUS, Z ; skip if working is zero
goto turnoff
incf working, f ; set working to 1
call waitup ; wait for button release
return
turnoff:
clrf working ; working set to zero
call waitup ; wait for button to be released
return
;-------------------------------------------------------------------------;
; The Main routine ;
;-------------------------------------------------------------------------;
main:
call init ; initialize ports, set up timer
call initlcd ; initialize the LCD
movlw 0 ; display 'Working Time:'
call OutMessage
ckbutton: ; check for a press of the TOGGLE button
btfss TOGGLESW ; skip if not pressed
call togglewk ; else change the mode of timer
movf oldtime, W ; is oldtime the same as sec?
subwf sec, W
btfsc STATUS, Z ; if not, skip over next instruction
goto ckbutton ; else continue checking
call DispTime ; sec has changed, display the time
movf sec, W ; make sec and oldsec the same
movwf oldtime
goto ckbutton ; and continue checking
end
I'm getting the errors as follows:
Warning[219] C:\VELLEMAN\K8048\OISIN ASM\LCD\CLOCK ONE - MODIFIED.ASM 70 : Invalid RAM location specified.
Warning[219] C:\VELLEMAN\K8048\OISIN ASM\LCD\CLOCK ONE - MODIFIED.ASM 72 : Invalid RAM location specified.
Warning[219] C:\VELLEMAN\K8048\OISIN ASM\LCD\CLOCK ONE - MODIFIED.ASM 93 : Invalid RAM location specified.
Warning[219] C:\VELLEMAN\K8048\OISIN ASM\LCD\CLOCK ONE - MODIFIED.ASM 97 : Invalid RAM location specified.
Warning[219] C:\VELLEMAN\K8048\OISIN ASM\LCD\CLOCK ONE - MODIFIED.ASM 98 : Invalid RAM location specified.
Warning[219] C:\VELLEMAN\K8048\OISIN ASM\LCD\CLOCK ONE - MODIFIED.ASM 124 : Invalid RAM location specified.
Warning[219] C:\VELLEMAN\K8048\OISIN ASM\LCD\CLOCK ONE - MODIFIED.ASM 264 : Invalid RAM location specified.
Warning[219] C:\VELLEMAN\K8048\OISIN ASM\LCD\CLOCK ONE - MODIFIED.ASM 296 : Invalid RAM location specified.
Warning[219] C:\VELLEMAN\K8048\OISIN ASM\LCD\CLOCK ONE - MODIFIED.ASM 302 : Invalid RAM location specified.
I haven't a clue how to fix this, does anyone know whats gone wrong?