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.

Delay Loop Question

Status
Not open for further replies.

Broz

New Member
I received my PicKit2 a few weeks ago and I've been playing around with it. I'm having fun and learning alot. I should be able to complete one of my projects soon. However, I have a question, and be gentle, I'm new to this. One of the tutorials that came with the kit had the following program to make an LED blink:

#include <p16F690.inc>
__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)

cblock 0x20
Delay1 ; Define two file registers for the
Delay2 ; delay loop
endc

org 0
Start:
bsf STATUS,RP0 ; select Register Page 1
bcf TRISC,0 ; make IO Pin B.0 an output
bcf STATUS,RP0 ; back to Register Page 0
MainLoop:
bsf PORTC,0 ; turn on LED C0
OndelayLoop:
decfsz Delay1,f ; Waste time.
goto OndelayLoop ; The Inner loop takes 3 instructions per loop * 256 loopss = 768 instructions
decfsz Delay2,f ; The outer loop takes and additional 3 instructions per lap * 256 loops
goto OndelayLoop ; (768+3) * 256 = 197376 instructions / 1M instructions per second = 0.197 sec.
; call it a two-tenths of a second.

bcf PORTC,0 ; Turn off LED C0
OffDelayLoop:
decfsz Delay1,f ; same delay as above
goto OffDelayLoop
decfsz Delay2,f
goto OffDelayLoop
goto MainLoop ; Do it again...
end


My question is concerning Delay1 and Delay2. No value was specified for them in the program, yet it says that the inner and outer loops occur 256 times each. Is it assumed that if no value is specified that the value will be 256? From Nigel's tutorials I know that one can specify values and change the delay, but this program doesn't do that.
 
The valure 256 is the maximum value because when you decrement zero it goes to 255 and so the decfsz instruction gets repeated 256 times. If you want to make the delay shorter then insert 2 lines before the On/OffdelayLoop line with,
Code:
	movlw	.128
	movwf	Delay2

Mike.
 
Broz said:
So if a value is not specified, it defaults to the maximum value?

It defaults to whatever happens to be in ram when it is powered on. However, once the delay has been executed, the variable Delay2 will be left at zero and so the following delays will be at the maximum value.

Mike.
 
Alright, I think I got it. So when it is powered on, it may not blink with the time advertised at first, but once it goes through one cycle, the delays go to maximum.

Thanks
 
Lets imagine that you have just powered on your PIC.

The delay variables are in volatile RAM so will be 0.

Your code performs the first decrement, so zero minus 1 equals 255 or 0xFF , remember it is a byte value so can only contain numbers from 0x00 to 0xFF.

Alternatively if one of your delay variables contained 0xFF if you were to perform an increment the contents of the variable would "roll over" to 0x00.

What your DECFSZ is doing is looking for when a decrement happens which sets the variable to 0, if the result of the decrement is 0 it sets a ZERO status flag, if DECFSZ finds this it performs the skip.

So in essence your loop program starts at 0x00, 0xFF, 0xFE, 0xFD ..... until it goes 0x1, 0x0 = at this stage the ZERO flag is set and you code takes the alternate path.

Here's a question for you, if the delay starts at 0x00 why doesnt the loop break immediately?

Good Luck

Mark
 
UTMonkey said:
Lets imagine that you have just powered on your PIC.

The delay variables are in volatile RAM so will be 0.

NO!, NO!, NO!, the GPR variables may be any value between 0 and 255, you can't assume they will be zero, and they most likely won't be.
 
UTMonkey,

As well as the error pointed out by Nigel, you have one other, the decfsz instruction does not set the zero flag in the status register. It does skip the next instruction if the result is zero but it doesn't set the zero flag. While this may seem picky, assuming things like this can cause very frustrating bugs. I know because it has caused problems for myself in the past.

Mike.
 
Nigel does a good impression of Jim Trott!

I bow to everyone elses experience.

Out of interest though, what does set the ZERO flag?
 
UTMonkey said:
Out of interest though, what does set the ZERO flag?
Look at the datasheet in the instructions, or opcodes. Each one tells you which status bits it affects.
Code:
SUBFWB Subtract f from W with Borrow
Syntax: SUBFWB f {,d {,a}}
Operands: 0 ≤ f ≤ 255
d ∈ [0,1]
a ∈ [0,1]
Operation: (W) – (f) – (C) → dest
Status Affected: N, OV, C, DC, Z
See that last line? Those are the status bits that that opcode affects.
 
Last edited:
Futz said:
Look at the datasheet in the instructions, or opcodes. Each one tells you which status bits it affects.

Or, download the **broken link removed** from Blueroomelectronics.com -- Bill has already done that for you. He has made a chart that details the 16F instruction set -- from the mnemonic to the operation, to the affected status bits and number of instruction cycles. Thanks, Bill! ;)
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top