1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Delay in [us] in C

Discussion in '8051/8951' started by rascupanamuha, Nov 26, 2012.

  1. rascupanamuha

    rascupanamuha Member

    Joined:
    Nov 4, 2012
    Messages:
    169
    Likes:
    0
    What do i need to have to make a delay of 0.001ms (1us), or at least 10us?

    I am programming in Keil, and i am using AT89C51ED2.

    Now i have only Delay() function in ms, but it is too low for me :(
     
  2. ChrisP58

    ChrisP58 Well-Known Member

    Joined:
    Apr 27, 2012
    Messages:
    1,081
    Likes:
    131
    Location:
    Provo, Utah, USA
    What clock frequency are you using? Depending on that, 1uS might be just a few instructions. So a 1uS delay would be a few no ops.

    As far as how to do that in Keil C, I can't help with that. You might get better response by posting the question in the 8051 Microcontroller forum.

    http://www.electro-tech-online.com/forums/8051-8951/
     
    Last edited: Nov 26, 2012
  3. ()blivion

    ()blivion Active Member

    Joined:
    Nov 24, 2010
    Messages:
    857
    Likes:
    210
    Location:
    Level 5
    Software delay
    The fastest you can probably make that μC run is 60Mhz in X2 mode (6 Clocks/machine cycle), where you will get 10 MIPS, or 100ns per instruction. In this mode you would need 10 instructions to make a 1us delay. This is assuming my interpretation of section 7.1 - X2 Feature of the datasheet is correct. If not, then it would only be able to run at 5 MIPS, which means you will have to make your software delay take 5 instructions. This would not be very tolerant of mistakes. But It can be done. Be aware that being off by one instruction would create as much as a 20% deviation in your frequency/period. If it were me, I would use "inline asm" and be particular to account for the extra delays caused by the call to the routine and such.

    Timer hardware/peripherals.
    The AT89C51ED2 has three timers. Timer 2 is the only one I can find information on in the datasheet. You can clock it from the system clock (CLK PERIPH), to create a 100ns~200ns time base. Or have it directly create your 1μs delay with the prescaler. Then have it interrupt every time it overflows. The problem here is that this will happen every 5~10 instructions, which will make the device practically useless for anything other than this time base. It's just about as useful as the software method, only you can run a handful of instructions between each tick.

    External clock.
    If you can get a 1Mhz xtal, you can use it to create a 1μs time base directly. 1MHz by nature is 1μs per period. This is almost no different from the above, in order to use the time base you will have to get it every 5~10 instructions, as the CPU is still clocked at the same speed.


    Bottom line
    Unless you only really need to make this precise delay happen once every so often, then you're most likely going to need a faster microcomputer. Probably something in the >100MHz range.
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. rascupanamuha

    rascupanamuha Member

    Joined:
    Nov 4, 2012
    Messages:
    169
    Likes:
    0

    Thank you !
    I have posted there, so we will see. Btw clock freq is 40MHz so uC shouldnt be a problem
     
  6. ()blivion

    ()blivion Active Member

    Joined:
    Nov 24, 2010
    Messages:
    857
    Likes:
    210
    Location:
    Level 5
    It's not 40Mhz per instruction BTW. It's 40Mhz *DIVIDED BY* 6 in x2 mode. This is because all instructions take 6 machine (clock) cycles to complete. So at 40MHz, you need 6.6[SUP]r[/SUP] instructions for every 1μs.

    !!!UNLESS!!! it is a heavily pipe-lined arch, which I don't think 8051 is.
     
    Last edited: Nov 26, 2012
  7. rascupanamuha

    rascupanamuha Member

    Joined:
    Nov 4, 2012
    Messages:
    169
    Likes:
    0
    By instructions you mean some useless code lines? Why cant i use #include <unistd.h> and usleep(x) function?

    i dont need anything precise, it is for led driving for display with 100 or more rows, so it could refresh faster than 1ms (because otherwise, it would be too slow)..
     
  8. ()blivion

    ()blivion Active Member

    Joined:
    Nov 24, 2010
    Messages:
    857
    Likes:
    210
    Location:
    Level 5
    Instructions are the smallest steps that the microcomputer takes when following your program. When you send something into a C compiler, it gets turned into these steps. They are the smallest building blocks of software. It is similar to making molecules out of atoms, or projects out of Lego's™. You can't really make code that is "smaller" in the time domain than one instruction because that is the smallest thing we can control.

    The important point is that you can't see or work with them in just C usually. A simple line of C code like "printf("Hello World!\n");" may turn into ten, or two hundred instructions. You won't know until you look at the code the compiler gives you. Usleep(x) function for example is part of and entire library and the routine it's self may take up enough instructions that it couldn't possibly be fast enough. It may take several instructions just to call the thing.


    Some times you can do this by just not using a delay at all. At some point the system it's self will have a delay just by nature that you will be waiting for, and if you are smart you can take advantage of that. If you use one instruction that is automatically a delay of 100~200ns, no routine required.

    It really depends on EXACTLY what you're doing.
     
    Last edited: Nov 26, 2012
    • Like Like x 1
  9. rascupanamuha

    rascupanamuha Member

    Joined:
    Nov 4, 2012
    Messages:
    169
    Likes:
    0
    Thank you very much. You were right !
    I did this: void A(int i) { ROW=15; COL=i; for ( k = 0; k < 50; k++);
    ROW=20; COL=i+1; for ( k = 0; k < 50; k++);
    ROW=15; COL=i+2; for ( k = 0; k < 50; k++);
    }

    So i got nice delay, and then i did this: for (i=-20; i<30; i--) {
    for (j=0; j<70; j++) {M(i);M(i+4);M(i+8);A(i+12);;}
    }
    so it could roll :)
    It is very fast, very easy, and i have very good resolution for speed now. I did this on my 8x12 matrix display, but it was also good with 1ms delay, but on 8x100 display it wouldnt be that good without this trick you showed me
     

Share This Page