This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

assembler macro included in C macro

l.s.,

For delay purposes I need NOP's in an assembler macro, the code below doesn't do the trick. Thread 2267.htm doesn't help me either. A C macroloop, with e.g. DELAY(a); a = 10, slows the execution down too much. Can Anyone help me?

thanks, ***

#define DELAY(a) \
{ \
volatile unsigned b; \
for(b = 0; b < a; b++) \
{ \
} \
}

#define DELAYNOP \
{ \
#pragma asm \
NOP \
NOP \
NOP \
NOP \
NOP \
NOP \
NOP \
#pragma endasm \
}

  • ***,

    The simplest form of a delay is:

    void Delay (unsigned char Cycles)
    {
       // The following generates:
       // C0001: DJNZ R7,C0001   ; 1 to 256 times
    
       while (--Cycles);
    }
    

    If you want to avoid the call use:

    #define Delay(Cycles) { while(--Cycles); }
    

    If you need a longer delay modify the function to be:

    #include <intrins.h>
    
    void Delay (unsigned char Cycles)
    {
       do {
          _nop_();  _nop_(); ...
       } while (--Cycles);
    }
    

  • 1) Use a = 9?

    2) In <intrins.h> there is an _nop_() function.

    3) The following generates a tight loop (an DJNZ instruction )

       register unsigned char i;
       i = count;
       do { --i; } while( i != 0 );
    
    
    
    

  • Hi Bob & Jon,

    Thanks. I will use the _nop_() for slowing down things. The best way for me is putting as much _nop_()'s in a C macro as I need. This results in about 500nS/_nop_() delay which is, when used 8 times, just enough for me to get it the way I want. When I used the do/while loop one decrement was as much as 14uS and not appropriate.

    baai, ***.

  • If you like, you can use assembly code to give you more control on timing issue.

    Delay100u:
    	push	DPL
    	push	DPH
            mov     DPTR, #(65535-10)
            sjmp    DelayLoop
    Delay50u:
    	push	DPL
    	push	DPH
            mov     DPTR, #(65535-5)
            sjmp    DelayLoop
    Delay20u:
    	push	DPL
    	push	DPH
    	mov	DPTR, #(65535-2)
    DelayLoop:      ;About 10uS for 12MHz
            nop
            nop
            inc     DPTR
            mov     a, DPH
            orl     a, DPL
            jnz     DelayLoop
    	pop	DPH
    	pop	DPL
            ret
    
    You can use #pragma asm/endasm to embed to your C code.

  • "If you like, you can use assembly code to give you more control on timing issue."

    If you want it to work, you MUST use assembly code - because 'C' gives you absolutely NO control on timing issues!

    "You can use #pragma asm/endasm to embed to your C code."

    Better to write a specific assembler function, in an assembler source file.
    (by all means, use ASM/ENDASM to create the outline of your function - but then throw the 'C' away and just keep it in assembler).