Topic : Optimization issue with delay loops

Forum : 8051

Original Post
Post Information Post
February 24, 2010 - 11:56pm
Guest

i'm teaching students in asm and C.
For many beginner's projects i use delay-loops for timing. No problems with calculation while using asm.
But the optimizer in C sometimes behaves strange. (BN-761)
For example:

unsigned char time;
while(1){
for(time=200;time!=0;time--){}
P2++;
}
i would expect a djnz-loop with ~400us (@12MHz).
Depending on Compiler-Settings and space-qualifiers for time i get most unexpected results.
- the for-loop is removed completely (optimizer Speed Level 1-7 or Size doesn't matter)
- Changing the declaration of time to 'volatile unsigned char' results in
mov time,#C8
mov time,#0 // ??????????
- Changing the declaration to 'data unsigned char' results in the same 2 asm operations.

- Changing it to idata leaves the loop in the code:
mov R1, #0F
mov @R1,#C8
mov R1,#0F // why that? R1 wasn't changed!
dec @R1 // counting - uff
mov a,@R1
jz target

- adding one _nop_() to the loop: for (time=200;time!=0;time--){_nop_();}
gives the expected djnz-loop (now 3 machine-cycles per loop)
mov time,#C8
nop
djnz time,002A

so, which is the preferred way to declare reliable delay-loops in C?

regards
B. Spitzer

Replies
Post Information Post
+1
0
-1
February 25, 2010 - 9:59am
Guest

Adding the _nop_() is the best solution. At least, it forces the body of the loop. However, it does not specify how the 'frame' of the loop will be built. For sure, it could depends on the complier settings (and -at least- on the compiler itself). But such a simple loop will probably stay unchanged in the future versions of the compiler. Thus, it could work..
Now, the best way to implement a delay is, for sure, programming a timer!

+1
0
-1
February 25, 2010 - 10:32am
Guest

>> Now, the best way to implement a delay is, for sure, programming a timer!
makes things more complicated for beginners (learn timers first) and is sometimes impossible if all timers are used.

regards
B. Spitzer