Thanks to David Thomas, Stuart Lea, Don lekei and Eric Smith for a some
previous advice. I am still having trouble, that I can't see how to attack.
My question then, was for help about why might a PIC16C57 program work fine
on the Microchip simulator, but never on the chip.
I believe that I have properly checked:
1. that the FSR is adjusted for the right data page
2. the status flags are set for the right program page
3. FSR has been initialised properly
4. All other registers that could affect this have been checked for initialisation
5. the RTCC is not compared directly but with the value in W
6. page select bit are properly maintained;
To describe the situation.
I wanted to extend code from the ap notes for provide me with 4
general purpose timers. these were designed to count down and
then trigger a flag (and action) when they timed out. The code
is yet to be modified for decimal rather than hex, but that is
just work for later.
The problem.
The timers never time out.
analysis:
If we set the timer with a value of 5 (seconds), but XORing
with constants it has been possible to trigger LEDs to indicate
that the value is decremented.
BUT,
the timer is decremented from 5 to 4, and then next time from 4
to 3, BUT it never seems to be decremented to 2 or to 1.
Hopefully you could help by:
1. Suggestions for further analysis
2. Suggestions of what might be wrong.
I am becomeing quite frustrated - it affects my confidence in
embedded programming. There are not spurious processes that
could be messing it up (it is not a DOS program!), so I am
failing to see where the difficulty could be.
Thanks for any advice. The code is appended.
PS the watchdog is not timeing out. The chips have been tried
with it on and off. I also have the chip blinking an LED (Port A
bit 3) to ensure that it is still ticking over, and that never
stops or fails.
I am including a listing file and a source file.
------------------------------------------------------------------------------
16c5x/xx Cross-Assembler V4.14 Released Sun Jul 31 15:05:04 1994 Page 1
Line PC Opcode
0001 ; TST2.asm May 1, 1994
0002 ; modified to test PIC out and do demos. extra comments
added
0003 ; Insert BCD timers and test
0004 ; Original code from the Applications notes from Microchi
p.
0005 ;
0006 ; Gary Gaskell mods for count down timers.
0007 ;
0008 LIST P= 16C57
0009 ;
0010 ; Coding policy:
0011 ; A routine is a section of code. This defintion may be r
efined to two types
0012 ; of routines. The first is a PROCEDURE. Procedures may
be called
0013 ; using the stack of the PIC. The second is a "CODE SEQU
ENCE". This
0014 ; type of routine may not be called, only jumped/branched
to. The
0015 ; intention is to limit the likelihood to too many calls
resulting in
0016 ; an overflow on the stack.
0017 ; Level 0 This code is Base code (stack is empty)
0018 ; Level 1 Called from base code, may call another rou
tine. (stack=1)
0019 ; Displine and quality code requires that a r
eturn is
0020 ; executed.
0021 ; Level 2 Called from base or Level 1 code. The stack
is now full
0022 ; so no calls are allowed. branching only, b
ut a return
0023 ; is essential to unwind the stack.
0024 ; CONSTANTS will be in UPPERCASE, with variables in lowe
rcase.
0025 ;
0026 ;
0027 ; define equates:
0028 ;
0029 07FF PIC57 equ 7FFH
0030 ;
0031 ; external osc used = 4.096mHz. prescaler of 32 used, wh
ich gives a
0032 ; 31.25 microsec inc of the RTCC. If the rtcc is initial
ly loaded with 96
0033 ; it would overflow to 0 in 5.00ms. giving 0.00% error
0034 ; If the crystal is 4.000 Mhz (prototype Xtal), NB 4Mhz x
tal gives 1 Mhz
0035 ; internal clock. then overflow at 32usec,
0036 ; requiring 156.25 rtcc cycles, ie msecs should be 100, b
ut an error needs
0037 ; to be corrected. , Easier option is to decrease interva
l to 4 ms and to
0038 ; alter the constant for the seconds to 250 (249 actually
). NB gives
0039 ; 4000 instructions before the RTCC overflow must be caug
ht.
0040 ;
0041 ; MTICKS EQU d'96' ; for 4.096 Mhz xtal
0042 ; MTICKS EQU d'100' ; for 4.000Mhz xtal
0043 ; MTICKS equ d'131' ; for 4.000MHz xtal and
4msec overflow
0044 0001 MTICKS equ d'1' ; for testing
0045 ; Number of rttc timeouts to equal one second.
0046 ; NumRollover equ d'199'
0047 ; NumRollOver equ d'249'
0048 0001 NumRollover equ d'1' ; for testing
0049 ;
0050 ; needs fixing to right value
0051 0000 key_hit equ 0
16c5x/xx Cross-Assembler V4.14 Released Sun Jul 31 15:05:04 1994 Page 2
Line PC Opcode
0052
0053 0001 same equ 1 ; register operation sourc
e=dest
0054 0000 C EQU 0
0055 0000 BEP EQU 0
0056 0000 RTATS EQU 0
0057 0001 DC EQU 1
0058 0001 HR10 EQU 1
0059 0002 Z EQU 2
0060 0002 HR EQU 2
0061 0004 MIN EQU 4
0062 0004 FLASH EQU 4
0063 0005 PA0 EQU 5
0064 0006 PA1 EQU 6
0065 0000 F0 EQU 0
0066 0005 LEDon EQU 5 ; is set if the LED is on. bit 5 of alflag
0067 0003 led equ 3 ; bit of portA for the le
d.
0068 0005 dataP1 equ 5 ; bit 5 of FSR (sets from
DP0 to dataPg 1)
0069 ;
0070 ; Constants for timers etc
0071 ; these are set if the timer is active
0072 0000 timer1 equ 0 ; bit numbers for flag "t
imeFlag"
0073 0001 timer2 equ 1
0074 0002 timer3 equ 2
0075 0003 timer4 equ 3
0076
0077 ; these are set if the timer has finished and awa
its action
0078 0004 tmr1end equ 4
0079 0005 tmr2end equ 5
0080 0006 tmr3end equ 6
0081 0007 tmr4end equ 7
0082
0083 ; This is the number of bytes that separate the t
imer, from
0084 ; a copy of its setup values
0085 0008 OFFSET equ 8
0086
0087
0088 ;
0089 ; DEFINE RAM LOCATIONS
0090 ;
0091 0001 RTCC EQU 1
0092 0002 PC EQU 2
0093 0003 STATUS EQU 3
0094 0004 FSR EQU 4
0095 0005 PORT_A EQU 5
0096 0006 PORT_B EQU 6
0097 0007 PORT_C EQU 7
0098 ;
0099 0008 MSTMR EQU 8 ; ms timer
0100 0009 STMR EQU 9 ; sec timer
0101 ;
0102 000A MTMR EQU 0A ; min timer
16c5x/xx Cross-Assembler V4.14 Released Sun Jul 31 15:05:04 1994 Page 3
Line PC Opcode
0103 000B HTMR EQU 0B ; hour timer
0104 ;
0105 000C temp EQU 0C ;
0106 000D tmp2 EQU 0D ;
0107 ;
0108 000E timeFlag EQU 0E ; min entry
0109 000F dummy EQU 0F ; hour entry
0110 ;
0111 ; New data page : Page 0
0112 0011 tmp3 EQU 11
0113 0012 genFlag equ 12 ; general flags
0114 0013 digit equ 13
0115 0014 new_key equ 14
0116 0015 KEY_NIBL EQU 15
0117 0016 DEBOUNCE EQU 16
0118
0119 0017 MIN_SEC EQU 17 ; MIN/seconds timer
0120 ;
0121 ; PORT pin definitions
0122 ;
0123 ; Port A: s
0124 ; bit0 led to flash
0125 ; bit 1-3 unsed i/o
0126 ;
0127 ; define the RAM locations of DATA PAGE 1 (timers)
0128 ; NB to use these RAM locations (variables) the correct b
its of the
0129 ; FSR must be set (5&6).
0130 ; setup 5 timers. Each will store BCD time values and be
decremented to-
0131 ; wards zero. NB if these timers are moved the code that
works on that
0132 ; must be updated.
0133 ;
0134 ; Timers placed in Data Page 1
0135 0030 stmr1 equ 30
0136 0031 mtmr1 equ 31
0137 0032 stmr2 equ 32
0138 0033 mtmr2 equ 33
0139 0034 stmr3 equ 34
0140 0035 mtmr3 equ 35
0141 0036 stmr4 equ 36
0142 0037 mtmr4 equ 37
0143 0038 stmr1Val equ 38
0144 0039 mtmr1Val equ 39
0145 003A stmr2Val equ 3A
0146 003B mtmr2Val equ 3B
0147 003C stmr3Val equ 3C
0148 003D mtmr3Val equ 3D
0149 003E stmr4Val equ 3E
0150 003F mtmr4Val equ 3F
0151 ;
0152 ;
0153 ;
16c5x/xx Cross-Assembler V4.14 Released Sun Jul 31 15:05:04 1994 Page 4
Line PC Opcode
0154 ; *******************************************************
*********************
0155 0000 org 0
0156 START
0157 0000 0A1E goto initialise
0158 ; this routine runs a test on the leds
0159 ; all the relevent leds are lit up for 2 secs.
0160 ;
0161 test_hardware
0162 0001 0C01 movlw D'1' ; flash every two for 2 se
cs
0163 0002 0037 movwf min_sec
0164 ;
0165 ;
0166 norm_time
0167 0003 0412 bcf genFlag, 0 ; put in real time
0168 0004 0432 bcf genFlag, 1
0169 ;
0170 time_loop
0171 ; call update_display
0172 ; bsf status, PA1 ; goto page 2
0173 ; call service_keys
0174 0005 05A3 bsf status, PA0 ; goto page 1
0175 0006 0900 call update_timers ; wait and update timers
(Realtime)
Warning: [Warning 1] : line 175 : Address change across page boundary, ensure page bits are set
0176 0007 04A3 bcf status, PA0
0177 0008 0D00 iorlw 0 ;
0178 0009 0743 btfss status, Z ;
0179 000A 0A0C goto GPtime ;
0180 ; movf genFlag, w ; see if in atm
0181 ; andlw B'00000011'
0182 ; xorlw B'00000001'
0183 ; btfsc status, z ; skip if not
0184 retrn
0185 000B 0A05 goto time_loop
0186
0187 GPtime
0188 ; code sequence to call general purpose timers
0189 ; Pre: only called after a second interval has past
0190
0191 000C 05A3 bsf status, PA0 ; goto page 1
0192 000D 0975 call servTmr ; service the gen purpose
timers
Warning: [Warning 2] : line 192 : Address change across page boundary, ensure page bits are set
0193 000E 09A5 call TmrAct
Warning: [Warning 3] : line 193 : Address change across page boundary, ensure page bits are set
0194 000F 04A3 bcf status, PA0 ; reset page flags
0195 0010 0915 call ChangeState
0196 0011 0A0B goto retrn
0197
0198 on
0199 ; Level 2 routine.
0200 ; set led on, by setting it low, set in flag and at port.
0201 ; Pre:
16c5x/xx Cross-Assembler V4.14 Released Sun Jul 31 15:05:04 1994 Page 5
Line PC Opcode
0202 ; Post:
0203 0012 05B2 bsf genflag, LEDON
0204 0013 0465 bcf port_a, led
0205 0014 0800 retlw 0
0206 ;
0207 ChangeState
0208 ; Level 2 routine
0209 ; routine to change the state of the led. this is only e
ntered if the
0210 ; min_sec timer has reached zero.
0211 ;
0212 ; Pre:
0213 ; POst:
0214 ;
0215 ; reset value for blinks the led ever 2 secs
0216 0015 0C01 movlw D'01' ; 2 secs
0217 0016 0037 movwf min_sec
0218 ; check the led status on/off?
0219 0017 0212 movf genflag, w
0220 0018 0E20 andlw B'00100000'
0221 0019 0643 btfsc status, z ; if ledon is on
0222 001A 0A12 goto on ; turn it on
0223 001B 0565 bsf port_a, led ; turn it off
0224 001C 04B2 bcf genflag, ledon
0225 001D 0800 retlw 0
0226
0227
0228
0229 ;********************************************************
****************;
0230 ; This routine set up ports A, B, C and the internal
0231 ; real time clock counter.
0232 ; Level 1 routine
0233 ; Pre:
0234 ; Post: Timers have been setup.
0235 ; Ports have been setup
0236 ; The prescaler is set
0237 ;
0238 initialise
0239 001E 0064 clrf FSR
0240 001F 0C0F movlw B'00001111' ; make active high
0241 0020 0025 movwf port_a
0242 0021 0C00 movlw B'00000000' ; set port A as outputs
0243 0022 0005 tris port_a
0244 ;
0245 0023 0CFF movlw B'11111111' ; set levels high
0246 0024 0026 movwf port_b
0247 0025 0C00 movlw B'00000000' ; set portB as output
0248 0026 0006 tris port_b
0249 ;
0250 0027 0C00 movlw B'00000000' ; set levels low
0251 0028 0027 movwf port_c
0252 0029 0C00 movlw B'00000000' ; set port C as output
16c5x/xx Cross-Assembler V4.14 Released Sun Jul 31 15:05:04 1994 Page 6
Line PC Opcode
0253 002A 0007 tris port_c
0254 ;
0255 ; OPTION REG setup
0256 ; bits 7,6,5,4,3,2,1,0
0257 ; 6,7 not avail
0258 ; 5 rt source o = int, 1, edge on rtcc pin
0259 ; 4 rtcc edge l->H '0', H-->L '1'
0260 ; 3 prescaler assignment 0 rtcc, 1 wdt
0261 ; 1,2,3 ratio of prescaler '100' = 1:32
0262 ; 000 -> scale 1:2
0263 ; 111 -> scale 1:256
0264 ; NB if scale used for wdt, then ratio is 1/2 of the rtcc
scale
0265 ; movlw B'00000100' ; set up prescaler (1:32
)
0266 002B 0C00 movlw B'00000000' ; for testing
0267 002C 0002 option
0268 ;
0269 002D 0C01 movlw MTICKS ; rtcc = 5msecs
0270 ; init the rtcc with a value MTICKS, so that when it time
s out it is
0271 ; almost exactly 5msecs.
0272 002E 0021 movwf rtcc
0273 002F 0068 clrf mstmr
0274 0030 0069 clrf stmr
0275 0031 006A clrf mtmr
0276 0032 0C12 movlw 12H ; make hours = 12
0277 0033 002B movwf htmr
0278 0034 0072 clrf genFlag
0279 0035 05A3 bsf status, PA0
0280 0036 0940 call initTmr
Warning: [Warning 4] : line 280 : Address change across page boundary, ensure page bits are set
0303 ;
0304 ; This routine is called on every loop.
0305 update_timers
0306 ;
0307 ; Pre:
0308 ; Post: returns 1 in W if a 1 second interval has past
0309
0310 0200 0004 clrwdt
0311 timerLoop
0312 ; the timer loop is currently set to time out every 5ms.
NB it must be
0313 ; less than 18 ms or the watchdog may time out.
0314 0201 0000 nop ; allow time for rtcc = 0
to be available
0315 0202 0201 movf rtcc, w ; is rtcc =0
0316 0203 0743 btfss status, z ; if 0 then skip
0317 0204 0A01 goto timerLoop ; else loop
0318 ; setup real time counter again to count out the
next 5ms
0319 0205 0C01 movlw MTICKS ; rtcc = 5ms or 4ms
0320 0206 0021 movwf rtcc
0321 0207 02A8 incf mstmr ; inc 5 ms
0322 ; btfsc genFlag, key_hit ; no key hit, then sk
ip
0323 ; goto chk_de_bounce ; else debounce
0324 ;
0325 ; check to see if a second has rolled around. IE 200 x 5m
s = 1 sec
0326 ; or 250 x 4ms = 1sec
0327 0208 0208 movf mstmr, 0 ; get mstmr in W
0328 0209 0F01 xorlw NumRollOver ; if enough to equal 1 se
c then skip
0329 020A 0743 btfss status, z
0330 020B 0800 retlw 0 ; return as not a second
interval
0331 ;
0332 ; inc seconds count
0333 020C 0068 clrf MSTMR ; CLEAR ms-TMR
0334 020D 0217 movf min_sec, w ; get min_sec timer
0335 020E 0E0F andlw B'00001111' ; mask minutes
0336 020F 0743 btfss status, z ; zero then skip
0337 0210 00F7 decf min_sec
0338 0211 0C09 movlw stmr ; load fsr with s_tmr
0339 0212 0024 movwf fsr
0340 0213 0926 call inc_60 ; inc secs
0341 0214 0D00 iorlw 0 ;
0342 0215 0743 btfss status, z ;
0343 0216 0801 retlw 1 ; only a sec passed
0344 ;
0345 ; inc minutes count
0346 0217 03B7 swapf min_sec
0347 0218 0217 movf min_sec, w ; get min_sec in w
0348 0219 0E0F andlw B'00001111' ; mask seconds
0349 021A 0743 btfss status, z ; skip is not set
0350 021B 00F7 decf min_sec ; else dec
0351 021C 03B7 swapf min_sec ; swap back
0352 ; call chk_silnc_tim ; silence on?
0353 021D 0C0A movlw mtmr ; inc mins
16c5x/xx Cross-Assembler V4.14 Released Sun Jul 31 15:05:04 1994 Page 8
Line PC Opcode
0354 021E 0024 movwf fsr ;
0355 021F 0926 call inc_60
0356 0220 0D00 iorlw 0 ; do an operation
0357 0221 0743 btfss status, z ; if 0 then skip
0358 0222 0801 retlw 1 ;
0359 ;
0360 ;inc hour count
0361 ; Level ?
0362 ; Increment the hour count.
0363 0223 0C0B movlw htmr ; get htmr in fsr
0364 0224 0024 movwf fsr
0365 0225 0937 call inc_hr
0366 ;
0367 inc_60
0368 ; inc the register pointed to by the FSR modulo 60. NB B
CD is used.
0369 ; Pre: The Fsr is a timer register that is desired to be
incremented by 1
0370 ; modulo 60.
0371 ; Post: inc has occurred. If the result is 1 a inc was n
ormal. If the
0372 ; result is 0, then the tmr overflowed (=60)
0373 0226 02A0 incf f0 ; inc and get in w
0374 0227 0200 movf f0, 0
0375 0228 0E0F andlw B'00001111' ; mask high bits
0376 0229 0F0A xorlw B'00001010' ; = 10 them make it 0
0377 022A 0743 btfss status, z
0378 ; normal condition, return 1 (okay), unit digit i
ncremented
0379 022B 0801 retlw 1 ; else ret non zero
0380 022C 0CF0 movlw B'11110000' ; zero lsb
0381 022D 0160 andwf f0
0382 022E 03A0 swapf f0 ; swap indirect
0383 022F 02A0 incf f0
0384 0230 0200 movf f0,0 ; get in w
0385 0231 03A0 swapf f0 ; swap f0 back
0386 0232 0F06 xorlw D'6'
0387 0233 0743 btfss status,z
0388 ; normal condition, return 1, tens digit incremen
ted
0389 0234 0801 retlw 1
0390 ; mod 60 overflow, return 0.
0391 0235 0060 clrf f0
0392 0236 0800 retlw 0
0393 ;
0394 inc_hr
0395 ; FSR is pointing to the timer.
0396 ; i don't think that the hour timer is BCD.
0397 ; pre:
0398 ; post:
0399 0237 02A0 incf f0 ; inc hour timer
0400 0238 0200 movf f0, w
0401 ;
0402 chk_13
0403 0239 0200 movf f0, w ; get in w
0404 023A 0F12 xorlw 12h ; see if 13
16c5x/xx Cross-Assembler V4.14 Released Sun Jul 31 15:05:04 1994 Page 9
Line PC Opcode
0405 023B 0743 btfss status, z ; yes then skip
0406 023C 0000 nop
0407 023D 0801 retlw 1 ; flags that a second int
erval has past
0408 ;
0409 set_1_hr
0410 023E 0C01 movlw B'00000001' ; SET TO 1
0411 023F 0020 MOVWF f0
0412
0413 ; The general purpose timers are not affected if their va
lue is zero.
0414 ;
0415 InitTmr
0416 ; Initialise timers
0417 ; Timers can run for 255 minutes or over 4 hours.
0418 ; Procedure to initialise the general purpose timers syst
em. This will be
0419 ; by constants in the first place, but later from the NV
RAM.
0420 ; Pre: Data page is 0
0421 ; Post: Data page is 0
0422 ; Initialise the backup of the timer values. (this will
eventually
0423 ; come from the NVRAM)
0424 ;
0425 ; Set all timers to zero in the first instance.
0426 ;
0427 ; set data page to 1
0428 0240 05A4 bsf FSR, dataP1
0429 0241 006E clrf timeFlag
0430 ; move in address of first timer and then increment
the addr, clearing
0431 ; each timer as we step through the timers. Curren
tly this is the
0432 ; first 8 bytes of data page 1
0433 0242 0C30 movlw stmr1
0434 ClrLoop
0435 0243 0024 movwf fsr
0436 0244 05A4 bsf FSR, dataP1 ; maintain data page
0437 0245 0060 clrf f0 ; clears seconds part
of timer
0438 0246 02A4 incf fsr, same ; inc so to clear minu
tes part
0439 0247 0060 clrf f0 ; clears mins part
0440 ; test to see all timers are clear
0441 0248 0204 movf fsr, W
0442 0249 0F37 xorlw mtmr4
0443 024A 0E0F andlw b'00001111' ; ensure high nibble i
s clear
0444 024B 0743 btfss STATUS, Z ; = --> skip
0445 024C 0A43 goto ClrLoop
0446
0447 ; install some setup values
0448 024D 0C10 movlw 10
0449 024E 0038 movwf stmr1Val
0450
0451 024F 0C01 movlw 1
0452 0250 003A movwf stmr2Val
0453 0251 003C movwf stmr3Val
0454 0252 003E movwf stmr4Val
0455 0253 003B movwf mtmr2Val
16c5x/xx Cross-Assembler V4.14 Released Sun Jul 31 15:05:04 1994 Page 10
Line PC Opcode
0456 0254 0C02 movlw 2
0457 0255 003D movwf mtmr3Val
0458 0256 0C10 movlw 10
0459 0257 003F movwf mtmr4Val
0460 ; reset data page to 0
0461 0258 04A4 bcf FSR, DataP1
0462 0259 0800 retlw 0
0463
0464 SetTimer
0465 ; This procedure sets the timer to it's backup value
0466 ;
0467 ; Pre: W is the timer (the address of the seconds part o
f the tmr)
0468 ; Data Page is 0
0469 ; Post: The timer is set to the corresponding timer setu
p values
0470 ; Data page is 0
0471
0472 ; the offset to the setup values is currently 8 bytes hig
her than the
0473 ; timer variable locations
0474
0475 ; set to the timer data page
0476 025A 05A4 bsf FSR, dataP1
0477
0478 ; firstly transfer the seconds values
0479 ; calculate timer using the offset in W
0480 025B 002C movwf temp ; Save timer address
0481 025C 0C08 movlw OFFSET
0482 025D 01CC addwf temp, w ; calculate reg of the i
nitial value
0483 025E 0024 movwf FSR ; save this address in F
SR
0484 025F 05A4 bsf FSR, dataP1 ; maintain data page
0485 ; get timer (secs) value
0486 0260 0200 movf f0, W ; get setup value
0487 0261 002D movwf tmp2 ; save value, then get b
ack timer address
0488 0262 020C movf temp, W ; get timer address agai
n
0489 0263 0024 movwf fsr
0490 0264 05A4 bsf FSR, dataP1 ; maintain data page
0491 0265 020D movf tmp2, W
0492 0266 0020 movwf f0
0493
0494 ; Now transfer the minutes value
0495 0267 0C09 movlw OFFSET+1
0496 0268 01CC addwf temp, w ; calculate reg of the i
nitial value
0497 0269 0024 movwf FSR ; save this address in F
SR
0498 026A 05A4 bsf FSR, dataP1 ; maintain data page
0499
0500 ; get timer (mins) value
0501 026B 0200 movf f0, W
0502 026C 002D movwf tmp2 ; save value, then get b
ack timer address
0503 026D 02AC incf temp, same
0504 026E 020C movf temp, W
0505 026F 0024 movwf fsr
0506 0270 05A4 bsf FSR, dataP1
16c5x/xx Cross-Assembler V4.14 Released Sun Jul 31 15:05:04 1994 Page 11
Line PC Opcode
0507 0271 020D movf tmp2, W
0508 0272 0020 movwf f0
0509 0273 04A4 bcf FSR, dataP1 ; reset data page pointe
r
0510 0274 0800 retlw 0 ; ???
0511
0512
0513
0514 ServTmr
0515 ; Services the timers, decrementing the active timers
0516 ; Pre: Must called from main loop, as there are calls in
this routine
0517 ; Data Page is 0
0518 ; Post: Data Page is 0
0519
0520 ; testing
0521 ; bcf port_a, 2
0522 ; set to data page 1
0523 0275 05A4 bsf FSR, dataP1
0524
0525 ; get timer address in working register
0526 0276 0C30 movlw stmr1
0527
0528 ; check to see timer active
0529 0277 060E btfsc timeFlag, timer1
0530 ; if it is decrement it
0531 0278 0990 call timerDec
0532
0533 ; if the value returned in w is 1, then the timer i
s finished
0534 ; so set it's flag
0535 0279 0F01 xorlw d'1'
0536 027A 0643 btfsc status, z ;
0537 027B 058E bsf timeFlag, tmr1end ;
0538
0539 027C 0C32 movlw stmr2
0540 027D 062E btfsc timeFlag, timer2
0541 027E 0990 call timerDec
0542 ; if the value returned in w is 1, then the timer i
s finished
0543 ; so set it's flag
0544 027F 0F01 xorlw d'1'
0545 0280 0643 btfsc status, z ;
0546 0281 05AE bsf timeFlag, tmr2end ;
0547
0548 0282 0C34 movlw stmr3
0549 0283 064E btfsc timeFlag, timer3
0550 0284 0990 call timerDec
0551 ; if the value returned in w is 1, then the timer i
s finished
0552 ; so set it's flag
0553 0285 0F01 xorlw d'1'
0554 0286 0643 btfsc status, z ;
0555 0287 05CE bsf timeFlag, tmr3end ;
0556
0557 0288 0C36 movlw stmr4
16c5x/xx Cross-Assembler V4.14 Released Sun Jul 31 15:05:04 1994 Page 12
Line PC Opcode
0558 0289 066E btfsc timeFlag, timer4
0559 028A 0990 call timerDec
0560 ; if the value returned in w is 1, then the timer i
s finished
0561 ; so set it's flag
0562 028B 0F01 xorlw d'1'
0563 028C 0643 btfsc status, z ;
0564 028D 05EE bsf timeFlag, tmr4end ;
0565
0566 028E 04A4 bcf FSR, dataP1
0567 028F 0800 retlw 0
0568
0569
0570 timerDec
0571 ; Pre: W = stmr1 | stmr2 | stmr3 | stmr4 (addresses)
0572 ; the seconds are never 0, either counting down, or
0573 ; reset to 60
0574 ; post:
0575 ;
0576 ; testing
0577 ; bcf port_a, 2
0578
0579 0290 0024 movwf fsr
0580 0291 05A4 bsf FSR, dataP1 ; ensure that data pag
e remains ok
0581 0292 00E0 decf f0, same ; dec seconds, then
0582
0583 ; *******************************************************
*****************
0584 ; *******************************************************
*****************
0585 ; This is where I have found the timer not to progress.
It will light the
0586 ; LED on port A if the Xorlw is for 3 or 4 as it counts d
own, but it never
0587 ; gets to the stage where comparsion (via XOR) with 1 or
2, lights the LED.
0588 ; I take this to mean that, it never gets to the value of
1 or 2.
0589
0590 ; movf f0, w
0591 ; xorlw 4
0592 ; btfsc status, z
0593 ; bcf Port_A, 1
0594 ; xorlw 3
0595 ; btfsc status, z
0596 ; bcf Port_A, 0
0597 ; xorlw 2
0598 ; btfsc status, z
0599 ; bcf Port_A, 2
0600
0601 0293 0743 btfss status, z ; if zero dec minutes
0602 0294 0800 retlw 0
0603
0604 ZeroSecs
0605 ; The seconds have zeroed, so if no mins left end, else d
ec mins
0606 ; and set seconds to 60
0607 ; Pre: FSR is the ADDR of the seconds part of the timer
0608 ; Data page is 1
16c5x/xx Cross-Assembler V4.14 Released Sun Jul 31 15:05:04 1994 Page 13
Line PC Opcode
0609 ; Post: Data page is 1
0610 ; retlw 1 if the timer is finished
0611
0612 ; testing
0613 0295 0405 bcf Port_a, 0
0614 0296 02A4 incf FSR, same ; so to move to mins
part
0615 0297 0200 movf f0, w
0616 0298 0EFF andlw B'11111111' ; test for zero
0617 0299 0743 btfss status, z ; skip if 0
0618 029A 0A9E goto decNow ; else dec the minut
es now
0619
0620 ; testing
0621 029B 0445 bcf Port_A, 2
0622 029C 04A4 bcf FSR, dataP1
0623 029D 0801 retlw 1 ; return from timerD
ec, noting
0624 ; that the tmr is fi
nished
0625
0626 decNow
0627 ; Pre: accessed by a goto from ZeroSecs
0628 ; Post:
0629 029E 00E0 decf f0, same ; dec minutes
0630 029F 00E4 decf FSR, same ; access seconds add
ress
0631 02A0 0C60 movlw 60
0632 02A1 0020 movwf f0 ; set seconds
0633
0634 ;testing
0635 02A2 0425 bcf Port_a, 1
0636 02A3 04A4 bcf FSR, dataP1 ;
0637 02A4 0800 retlw 0 ; return from timerD
ec
0638
0639
0640
0641 TmrAct
0642 ; Take initial action if a timer is finished.
0643 ; Pre: The finshed flag for the timer is set
0644 ; Post: The finshed flag is cleared
0645 ; testing
0646 ; bcf port_a, 2
0647
0648 02A5 068E init1 btfsc timeFlag, tmr1end
0649 02A6 0AAE goto TmrAct1
0650 02A7 06AE init2 btfsc timeFlag, tmr2end
0651 02A8 0AB5 goto TmrAct2
0652 02A9 06CE init3 btfsc timeFlag, tmr3end
0653 02AA 0ABD goto TmrAct3
0654 02AB 06EE init4 btfsc timeFlag, tmr4end
0655 02AC 0AC5 goto TmrAct4
0656 02AD 0800 retlw 0 ; return from T
mrAct routine
0657 ;
0658 02AE 048E TmrAct1 bcf timeFlag, tmr1end ; clear the end
ed flag
0659 02AF 040E bcf timeFlag, timer1 ; stop timer de
crementing
16c5x/xx Cross-Assembler V4.14 Released Sun Jul 31 15:05:04 1994 Page 14
Line PC Opcode
0660 ; testing
0661 ; bcf Port_A, 2
0662 02B0 0C32 movlw stmr2
0663 02B1 095A call setTimer
0664 02B2 052E bsf timeFlag, timer2 ; activate time
r2
0665 02B3 0405 bcf port_A, 0
0666 02B4 0AA7 goto init2
0667 02B5 04AE TmrAct2 bcf timeFlag, tmr2end ; clear the end
ed flag
0668 02B6 042E bcf timeFlag, timer2 ; stop timer de
crementing
0669 02B7 0C34 movlw stmr3
0670 02B8 095A call setTimer
0671 02B9 054E bsf timeFlag, timer3 ; activate time
r3
0672 02BA 0505 bsf Port_A, 0 ; turn off prev
ious led
0673 02BB 0425 bcf Port_A, 1 ; turn on led
0674 02BC 0AA9 goto init3
0675 02BD 04CE TmrAct3 bcf timeFlag, tmr3end ; clear the end
ed flag
0676 02BE 044E bcf timeFlag, timer3 ; stop timer de
crementing
0677 02BF 0C36 movlw stmr4
0678 02C0 095A call setTimer
0679 02C1 056E bsf timeFlag, timer4 ; activate time
r4
0680 02C2 0525 bsf Port_A, 1 ; turn off prev
ious led
0681 02C3 0445 bcf Port_A, 2 ; turn on led
0682 02C4 0AAB goto init4
0683 02C5 04EE TmrAct4 bcf timeFlag, tmr4end ; clear the end
ed flag
0684 02C6 046E bcf timeFlag, timer4 ; stop timer de
crementing
0685 02C7 0545 bsf Port_A, 2 ; turn off prev
ious led
0686 02C8 0465 bcf Port_A, 3
0687 02C9 05A3 bsf status, PA0
0688 02CA 05C3 bsf status, PA1
0689 02CB 0BFF goto sys_reset
Warning: [Warning 5] : line 689 : Address change across page boundary, ensure page bits are set
0690 02CC 0800 retlw 0 ; return from T
mrAct routine
0691
0692 ;
0693 ;
0694 ; *******************************************************
*******************
0695 0000 org PIC57
0696 sys_reset
0697 07FF 0A00 goto start
Warning: [Warning 6] : line 697 : Address change across page boundary, ensure page bits are set
0698 ;
0699 0000 end
16c5x/xx Cross-Assembler V4.14 Released Sun Jul 31 15:05:04 1994 Page 15
------------------------------------------------------------------------
and the asm file
; TST2.asm May 1, 1994
; modified to test PIC out and do demos. extra comments added
; Insert BCD timers and test
; Original code from the Applications notes from Microchip.
;
; Gary Gaskell mods for count down timers.
;
LIST P= 16C57
;
; Coding policy:
; A routine is a section of code. This defintion may be refined to two types
; of routines. The first is a PROCEDURE. Procedures may be called
; using the stack of the PIC. The second is a "CODE SEQUENCE". This
; type of routine may not be called, only jumped/branched to. The
; intention is to limit the likelihood to too many calls resulting in
; an overflow on the stack.
; Level 0 This code is Base code (stack is empty)
; Level 1 Called from base code, may call another routine. (stack=1)
; Displine and quality code requires that a return is
; executed.
; Level 2 Called from base or Level 1 code. The stack is now full
; so no calls are allowed. branching only, but a return
; is essential to unwind the stack.
; CONSTANTS will be in UPPERCASE, with variables in lowercase.
;
;
; define equates:
;
PIC57 equ 7FFH
;
; external osc used = 4.096mHz. prescaler of 32 used, which gives a
; 31.25 microsec inc of the RTCC. If the rtcc is initially loaded with 96
; it would overflow to 0 in 5.00ms. giving 0.00% error
; If the crystal is 4.000 Mhz (prototype Xtal), NB 4Mhz xtal gives 1 Mhz
; internal clock. then overflow at 32usec,
; requiring 156.25 rtcc cycles, ie msecs should be 100, but an error needs
; to be corrected. , Easier option is to decrease interval to 4 ms and to
; alter the constant for the seconds to 250 (249 actually). NB gives
; 4000 instructions before the RTCC overflow must be caught.
;
; MTICKS EQU d'96' ; for 4.096 Mhz xtal
; MTICKS EQU d'100' ; for 4.000Mhz xtal
; MTICKS equ d'131' ; for 4.000MHz xtal and 4msec overflow
MTICKS equ d'1' ; for testing
; Number of rttc timeouts to equal one second.
; NumRollover equ d'199'
; NumRollOver equ d'249'
NumRollover equ d'1' ; for testing
;
; needs fixing to right value
key_hit equ 0
same equ 1 ; register operation source=dest
C EQU 0
BEP EQU 0
RTATS EQU 0
DC EQU 1
HR10 EQU 1
Z EQU 2
HR EQU 2
MIN EQU 4
FLASH EQU 4
PA0 EQU 5
PA1 EQU 6
F0 EQU 0
LEDon EQU 5 ; is set if the LED is on. bit 5 of alflag
led equ 3 ; bit of portA for the led.
dataP1 equ 5 ; bit 5 of FSR (sets from DP0 to dataPg 1)
;
; Constants for timers etc
; these are set if the timer is active
timer1 equ 0 ; bit numbers for flag "timeFlag"
timer2 equ 1
timer3 equ 2
timer4 equ 3
; these are set if the timer has finished and awaits action
tmr1end equ 4
tmr2end equ 5
tmr3end equ 6
tmr4end equ 7
; This is the number of bytes that separate the timer, from
; a copy of its setup values
OFFSET equ 8
MIN_SEC EQU 17 ; MIN/seconds timer
;
; PORT pin definitions
;
; Port A: s
; bit0 led to flash
; bit 1-3 unsed i/o
;
; define the RAM locations of DATA PAGE 1 (timers)
; NB to use these RAM locations (variables) the correct bits of the
; FSR must be set (5&6).
; setup 5 timers. Each will store BCD time values and be decremented to-
; wards zero. NB if these timers are moved the code that works on that
; must be updated.
;
; Timers placed in Data Page 1
stmr1 equ 30
mtmr1 equ 31
stmr2 equ 32
mtmr2 equ 33
stmr3 equ 34
mtmr3 equ 35
stmr4 equ 36
mtmr4 equ 37
stmr1Val equ 38
mtmr1Val equ 39
stmr2Val equ 3A
mtmr2Val equ 3B
stmr3Val equ 3C
mtmr3Val equ 3D
stmr4Val equ 3E
mtmr4Val equ 3F
;
;
;
; ****************************************************************************
org 0
START
goto initialise
; this routine runs a test on the leds
; all the relevent leds are lit up for 2 secs.
;
test_hardware
movlw D'1' ; flash every two for 2 secs
movwf min_sec
;
;
norm_time
bcf genFlag, 0 ; put in real time
bcf genFlag, 1
;
time_loop
; call update_display
; bsf status, PA1 ; goto page 2
; call service_keys
bsf status, PA0 ; goto page 1
call update_timers ; wait and update timers (Realtime)
bcf status, PA0
iorlw 0 ;
btfss status, Z ;
goto GPtime ;
; movf genFlag, w ; see if in atm
; andlw B'00000011'
; xorlw B'00000001'
; btfsc status, z ; skip if not
retrn
goto time_loop
GPtime
; code sequence to call general purpose timers
; Pre: only called after a second interval has past
bsf status, PA0 ; goto page 1
call servTmr ; service the gen purpose timers
call TmrAct
bcf status, PA0 ; reset page flags
call ChangeState
goto retrn
on
; Level 2 routine.
; set led on, by setting it low, set in flag and at port.
; Pre:
; Post:
bsf genflag, LEDON
bcf port_a, led
retlw 0
;
ChangeState
; Level 2 routine
; routine to change the state of the led. this is only entered if the
; min_sec timer has reached zero.
;
; Pre:
; POst:
;
; reset value for blinks the led ever 2 secs
movlw D'01' ; 2 secs
movwf min_sec
; check the led status on/off?
movf genflag, w
andlw B'00100000'
btfsc status, z ; if ledon is on
goto on ; turn it on
bsf port_a, led ; turn it off
bcf genflag, ledon
retlw 0
;************************************************************************;
; This routine set up ports A, B, C and the internal
; real time clock counter.
; Level 1 routine
; Pre:
; Post: Timers have been setup.
; Ports have been setup
; The prescaler is set
;
initialise
clrf FSR
movlw B'00001111' ; make active high
movwf port_a
movlw B'00000000' ; set port A as outputs
tris port_a
;
movlw B'11111111' ; set levels high
movwf port_b
movlw B'00000000' ; set portB as output
tris port_b
;
movlw B'00000000' ; set levels low
movwf port_c
movlw B'00000000' ; set port C as output
tris port_c
;
; OPTION REG setup
; bits 7,6,5,4,3,2,1,0
; 6,7 not avail
; 5 rt source o = int, 1, edge on rtcc pin
; 4 rtcc edge l->H '0', H-->L '1'
; 3 prescaler assignment 0 rtcc, 1 wdt
; 1,2,3 ratio of prescaler '100' = 1:32
; 000 -> scale 1:2
; 111 -> scale 1:256
; NB if scale used for wdt, then ratio is 1/2 of the rtcc scale
; movlw B'00000100' ; set up prescaler (1:32)
movlw B'00000000' ; for testing
option
;
movlw MTICKS ; rtcc = 5msecs
; init the rtcc with a value MTICKS, so that when it times out it is
; almost exactly 5msecs.
movwf rtcc
clrf mstmr
clrf stmr
clrf mtmr
movlw 12H ; make hours = 12
movwf htmr
clrf genFlag
bsf status, PA0
call initTmr
movlw stmr1 ; set W = timer1
; call setTimer
; testing
movlw 5
bsf fsr, DataP1
movwf stmr1
bcf fsr, DataP1
bsf timeFlag, timer1 ; activate timer
bcf status, PA0
goto test_hardware
;
;
; *************************************************************************
;
; TIMER MODULE
;
; *************************************************************************
; All routines related to timer update are located at address
; 200 and above.
;
org 200
;
; This routine is called on every loop.
update_timers
;
; Pre:
; Post: returns 1 in W if a 1 second interval has past
clrwdt
timerLoop
; the timer loop is currently set to time out every 5ms. NB it must be
; less than 18 ms or the watchdog may time out.
nop ; allow time for rtcc = 0 to be available
movf rtcc, w ; is rtcc =0
btfss status, z ; if 0 then skip
goto timerLoop ; else loop
; setup real time counter again to count out the next 5ms
movlw MTICKS ; rtcc = 5ms or 4ms
movwf rtcc
incf mstmr ; inc 5 ms
; btfsc genFlag, key_hit ; no key hit, then skip
; goto chk_de_bounce ; else debounce
;
; check to see if a second has rolled around. IE 200 x 5ms = 1 sec
; or 250 x 4ms = 1sec
movf mstmr, 0 ; get mstmr in W
xorlw NumRollOver ; if enough to equal 1 sec then skip
btfss status, z
retlw 0 ; return as not a second interval
;
; inc seconds count
clrf MSTMR ; CLEAR ms-TMR
movf min_sec, w ; get min_sec timer
andlw B'00001111' ; mask minutes
btfss status, z ; zero then skip
decf min_sec
movlw stmr ; load fsr with s_tmr
movwf fsr
call inc_60 ; inc secs
iorlw 0 ;
btfss status, z ;
retlw 1 ; only a sec passed
;
; inc minutes count
swapf min_sec
movf min_sec, w ; get min_sec in w
andlw B'00001111' ; mask seconds
btfss status, z ; skip is not set
decf min_sec ; else dec
swapf min_sec ; swap back
; call chk_silnc_tim ; silence on?
movlw mtmr ; inc mins
movwf fsr ;
call inc_60
iorlw 0 ; do an operation
btfss status, z ; if 0 then skip
retlw 1 ;
;
;inc hour count
; Level ?
; Increment the hour count.
movlw htmr ; get htmr in fsr
movwf fsr
call inc_hr
;
inc_60
; inc the register pointed to by the FSR modulo 60. NB BCD is used.
; Pre: The Fsr is a timer register that is desired to be incremented by 1
; modulo 60.
; Post: inc has occurred. If the result is 1 a inc was normal. If the
; result is 0, then the tmr overflowed (=60)
incf f0 ; inc and get in w
movf f0, 0
andlw B'00001111' ; mask high bits
xorlw B'00001010' ; = 10 them make it 0
btfss status, z
; normal condition, return 1 (okay), unit digit incremented
retlw 1 ; else ret non zero
movlw B'11110000' ; zero lsb
andwf f0
swapf f0 ; swap indirect
incf f0
movf f0,0 ; get in w
swapf f0 ; swap f0 back
xorlw D'6'
btfss status,z
; normal condition, return 1, tens digit incremented
retlw 1
; mod 60 overflow, return 0.
clrf f0
retlw 0
;
inc_hr
; FSR is pointing to the timer.
; i don't think that the hour timer is BCD.
; pre:
; post:
incf f0 ; inc hour timer
movf f0, w
;
chk_13
movf f0, w ; get in w
xorlw 12h ; see if 13
btfss status, z ; yes then skip
nop
retlw 1 ; flags that a second interval has past
;
set_1_hr
movlw B'00000001' ; SET TO 1
MOVWF f0
; The general purpose timers are not affected if their value is zero.
;
InitTmr
; Initialise timers
; Timers can run for 255 minutes or over 4 hours.
; Procedure to initialise the general purpose timers system. This will be
; by constants in the first place, but later from the NV RAM.
; Pre: Data page is 0
; Post: Data page is 0
; Initialise the backup of the timer values. (this will eventually
; come from the NVRAM)
;
; Set all timers to zero in the first instance.
;
; set data page to 1
bsf FSR, dataP1
clrf timeFlag
; move in address of first timer and then increment the addr, clearing
; each timer as we step through the timers. Currently this is the
; first 8 bytes of data page 1
movlw stmr1
ClrLoop
movwf fsr
bsf FSR, dataP1 ; maintain data page
clrf f0 ; clears seconds part of timer
incf fsr, same ; inc so to clear minutes part
clrf f0 ; clears mins part
; test to see all timers are clear
movf fsr, W
xorlw mtmr4
andlw b'00001111' ; ensure high nibble is clear
btfss STATUS, Z ; = --> skip
goto ClrLoop
; install some setup values
movlw 10
movwf stmr1Val
SetTimer
; This procedure sets the timer to it's backup value
;
; Pre: W is the timer (the address of the seconds part of the tmr)
; Data Page is 0
; Post: The timer is set to the corresponding timer setup values
; Data page is 0
; the offset to the setup values is currently 8 bytes higher than the
; timer variable locations
; set to the timer data page
bsf FSR, dataP1
; firstly transfer the seconds values
; calculate timer using the offset in W
movwf temp ; Save timer address
movlw OFFSET
addwf temp, w ; calculate reg of the initial value
movwf FSR ; save this address in FSR
bsf FSR, dataP1 ; maintain data page
; get timer (secs) value
movf f0, W ; get setup value
movwf tmp2 ; save value, then get back timer address
movf temp, W ; get timer address again
movwf fsr
bsf FSR, dataP1 ; maintain data page
movf tmp2, W
movwf f0
; Now transfer the minutes value
movlw OFFSET+1
addwf temp, w ; calculate reg of the initial value
movwf FSR ; save this address in FSR
bsf FSR, dataP1 ; maintain data page
; get timer (mins) value
movf f0, W
movwf tmp2 ; save value, then get back timer address
incf temp, same
movf temp, W
movwf fsr
bsf FSR, dataP1
movf tmp2, W
movwf f0
bcf FSR, dataP1 ; reset data page pointer
retlw 0 ; ???
ServTmr
; Services the timers, decrementing the active timers
; Pre: Must called from main loop, as there are calls in this routine
; Data Page is 0
; Post: Data Page is 0
; testing
; bcf port_a, 2
; set to data page 1
bsf FSR, dataP1
; get timer address in working register
movlw stmr1
; check to see timer active
btfsc timeFlag, timer1
; if it is decrement it
call timerDec
; if the value returned in w is 1, then the timer is finished
; so set it's flag
xorlw d'1'
btfsc status, z ;
bsf timeFlag, tmr1end ;
movlw stmr2
btfsc timeFlag, timer2
call timerDec
; if the value returned in w is 1, then the timer is finished
; so set it's flag
xorlw d'1'
btfsc status, z ;
bsf timeFlag, tmr2end ;
movlw stmr3
btfsc timeFlag, timer3
call timerDec
; if the value returned in w is 1, then the timer is finished
; so set it's flag
xorlw d'1'
btfsc status, z ;
bsf timeFlag, tmr3end ;
movlw stmr4
btfsc timeFlag, timer4
call timerDec
; if the value returned in w is 1, then the timer is finished
; so set it's flag
xorlw d'1'
btfsc status, z ;
bsf timeFlag, tmr4end ;
bcf FSR, dataP1
retlw 0
timerDec
; Pre: W = stmr1 | stmr2 | stmr3 | stmr4 (addresses)
; the seconds are never 0, either counting down, or
; reset to 60
; post:
;
; testing
; bcf port_a, 2
movwf fsr
bsf FSR, dataP1 ; ensure that data page remains ok
decf f0, same ; dec seconds, then
; ************************************************************************
; ************************************************************************
; This is where I have found the timer not to progress. It will light the
; LED on port A if the Xorlw is for 3 or 4 as it counts down, but it never
; gets to the stage where comparsion (via XOR) with 1 or 2, lights the LED.
; I take this to mean that, it never gets to the value of 1 or 2.
; movf f0, w
; xorlw 4
; btfsc status, z
; bcf Port_A, 1
; xorlw 3
; btfsc status, z
; bcf Port_A, 0
; xorlw 2
; btfsc status, z
; bcf Port_A, 2
btfss status, z ; if zero dec minutes
retlw 0
ZeroSecs
; The seconds have zeroed, so if no mins left end, else dec mins
; and set seconds to 60
; Pre: FSR is the ADDR of the seconds part of the timer
; Data page is 1
; Post: Data page is 1
; retlw 1 if the timer is finished
; testing
bcf Port_a, 0
incf FSR, same ; so to move to mins part
movf f0, w
andlw B'11111111' ; test for zero
btfss status, z ; skip if 0
goto decNow ; else dec the minutes now
; testing
bcf Port_A, 2
bcf FSR, dataP1
retlw 1 ; return from timerDec, noting
; that the tmr is finished
decNow
; Pre: accessed by a goto from ZeroSecs
; Post:
decf f0, same ; dec minutes
decf FSR, same ; access seconds address
movlw 60
movwf f0 ; set seconds
TmrAct
; Take initial action if a timer is finished.
; Pre: The finshed flag for the timer is set
; Post: The finshed flag is cleared
; testing
; bcf port_a, 2
init1 btfsc timeFlag, tmr1end
goto TmrAct1
init2 btfsc timeFlag, tmr2end
goto TmrAct2
init3 btfsc timeFlag, tmr3end
goto TmrAct3
init4 btfsc timeFlag, tmr4end
goto TmrAct4
retlw 0 ; return from TmrAct routine
;
TmrAct1 bcf timeFlag, tmr1end ; clear the ended flag
bcf timeFlag, timer1 ; stop timer decrementing
; testing
; bcf Port_A, 2
movlw stmr2
call setTimer
bsf timeFlag, timer2 ; activate timer2
bcf port_A, 0
goto init2
TmrAct2 bcf timeFlag, tmr2end ; clear the ended flag
bcf timeFlag, timer2 ; stop timer decrementing
movlw stmr3
call setTimer
bsf timeFlag, timer3 ; activate timer3
bsf Port_A, 0 ; turn off previous led
bcf Port_A, 1 ; turn on led
goto init3
TmrAct3 bcf timeFlag, tmr3end ; clear the ended flag
bcf timeFlag, timer3 ; stop timer decrementing
movlw stmr4
call setTimer
bsf timeFlag, timer4 ; activate timer4
bsf Port_A, 1 ; turn off previous led
bcf Port_A, 2 ; turn on led
goto init4
TmrAct4 bcf timeFlag, tmr4end ; clear the ended flag
bcf timeFlag, timer4 ; stop timer decrementing
bsf Port_A, 2 ; turn off previous led
bcf Port_A, 3
bsf status, PA0
bsf status, PA1
goto sys_reset
retlw 0 ; return from TmrAct routine
I didn't read all of your code & have not used the 57 ( I am using the '71)
but I did check the '57 op-codes. A movf RTCC to W will set the Z flag but
will also clear the prescaler. Could this tie in with your troubles, or have
you allowed for it?
> There may be more to it that this, but a quick look shows that you are
> moving RTCC into W and then expecting the Z bit in the status register
> to indicate the zero or nonzero status of the RTCC. I don't think the
> movf instruction affects the Z bit, so try adding a specific test.
>
> David
The Microchip data pages say that movf does set the Z bit. Besides the
seconds timing seems to working fine. A LED i have blinking is regular
and never fails.
> I didn't read all of your code & have not used the 57 ( I am using the '71)
> but I did check the '57 op-codes. A movf RTCC to W will set the Z flag but
> will also clear the prescaler. Could this tie in with your troubles, or have
> you allowed for it?
>
> Good luck,
> Brian
Brian, I thought you may have hit the problem, but it does not appear
so. Firstly if the movf RTCC, w did change the prescaler, then the
whole time would be out (and my LED blinking each second would not be
operational). I did try resetting the prescaler after each operation
with the RTCC, but this gave not change.
The Microchip data page is confusing. It talks in note 4 of the
instruction table, about the prescaler being reset, but is ambiguous. (to
me atleast)