ON 20050328@7:03:38 PM at page: http://piclist.com/techref/microchip/delay/xb1crnm-ng.htm#38439.7941898148 Nikolai Golovchenko [NG--944] Code:
The PIC delay routine above works correctly only if d3 and d4 are zero (the same is probably true for the SX version as well). The problem lies in how the routine is extended by adding another loop. Basically, every time a loop is appended, it adds at least 2 cycles, which must be subtracted. Sometimes, it can be done by moving the jump target by 2 nops down, but when there are no more nops, it can be done by subtracting one from d1, which subtracts 4 cycles. So d1 is decremented, a new loop adds 3 cycles and subtracts 4, which is -1 overall. So the jump should include an additional nop. The corrected PIC version is below: ; preincrement counters except d0 incf d1, f incf d2, f incf d3, f incf d4, f ; Let Delay = 0 at this point comf d0, w andlw 0x03 addwf PCL, f nop Delay2 nop Delay1 nop ; Delay = 4 + d0 Delay0 decfsz d1, f goto Delay1 ; Delay = 6 + d0 + 4 * d1 decf d1, f decfsz d2, f goto Delay2 ; Delay = 9 + d0 + 4 * (d1 + 256 * d2) decfsz d3, f goto Delay0 ; Delay = 11 + d0 + 4 * (d1 + 256 * d2 + 256^2 * d3) decf d1, f decfsz d4, f goto Delay1 ; Delay = 14 + d0 + 4 * (d1 + 256 * d2 + 256^2 * d3 + 256^3 * d4) ; This can be extended like this: ; ; decf d1, f ; decfsz d5, f ; goto Delay2 ; ; decfsz d6, f ; goto Delay0 ; ; decf d1, f ; decfsz d7, f ; goto Delay1 ; ; decf d1, f ; decfsz d8, f ; goto Delay2 ; ; decfsz d9, f ; goto Delay0