Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

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..
 
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.
 
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.
 
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
 
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:
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
 
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

  • MPASM.pdf
    2.6 MB · Views: 351
Last edited:
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
 
Follow the code lol
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
 
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.
 
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%
 
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);
  }
}
 
To calculate the length of the delay the equation is,

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

Mike.
 
Wow...Mike you are very pro in calculation, that * 7 - 460539 where u get it? is it constant value?
 
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.
 
Give yourself a headache!

If you really want to understand it in depth its explained
 
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
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top