Search code examples
embeddedkeilc51

Keil C51: Dead Loop in Custom Delay Function (STC89C52RC)


I'm trying to write a simple delay function. It takes two arguments: a pointer to a void function and an unsigned integer (unsigned int) specifying how many times the function should be executed. However, I'm encountering a dead loop, preventing the code after the function call from executing.

void delay(void (*func)(void), unsigned int time) {
    unsigned int i, j;
    for (i = 0; i < time; i++) {
        func();
        for (j = 0; j < 10000; j++);
    }
}

In an attempt to avoid using functions, I implemented the following code:

void main() {
    unsigned int i, j;
    for (i = 0; i < time; i++) {
        for (j = 0; j < 10000; j++);
        func();
    }
    // other codes to be executed
}

I was surprised to find that this code avoids the dead loop I encountered previously. I'm confused about this. Maybe it has something to do with the function pointer? (The complier is Keil C51)


Solution

  • Keil supports the __nop() function that does nothing but isn't optimized out by the compiler. So you might write a delay function like this:

    void delay(unsigned int time)
    {
        while(time--)
        {
            __nop();
        }
    }
    

    If for some reason your compiler doesn't have __nop(), you can also do the following to generate a proper NOP in Keil C51.

    #pragma asm
        NOP
    #pragma endasm
    

    Of course it would be better to use a hardware timer to get a precise delay. But if you just want "some" dealy the above should be fine.