Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[51] Help : Delay in STC89C52 Micro controller

ahmar123

Newbie level 5
Newbie level 5
Joined
Jul 10, 2024
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
50
Lack of CODE or SYNTAX Tags: Added by moderator
Why we use 120 to create a delay of 1ms ,


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*#include<reg51.h>
sbit led = P2^0;
 
void delay();
 
void delay() {
    unsigned int i, j;
    for(i = 0; i < 500; i++) {
        for(j = 0; j < 120; j++){
                }
    }
}
 
void main() {
    while(1) {
        led = 1;
        delay();
        led = 0;
        delay();
    }
}



*/ In this code i create a delay of 500ms using j<120 , whats the reason we use this , i verify the delay using logic analyzer

1740054673655.png
 
Last edited by a moderator:
Because each iteration inside the inner for takes a 120 part of 1s...how about that?
 
How it comes as 120 for 1 ms any formula derivation in reference of Crystall oscillator , machines cycles How ??? it came as 120 ??? i did not get
 
Hi,

120 is not a fix value.
it depends on
* instructions used by the compiler
* run time per each single instruction
* clock frequency
.. maybe even more (like clock dividers ...)

I used this maybe 30 years ago ... then I switched over to hardware counters.
Hardware counters are as accurate as the external clock. (Mind: accuracy, not precision)
And they are independent of delays caused by interrupts.

With a "delay_ms()" function you could never build an accurately running real time clock.

Klaus
--- Updated ---

Because each iteration inside the inner for takes a 120 part of 1s...how about that?
it should be "1ms" instead of "1s" ... I´m sure you meant it this way.

Klaus
 
How it comes as 120 for 1 ms any formula derivation in reference of Crystall oscillator , machines cycles How ??? it came as 120 ??? i did not get
  1. Disassemble the above code on the specific compiler you are using...
  2. Read instructions datasheet of above uC to see how many clock cycles are used by each instruction on the loop...
  3. Check crystal value and oscillator settings if set on fuse bits...

Not a straight answer without further details.
 
Hello!

Why we use 120 to create a delay of 1ms

In fact, counting is the worst method to implement a delay.
As said above, each instruction needs a certain number of clocks.
Incrementing is quite quick (the i++, j++). Depends on the chip, but
let's say 2 clocks. But at every step of every loop, you also use
comparisons (with 120 and with 500 in your code) which add clocks at
every step. That must be also short. But it's better to compare to 0.

Today's lab: try to write your loop like this: for(j = 120, j > 0 ; j--)
and you will (probably) notice it's faster because it's usually faster
to compare to 0 than to an arbitrary number.

Then at the end of any loop, there is a jmp instruction which is a bit
more costly. You will have a jump everytime your comparison is false
(e.g. everytime i is less than 500) to return to the beginning of the
current loop with incremenation of i, j.

If 1 ms is 120 cycles, then your clock is 120 x 000 x loop_clocks,
this latter being the average number of clock you need to make your
increments.

Drawbacks of this method

1. Very inaccurate

One loop length will depend on where you are in the process. When you are
not at the border of the j interval, for example j = 100, then the loop is short.
j is incremented to 101, then compared to 120, and then there is a conditional jump.
But when you reach the end of the j loop, then you exit the loop,
enter the i loop, increment i, compare with 500, and then do the j loop,
in which case you have to set j = 0, and process with the short loop above.
It's very difficult to calculate the number of clocks you are going to spend.
Not rocket science, but let's say calendar-like science.

2. It just consumes power
In all meanings of this.
It consumes processing power, making additions, comparisons, etc, only for counting.
What a waste! Then it blocks the program flow.
When you block your system by counting, then you cannot do any other work.
That's why the best method (now that I have described the worst, I'm stuck, I have
to describe the best) is the one mentioned by Klaus. Hardware counter. I suppose
he means one of the processor timers because a timer is a counter with fancy features.
And the second meaning of power: the electrical power because the processor is
continuously on.

Every processor I know has internal timers which have hardware counters, and myriads
of settings that I cannot fully describe here, so I will focus only to the timer
interrupt.

You can setup a timer interrupt, which is an event coming from the timer.
This event will call a function which is called an interrupt service routine (ISR).
I will be short on the details, I'm sure you can find sample code for your
particular processor.

So you set the timer to count to a certain value. If your crystal has a frequency
of 32768Hz (RTC), you can use a 16-bit integer value (assuming it's at least
a 16-bit counter). You can also setup the timer so that it counts in a loop, back to 0
after 32767. Then you program it so that every time it reaches 0, the ISR is called.

You can then program it like this (pseudo code)

main() {
set_timer(32767, loop_mode, interrupt);
sleep();
}

void timer_int_routine() {
LED = !LED;
}

And that's it. You don't need a loop, it exists by the timer itself. Note that
your processor will do nothing exceot when it's called. This one would be 1 on and
1s off. And of course you need to implement set_timer, which is processor specific
code. Beside this, it's not recommended to do something in the ISR, but I cannot
explain everything within a single post.

With this implementation
- You will have an accurate timing
- You can do some other work instead of counting loop cycles.
-> With the first method (the one you have implemented), this extra work
would change the timing. With a hardware counter no. Except it the work
takes more than the counter period.
- If you sleep, the processor will consume possible 1% of the power it consumes
with a software counter.

Have fun!

Dora.
 


Write your reply...

LaTeX Commands Quick-Menu:

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top