Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

PIC Delays. Where to put the labels?

Status
Not open for further replies.
Joined
Dec 4, 2012
Messages
4,280
Helped
822
Reputation
1,654
Reaction score
791
Trophy points
1,393
Location
Bangalore, India
Activity points
0
I am posting a delay code generated at

I see goto $+1 and $+2 instructions but I don't see $+1 and $+2 labels. Can anyone tell me where to put the labels. I want $+1 and $+2 to be replaced by loop1 and loop2 labels.


Code ASM - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
; Delay = 1 seconds
; Clock frequency = 20 MHz
 
; Actual delay = 1 seconds = 5000000 cycles
; Error = 0 %
 
        cblock
        d1
        d2
        d3
        endc
 
Delay
                        ;4999993 cycles
        movlw   0x2C
        movwf   d1
        movlw   0xE7
        movwf   d2
        movlw   0x0B
        movwf   d3
Delay_0
        decfsz  d1, f
        goto    $+2
        decfsz  d2, f
        goto    $+2
        decfsz  d3, f
        goto    Delay_0
 
                        ;3 cycles
        goto    $+1
        nop
 
                        ;4 cycles (including call)
        return




Edit: I came to know that $+2 stands for jump to two instructions below and $+1 stands for jump to one instruction below. So Is my new code right?


Code ASM - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
; Delay = 1 seconds
; Clock frequency = 20 MHz
 
; Actual delay = 1 seconds = 5000000 cycles
; Error = 0 %
 
        cblock
        d1
        d2
        d3
        endc
 
Delay
                        ;4999993 cycles
        movlw   0x2C
        movwf   d1
        movlw   0xE7
        movwf   d2
        movlw   0x0B
        movwf   d3
Delay_0
                decfsz  d1, f
                goto    loop2
                decfsz  d2, f
loop2:  goto    loop2
                decfsz  d3, f
                goto    Delay_0
 
                        ;3 cycles
                goto    loop1
loop1:  nop
 
                        ;4 cycles (including call)
        return

 
Last edited:

Loop1 isn't a loop, so "goto loop1" and "loop1: nop" are confusing. They aren't needed. If you need to burn some clock cycles, just put in a number of "nop" instructions or use a number of "goto $+1" instructions.

And, yes, the "$" means the current program counter, so "$+1" is the next instruction.
 

But my loop2: goto loop2 will create a endless loop. How to fix that?

Edit: I got it. It's like this.

Code ASM - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
; Delay = 1 seconds
; Clock frequency = 20 MHz
 
; Actual delay = 1 seconds = 5000000 cycles
; Error = 0 %
 
        cblock
        d1
        d2
        d3
        endc
 
Delay
                        ;4999993 cycles
        movlw   0x2C
        movwf   d1
        movlw   0xE7
        movwf   d2
        movlw   0x0B
        movwf   d3
Delay_0
                decfsz  d1, f
                goto    label1
                decfsz  d2, f
label1: goto    label2
                decfsz  d3, f
label2: goto    Delay_0
 
                        ;3 cycles
                goto    label3
label3: nop
 
                        ;4 cycles (including call)
                return

 
Last edited:

Please don't use $+ and $- without specifying the type of processor as it can cause serious problems. The '$' means "the present program counter value" so the addition or subtraction moves execution forward or backward by the number provided. Some instructions can be single address and some two addresses so it is possible to 'jump' to an inapropriate location and also the code is no longer portable between devices. It is always better to use a label as the target for a jump, even if it is on the next or previous line, this lets the assembler work out how far the jump should be and produce the correct code every time.

Brian.
 
The software delay principle is to run one loop inside another and to return to the beginning of the first loop each time. This gives a delay of A*B*C... where A,B and C are the values used in each loop. There is a small overhead caused by the check to see if the loop has completed and you have to be careful because a repeating loop will assume a count of 255 (0xFF) unless you re-load it with it's start value each time.

So the loop should be contructed like this:
Code:
	cblock
d1
d2
d3
	endc
 
Delay
	movlw   0x2C
	movwf   d1	
	movlw   0xE7
	movwf   d2
	movlw   0x0B
	movwf   d3
Delay_0
	decfsz  d1, f
	goto    Delay_0
	decfsz  d2, f
	goto	Delay_0
	decfsz  d3, f
	goto	Delay_0
        return

so 'd1' is counted down to zero 'd2' times and 'd2' is counted down to zero 'd3' times.
Incidentally, you should add an address to the cblock declaration.

Brian.
 

Hi,

It looks like you got your delay routine from the golovchenko.org/cgi-bin/delay site which always seems good to me.

However its always best to run your code in MPLABS SIM using the STOPWATCH function.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top