# Problem of delay timing, wish someone can help.^^

Status
Not open for further replies.

#### Tong

##### New Member
i stuck in timing control at PIC and wish someone can help me. Now i follow book to learn PIC microcontroller, i done many practise project already, but now i am trying to do my own project. so i use 16F877A with the keypad to set my password and show on the LCD screen. Actually the project is work, but the problem is the timing. My 16F877A IC is run too slow, because i normally use the 32768hz crystal that learn from the book, therefore now my project run too slow so i try to use 4Mhz crystal, but cant be run. Actually i know there is
the program problem, but i cant soft so wish someone can help. Below is my timing programed:

;CAN WORK!!(FOR 32768Hz Crystal, 68PF x2)

;**********************************************************************************************
;DELAY 1 SECOND
DELAY1 CLRF TMR0 ;for 32768Hz crystal:
LOOPA MOVF TMR0,W ;1/4 of 32768 = 8192
SUBLW .32 ;8192/256 =32pulse
BTFSS STATUS,ZEROBIT ;so 1 sec = 32pulse
GOTO LOOPA ;if 0.5 sec = 16pulse
RETLW 0

;DELAY 0.5 SECOND
DELAYp5 CLRF TMR0 ;START TMR0
LOOPb MOVF TMR0,W ;READ TMR0 INTO W.
SUBLW .16 ;TIME - 16
BTFSS STATUS,ZEROBIT ;check TIME-W=0
GOTO LOOPb ;TIME IS NOT=16
RETLW 0

;CANt WORK!!(FOR 4MHz Crystal, 22PF x2)

;**********************************************************************************************

;DELAY 1 SECOND
DELAY1 CLRF TMR0 ;for 4MHz crystal:
LOOPA MOVF TMR0,W ;1/4 of 4MHz = 1MHz
SUBLW .3906 ;1MHz/256 = 3906.25pulse
BTFSS STATUS,ZEROBIT ;so 1 sec = 3906pulse
GOTO LOOPA ;if 0.5 sec = 1953pulse
RETLW 0

;DELAY 0.5 SECOND
DELAYp5 CLRF TMR0
LOOPb MOVF TMR0,W
SUBLW .1953
BTFSS STATUS,ZEROBIT
GOTO LOOPb
RETLW 0

I try to look for internet information but not so understand and very tricky, and i stuck at the timing
quite long, may be my calculation is wrong...hiaz........T.T.....Wish can help..

#### AtomSoft

##### Well-Known Member
32768Hz is 1 cycle per second if im right.

4mhz clock is about 1us per cycle.

So you have to use about 1,000,000 @ 4mhz to make a 1 second delay
to make a 1/2 second (.5 second) delay in 4mhz you have to use 500,000 cycles.

You cannot delay .5 seconds if using 32768Hz as the clock.

#### ArtemisGoldfish

##### Member
32768Hz is 1 cycle per second if im right.

4mhz clock is about 1us per cycle.

So you have to use about 1,000,000 @ 4mhz to make a 1 second delay
to make a 1/2 second (.5 second) delay in 4mhz you have to use 500,000 cycles.

You cannot delay .5 seconds if using 32768Hz as the clock.
I'd say 32768Hz is 32768 cycles per second.

#### Tong

##### New Member
Thank you Jason Lopez, but can u simply write the 1 second and 0.5second delay time example of 4Mhz in ASM file, and explain some more for that. ^^ thanks alot

#### be80be

##### Well-Known Member
It tells and gives you code at the link atom posted you'll get this
Code:
; Delay = 0.5 seconds
; Clock frequency = 4 MHz

; Actual delay = 0.5 seconds = 500000 cycles
; Error = 0 %

cblock
d1
d2
d3
endc

Delay
;499994 cycles
movlw	0x03
movwf	d1
movlw	0x18
movwf	d2
movlw	0x02
movwf	d3
Delay_0
decfsz	d1, f
goto	$+2 decfsz d2, f goto$+2
decfsz	d3, f
goto	Delay_0

;2 cycles
goto	$+1 ;4 cycles (including call) return Make sure you check the box "Generate routine" Last edited: #### AtomSoft ##### Well-Known Member ArtemisGoldfish: heh that goes to show you dont drink and write lol i was thinking of a RTC and its 1hz output lol You are correct heh #### Tong ##### New Member thanks a lot, but What is the meaning of goto$+2 ?

Delay_0
decfsz d1, f
goto $+2 decfsz d2, f goto$+2
decfsz d3, f
goto Delay_0

#### gaspode42

goto

goto $= goto current line (ie loop forever) goto +2 = goto two command lines forward goto -2 = goto two lines previous It's explained in the attached #### Attachments • 2.6 MB Views: 277 Last edited: #### Tong ##### New Member Oh i see, but how to calculate this for 500000 cycles?someone know how to calculate? Delay ;499994 cycles movlw 0x03 movwf d1 movlw 0x18 movwf d2 movlw 0x02 movwf d3 Delay_0 decfsz d1, f goto$+2
decfsz d2, f
goto $+2 decfsz d3, f goto Delay_0 ;2 cycles goto$+1

;4 cycles (including call)
return

#### AtomSoft

##### Well-Known Member
it will decrease d1 until 0 then decrease d2 it will then repeat until d2 is 0 and then the whole thing repeats until d3 is 0.

Remember it goes 1.2.3.4.5.......253.254.255.0.1.2.3.4.5.6

So when counting backwards (decreasing) when a variable is decreased below 0 its 255 then 254 etc... so its a long loop

#### Tong

##### New Member
OK, but actually there is a way of calculation, because this loop i know is a long loop, so how do we calculate this loop until 500000 cycles, therefore we can change the value easily without using the delay code generator.

#### AtomSoft

##### Well-Known Member
im not sure exactly tho. You have to take account for how many cycles each instruction takes then multiply that by the amount of times each is called and poof.

i dont know 100%

#### be80be

##### Well-Known Member
Take a look at this this how C makec a delay

Code:
/*
* delays.c
*
* Various useful delay routines
*
* Mark Crosbie  9/15/98
*/

/* delay for d microseconds on a 4Mhz clock
*/
void delay_us(char d) {
char count;
char count2;

count = d;

_dmsouter:
asm	movlw D'20'
asm	movwf _count2_delay_us

_dmsinner:
asm        NOP
asm        NOP
asm	decfsz _count2_delay_us, f
asm	goto $-3 asm decfsz _count_delay_us,f asm goto$-7
}

/* delay for d milliseconds
* Trashes W
*/
void delay_ms(char d) {
char loop2;
char loop1;

loop1 = d;

_DELAY_1:
asm     MOVLW   110    ; close to 1.0 msec delay when set to .110
asm     MOVWF   _loop2_delay_ms
_DELAY_2:
asm     NOP
asm     NOP
asm     NOP
asm     NOP
asm     NOP
asm     NOP
asm     DECFSZ  _loop2_delay_ms, F   ; decrement and leave result in LOOP2
asm                             ; skip next statement if zero
asm     GOTO $-7 ; goto _DELAY_2 asm DECFSZ _loop1_delay_ms, F asm GOTO$-0xb              ; goto _DELAY_1

}

/* delay for d seconds */
void delay_s(char d) {

char i;
for(i=0; i < 10; i++) {
delay_ms(100);
}
}

#### Pommie

##### Well-Known Member
To calculate the length of the delay the equation is,

Delay = (d1 + d2 * 256 + d3 * 65536) * 7 - 460539

Mike.

#### Tong

##### New Member
Wow...Mike you are very pro in calculation, that * 7 - 460539 where u get it? is it constant value?

#### Pommie

##### Well-Known Member
Well the *7 is because there are 7 cycles in the loop, 1 decfsz and 3 gotos. The 460539 is (65536+256+1)*7-12, or 0x10101*7-12, and just compensates for the fact that a value of 1 doesn't complete a full loop. Plus a bodge (-12) for the setup code.

Mike.

#### gaspode42

##### Member

If you really want to understand it in depth its explained here

#### be80be

##### Well-Known Member
Thanks Mike for the brake down. I think myself I will stay with this Delay Code Generator
But if I have to do one by hand I saved this page in my notes