10ms delay

Go To Last Post
30 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello engineers,

I need to make a delay inside a function to make and check the overrun error of a task..How can i make a 10ms delay using for loop,clock is 16Mhz. whats the values i need to give inside for loop checking.Please give your valuable suggestions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why would you want a loop to delay? It will block all other (non interrupt) activity?

 

Surely you want a timer for this (as with the timing of most things in MCU code)?

 

Anyway if you really want a loop then say what language you are using. If it happens to be avr-gcc then it is as simple as:

#define F_CPU 1234567UL
#include <util/delay.h>

void function(void) {
    _delay_ms(10);
}

(replace 1234567 with your real CPU speed).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Why would you want a loop to delay? It will block all other (non interrupt) activity?

 

Surely you want a timer for this (as with the timing of most things in MCU code)?

 

Anyway if you really want a loop then say what language you are using. If it happens to be avr-gcc then it is as simple as:

#define F_CPU 1234567UL
#include <util/delay.h>

void function(void) {
    _delay_ms(10);
}

(replace 1234567 with your real CPU speed).

Hello sir i am using c programming...Actually i need a for loop...no need of timer..my task is to do somrthing after the over rum of a task..for testing purpose i need to make an overrun in that task..so i wish to put a for loop to make the task overun

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You still haven't said which C it is??

 

As I say avr-gcc has _delay_ms(). You don't really need a loop with that as you can just say _delay_ms(N) where N is the number of milliseconds you want to delay (can be fractional like _delay_ms(3.7) if you like). If you REALLY wanted a for( ) loop then I guess...

void function(void) {
    int i;
    for (i=0; i< 10; i++) {
        _delay_ms(1);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

You still haven't said which C it is??

 

As I say avr-gcc has _delay_ms(). You don't really need a loop with that as you can just say _delay_ms(N) where N is the number of milliseconds you want to delay (can be fractional like _delay_ms(3.7) if you like). If you REALLY wanted a for( ) loop then I guess...

void function(void) {
    int i;
    for (i=0; i< 10; i++) {
        _delay_ms(1);
    }
}

 

i cannot use any inbuilt functions only a for loop

eg:

uint32_t i;

for(i=0;i<10000;i++)

{

}

i wanted to know whats the value we can give instead of 10000 for making a 10ms delay

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

C gives no guarantees about how fast code operates so in C alone it is almost impossible to make a loop that will execute for a known time. This is why people use timers not loops in MCUs. The timers are very accurate (as accurate as the main chip clock source).

 

If you really have some requirement to use software loops then (if using avr-gcc) your iteration variable needs to be volatile:

volatile uint32_t i;

for(i=0;i<10000;i++)
{
}

"volatile" says "this variable must exist and cannot be optimised away". In avr-gcc without volatile that entire loop will be discarded as C will assume it has no purpose.

 

That still raises the question of how to get the timing right. I can only suggest you guess at some number of iterations (like 10000) and try that. Put code on either side of the loop to raise/lower an output and then monitor that pin with an oscilloscope or logic analyser. If you find that a count of 10,000 actually leads to a duration of 8.9ms instead of the desired 10ms then you need to make an adjustment 10/8.9 is 1.1235955 so to extend the loop to get the 10ms you would change the 10000 to now be 11236. Of course it might not just be out by a few ms but it could be vastly wrong. Perhaps a count of 10000 only delays for 27us. In that case you need to do the same operation 10000us/2.7us is 370.37 so the loop is out by a factor of 370. So the 10000 count would need to be 3703703 and so on.

 

But all this is madness - just use a timer!

Last Edited: Wed. May 10, 2017 - 08:34 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

C gives no guarantees about how fast code operates so in C alone it is almost impossible to make a loop that will execute for a known time. This is why people use timers not loops in MCUs. The timers are very accurate (as accurate as the main chip clock source).

 

actually accuracy is not an issue here..i have a task of 10ms.. i wish to make it overrun for testing purpose,,,so put a for loop that can make the task run more than 10ms....its ok even its worked 12ms or 15 ms...becasue i just need to make an overrun

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1) Connect 'scope to an output.

1) Turn on output at the start of your delay.

2) Run you delay.

3) Turn off the output and observe pulse width on 'scope.

5) Tweak delay value as required.

 

Or, use the simulator.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This seems like an homework exercise to understand how high-level langages are translated into machine code.

First of all, you need to turn off optimizations so you're sure that the compiler won't do any tricks to your code.

 

Then, look at the loop:

 

uint32_t i;

for(i=0;i<10000;i++)

{

}

 

This could also be rewrtten as

 

uint32_t i;

for(i=10000;i >0;i--)

{

}

 

as it's more efficient to test for zero than for a different number.

 

The loop will be translated into a number of 4-byte increments plus a test.  That's pretty much 4+1 cycles each.

At 16Mhz, each cycle will consume 63ns, so that loop will consume 63*5 = 315ns at each iteration.

 

Now, do your math, and see how many cycles you will need ;)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ecworks wrote:
i cannot use any inbuilt functions

Such statements come up here  from time to time. It puzzles us. It makes the question look very strange. We are often led astray into ill structured discussions when this happens, and a lot of confusion and wasted time follows.

 

Please give a reason for not being able to use the built-ins.

 

Is this by any chance a school assignment?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

spassig wrote:
First of all, you need to turn off optimizations so you're sure that the compiler won't do any tricks to your code.
No don't ever turn off optimisation - it may affect operation of other parts of the code - as I said above it just needs "i" to be volatile.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Guys, this is 100% sure a school assignment, not a real project.

No need of optimization etc.

The teacher presumably just want to know if these guys know the difference between high-level languages and machine code, and how the two are related from a timing perspective.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

spassig wrote:
First of all, you need to turn off optimizations

Making the loop variable volatile should be enough, right?

 

spassig wrote:
as it's more efficient to test for zero

LOL! We're discussing the ultimate efficiency here - a delay loop! (-:

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:

spassig wrote:
First of all, you need to turn off optimizations

Making the loop variable volatile should be enough, right?

Yes, that should be enough.

JohanEkdahl wrote:

spassig wrote:
as it's more efficient to test for zero

LOL! We're discussing the ultimate efficiency here - a delay loop! (-:

:D

Last Edited: Wed. May 10, 2017 - 09:23 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

its not actually a school project smiley , anyway i got so many valuable points from all of you..Thank you very much

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ecworks wrote:
its not actually a school project
But you wouldn't be putting delay loops in a commercial development would you? A professional engineer is almost bound to always use a timer for temporal scheduling. (with the possible exception of delays so short that they can be achieve by simply delaying a handful of CPU cycles).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If the OP is trying to test if a "task" will timeout then surely:

 

while(1); //loop forever!

 

should eventually cause the "task" to timeout would it not!

 

 

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes but he needs to test if the task timeout occurs not earlier than 10ms, so he needs to get some rough measurement in place.
Still, I think a timer would work a lot better, but seems is something that is not allowed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just to make it clear for OP.

 

 _delay_ms(10);

Don't use any timers, but generate a dummy loop like you want !?

and perhaps run 10  1 ms loops withe a check. 

Last Edited: Wed. May 10, 2017 - 01:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
But you wouldn't be putting delay loops in a commercial development would you?

I told that i did this only to test my code...actualy my code is doing some steps when a task is overrun..so for testing purpose i need to make an overrun..for that i am using this for loop,just for testing.after testing i will remove this for loop..my language is not well,that why i cannot make you understand what i really mean

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

We understand what you are trying to accomplish with your delay loop.

 

What we don't understand why you can not use the built-in _delay_ms() function. It too uses a delay loop. (No timer involved at all.)

 

The built-in _delay_ms() has been written by some real experts on AVRs and GCC, and has been tested by thousands of users. It takes the burden of fighting with the compiler/optimizer off your shoulders. No need for you to fiddle with 'volatile' and such. It just works (as long as you tell it the truth about your clock frequency via the F_CPU symbol).

 

Define F_CPU, do the #include of delay.h, call _delay_ms(). Done!

 

But, if you want to take on that work yourself - with the possible hazzles - then you're of-course free to do so.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Wed. May 10, 2017 - 01:59 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
(with the possible exception of delays so short that they can be achieve by simply delaying a handful of CPU cycles)

Another possible exception might be for initialization of some external peripherals during the system startup where the timing for anything else is not critical.

David (aka frog_jr)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

i cannot use any inbuilt functions only a for loop

its not actually a school project

I cannot reconcile these two statements.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is a delay routine I have used:

 

void delnms(int n)
{
//delay n ms
    volitile int x;

    while(n--)
    {
//        x=164;   //empirically determined fudge factor 1MHz
//        x=1330;   //empirically determined fudge factor 8MHz
//        x=2400;       //empirically determined fudge factor 14MHz
        x=2660;   //empirically determined fudge factor 16MHz
//        x=3000;       //empirically determined fudge factor 18MHz
        while(x--);
    }
}

Un-comment x that is close to your F_CPU speed

 

Call with delnms(value to wait);

 

Jim

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
I cannot reconcile these two statements.
+100.

 

OP says this is just to "stress load" some scheduling to see what occurs if a task exceeds 10ms. Already the most excellent suggestion of simply using a while(1) (which will take a LOT more than 10ms) has been given but beyond that I simply don't see why _delay_ms(10) is not the solution here and why a for() loop has to be used.

 

I have a sneaking suspicion we are talking about something other than AVR - there is no AVR-LibC (or equivalent). there is no _delay_ms(10) or equivalent.

 

Don't understand in that case why #6 is NOT the solution though?

 

When I first ever got a Cortex M board and it had an LED my first thought was "what's the delay() routine in this library?". When it wasn't immediately forthcoming I just went for:

for (volatile int i=0; i < 10000000; i++);

As it happened I hugely over-estimated (can't remember how many 0's I actually started with) and the flashing was astronomically slow so I just started trimming off 0's until the flash rate "looked right".

 

That is the essence of what I suggested in #6.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:

i cannot use any inbuilt functions only a for loop

its not actually a school project

I cannot reconcile these two statements.

You mean compile without warnings or errors.........cheeky

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

Last Edited: Thu. May 11, 2017 - 01:44 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You mean compile without warnings or errors......... Jim

 

... like as in ...

volitile int x;

(Sorry Central Jim. devil)

 

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

valusoft wrote:

You mean compile without warnings or errors......... Jim

 

... like as in ...

volitile int x;

(Sorry Central Jim. devil)

 

That's what I get when I make a change on the fly trying to port it to gcc,  crying

the original just had int x; and works fine using ICC!

 

Jim

 

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you like your elevation to the "Jim Club"?

 

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yea, I'm a life member!