Here's the delay code from the very good tutorials over at winpicprog.co.uk [specifically tutorial 1 ]:
I wanted to figure out how this worked, so I added up all the cycle counts for the instructions. The problem is that I don't think the number of cycles adds up to exactly 250000.
The initialisation (the MOVLW's and MOVWF's) requires 6 cycles. For the first 249 iterations of count1, we have:
0xC6 = 198 times a decfsz non-skip (1) and two goto's (4) = 990
plus one decfsz skip (2), a decfsz skip (2) [when countb is decremented, it becomes zero straight away], a decfsz non-skip [decrementing count1] (1), a goto (2) and four more initialisation cycles.
That's a total of 1001 cycles, meaning 249249 altogether. The last iteration gives us:
again 990 cycles
then 2, 2, decfsz skip (2), retlw (2) = 998 cycles.
Hence the entire routine takes 250253 cycles altogether - quite a large amount too many! Not to mention that the intial "call" procedure takes another 2 cycles to start with. I know that the code probably isn't meant to be 100% precise, but I had a go to see if it was possible to make an exact 250000 cycle routine [without a whole load of "nop"s ].
OK, so I didn't manage to avoid nop's completely, but...
I changed the 0xC7 to a 0xC5, so for the first 249 iterations we now get 196 lots of decfsz + goto + goto for 980, then decfsz skip + goto + nop + decfsz + goto + [pre_ret]8 nops + goto[/pre_ret] + 2 more initialisation cycles which should make 20 (total 1000).
On the last iteration we get 980, then decfsz skip, goto, nop, decfsz skip, nop, retlw which is 10. That's 249990 altogether; the last 10 instructions come from the initial call (2 cycles), then 4 nop's and 4 initialisation lines.
I'm completely new to PICs (not to programming though), so I've no idea if a 16F628's processor is precise enough for this effort to be even worth it! Still, let me know what you think.
ahydra
Code:
Delay movlw d'250' ;delay 250 ms (4 MHz clock)
movwf count1
d1 movlw 0xC7
movwf counta
movlw 0x01
movwf countb
Delay_0
decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1 ,f
goto d1
retlw 0x00
I wanted to figure out how this worked, so I added up all the cycle counts for the instructions. The problem is that I don't think the number of cycles adds up to exactly 250000.
The initialisation (the MOVLW's and MOVWF's) requires 6 cycles. For the first 249 iterations of count1, we have:
0xC6 = 198 times a decfsz non-skip (1) and two goto's (4) = 990
plus one decfsz skip (2), a decfsz skip (2) [when countb is decremented, it becomes zero straight away], a decfsz non-skip [decrementing count1] (1), a goto (2) and four more initialisation cycles.
That's a total of 1001 cycles, meaning 249249 altogether. The last iteration gives us:
again 990 cycles
then 2, 2, decfsz skip (2), retlw (2) = 998 cycles.
Hence the entire routine takes 250253 cycles altogether - quite a large amount too many! Not to mention that the intial "call" procedure takes another 2 cycles to start with. I know that the code probably isn't meant to be 100% precise, but I had a go to see if it was possible to make an exact 250000 cycle routine [without a whole load of "nop"s ].
OK, so I didn't manage to avoid nop's completely, but...
Code:
Delay nop ; 2 cycles to call, plus initialisation delay of 4 + 4
nop
nop
nop
movlw d'250' ; delay 250 ms (4 MHz clock)
movwf count1
d1 movlw 0xC5
movwf counta
Delay_0
decfsz counta, f
goto $+2 ; delay 2 cycles
goto Delay_1
goto Delay_0
Delay_1
nop ; delay 1 cycle
decfsz count1 ,f
goto pre_ret
nop ; delay 1 cycle
retlw 0x00
pre_ret
nop ; delay 10 cycles
nop
nop
nop
nop
nop
nop
nop
goto d1
I changed the 0xC7 to a 0xC5, so for the first 249 iterations we now get 196 lots of decfsz + goto + goto for 980, then decfsz skip + goto + nop + decfsz + goto + [pre_ret]8 nops + goto[/pre_ret] + 2 more initialisation cycles which should make 20 (total 1000).
On the last iteration we get 980, then decfsz skip, goto, nop, decfsz skip, nop, retlw which is 10. That's 249990 altogether; the last 10 instructions come from the initial call (2 cycles), then 4 nop's and 4 initialisation lines.
I'm completely new to PICs (not to programming though), so I've no idea if a 16F628's processor is precise enough for this effort to be even worth it! Still, let me know what you think.
ahydra