Hello all,

I just finished spending the time to design a accurate delay loop for PIC chips. This is a sequential delay, and is accurate only if its not interrupted. My application for this is some chips im interfacing with on power up take long times before they are ready, as in the case of a LCD. There is other uses, but this is one.

Anyways, its not all to fantastic to marvel over, but Its still useful if you need such things:
; LCD_Delay (Timings based on fint @ 4Mhz)

; Uses EBX/EAX (High/Low byte of delay size)
; Delay size WORD value in 4uS increments or 16 clocks
; (40mS = 27h / 10h )
; (05mS = 04h / E2h )
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
LCD_Delay
movlw 0x00 ; Clear W
LCD_A0
call WaitFourClockCycles ; 1uS Delay 1000ns
decfsz EAX,f ; EAX = EAX - 1 1250ns ( 1500ns )
goto LCD_A1 ; Not Zero 1750ns
goto LCD_A2 ; Deal with EBX ( 2000ns )

LCD_A1
nop ; 2000ns
call WaitFourClockCycles ; 1uS Delay 3000ns
goto $+1 ; 2 clocks 3500ns
goto LCD_Delay ; loop back 4000ns

LCD_A2
iorwf EBX, f ; EBX = EBX (Set/Clear Z) ( 2250ns )
btfss STATUS, Z ; Skip if Zero ( 2500ns ) [ 2750ns ]
goto LCD_B1 ; Next step ( 3000ns )
; 1 clock for movlw 0x00 [ 3000ns ]
return ; [ 3500ns ]
; Initial Call to routine [ 4000ns ]

LCD_B1
nop ; wait a clock ( 3250ns )
decf EBX, f ; EBX = EBX - 1 ( 3500ns )
goto LCD_Delay ; Continue Delay ( 4000ns )

WaitFourClockCycles ; A call/return is 4 clock cycles
return


Enjoy
:alright:
:NaN:
Posted on 2004-05-02 20:50:19 by NaN
Is to use the timer. That is an interrupt and therefore has priority over main program.
Posted on 2004-05-02 21:18:12 by mrgone
Exactly, however, sometimes while handling an interrupt you want to delay... Your only option at this point is sequential delay.

Regards,
:NaN:
Posted on 2004-05-02 23:22:06 by NaN
Let the timer interrupt do the counting and even detect roll over to increment another register or in the case of the PIC, a memory location. Then the main program can poll that memory rather than sit in an idle loop. You can also have the interrupt write a second (shadow) register that can be reset or cleared. This way you can acheive known time delays to say if you want something to occure every second or half second or minute etc. You may have seen this previous post of mine. It describes how to make a software adjustable clock. There is no 32 KHz xtal or variable capacitor on the processor xtal. It uses 4MHz.
Posted on 2004-05-03 12:01:59 by mrgone
If I'm just trying to meet set up and hold times I do a simple loop like this:

380: 3020 movlw 0x20 ; number of times to loop
381: 008C movwf 0xC
382: 038C decf 0xC
383: 1D03 btfss 0x3,0x2 ; test zero flag in options reg.
384: 2B82 goto 382
385: 0008 return
Posted on 2004-05-20 21:24:41 by mrgone