I tried to small program to see the code produced by the compiler.
This is the C code: unsigned char loop;
while (1) {
P3 = 0xFF;
for(loop=0xff; loop>0; loop--) {}
P3 = 0x00;
}
This is the disassembly:
25: unsigned char loop;
26:
27: while (1) {
28:
29: P3 = 0xFF;
C:0x0800 75B0FF MOV P3(0xB0),#0xFF
30: for(loop=0xff; loop>0; loop--) {}
C:0x0803 7FFF MOV R7,#0xFF
C:0x0805 DFFE DJNZ R7,C:0805
31: P3 = 0x00;
C:0x0807 E4 CLR A
C:0x0808 F5B0 MOV P3(0xB0),A
32: for(loop=0xff; loop>0; loop--) {}
C:0x080A 7FFF MOV R7,#0xFF
C:0x080C EF MOV A,R7
C:0x080D D3 SETB C
C:0x080E 9400 SUBB A,#0x00
C:0x0810 40EE JC main(C:0800)
C:0x0812 1F DEC R7
C:0x0813 80F7 SJMP C:080C
C:0x0815 787F MOV R0,#0x7F
C:0x0817 E4 CLR A
C:0x0818 F6 MOV @R0,A
C:0x0819 D8FD DJNZ R0,C:0818
C:0x081B 758107 MOV SP(0x81),#0x07
C:0x081E 020800 LJMP main(C:0800)
Why is the second timing loop so different than the first ??
What can I do so both are the same ???
Thank you
Donald
Since those loops have no side effects, the optimizer would be justified in removing them entirely. (What optimization level are you using?)
Much of the tail end of the code looks like initialization. 0815..081E zeroes data space and jumps to main to restart the code. The second loop body also looks like it jumps to main when the loop is done. Keil usually adds some code at the end of main to restart if you should fall out of main. But you've got a while(1), so that code seems a bit strange to me.
As Andy says, you can't count on any particular pattern of code generation from C (or any other language). That's what assembler is for.
For the delays, you could write a busy loop in assembler to control the cycle count, which parameter is a measure of the amount of time you want to loop. You could also use a hardware timer, and spin waiting for the timer to expire.