EmbDev.net

Forum: ARM programming with GCC/GNU tools Strange Behaviour or WinARM with LPC2148 (delay_ms function)


Author: Sobak Ava (Guest)
Posted on:

Rate this post
0 useful
not useful
Hi

I needed to create a simple delay subroutine by using dummy loops. I 
found some calculations and tested/working codes for LPC2148 on the net. 
Three of them are:

Code:
void delay_ms(long int ms)
{
long int i, j;
for(i=0;i for(j=0;j<6553;j++);
}


OR

Code:

void delay_ms(unsigned long int count1)
{
unsigned int i,k;
k=count1*2600;
  for(i=0;i<k;i++);                     // Loop Decrease Counter
}



OR

Code:

void delay_ms(int x)         //this isn't accurate right
now{               //it's just a rough delay   int a,b; 
for(a=0;a<x;a++){      for(b=0;b<3000;b++);   }}


Well, these supposed to be work but they do not.

I do something like this:


Code:

while (1) {
IOSET1 = 0x01000000;      // turn off LED
delay_ms(10);
IOCLR1 = 0x01000000;      // turn off LED
delay_ms(10);
}




I already made port direction settings etc.before this piece of code. It 
is working correctly. But delay_ms() seems not become compiled because I 
see very short (around 300-500 ns) pulses using an oscilloscope.

I tried to use delay_ms( 10000) insead of delay_ms(10)... Nothing 
changed.

Then I tried to increase i and j end values in delay_ms() function. 
Nothing changed.

for instance
Instead of for(i=0;i for(j=0;j<6553;j++);
I tried for(i=0;i for(j=0;j<16553;j++);

pulse durations did not changed. The stranger thing is, I compared two 
hex files byte by byte and they are identical! so 6553 to 16553 does not 
change anything in code.

Then I thought may be the compiler does not compile dummy loops because 
of optimization, I added some arithmetic calculations in loop:

Code:

for(i=0;i for(j=0;j<6553;j++)   a++;


nothing changed. It seems loops are not compiled. ?


I thought may be there is another delay_ms function in the search path 
include files. I changed the name to my_delay_ms... Nothing changed.

Finally I did something like this:

Code:

void delay_ms(long int ms)
{
long int i, j;
 for(i=0;i for(j=0;j<6553;j++) {
      IOSET1 = 0x00000001;    // set P1.1... it is an unused pin. just 
for testing
  }
}



after this delay_ms has effect (delay). Why It does not work and it has 
no effect if I do not place a port operation inside the loop?

Author: jl (Guest)
Posted on:

Rate this post
0 useful
not useful
that looks like optimization. your loops and the used variables were 
incremented only but never used for read access.

put your variable a as volatile and
   for(i=0;i for(j=0;j<6553;j++)   a++;
shall work.

Better would be use of a timer and compare that content with your delay 
time. You will never know what your compiler does or if the sequnece is 
cached (ARM7) and takes less time.

JL

Author: Marcus Harnisch (mharnisch)
Posted on:

Rate this post
0 useful
not useful
Make i volatile.

Interesting observation: Some compilers (e.g. RealView) don't seem to 
optimize empty loops "for (i=LIMIT; i>=0; i--);" even at high 
optimization levels. I suppose that the assumption is that empty loops 
are there for a reason.

Regards
Marcus
http://www.doulos.com/arm/

Author: Clifford Slocombe (clifford)
Posted on:

Rate this post
0 useful
not useful
It is not strange behaviour. It is exactly expected behaviour. For an 
explanation read this article: 
http://www.embedded.com/columns/beginerscorner/9900209

However and empty loop is a really dumb solution to delay timing. The 
chip has several hardware timers that won't vary between compiler or 
optimisation settings, I suggest that you use one of them. Moreover wrap 
the hardware access in a function (preferably in a separate hardware 
abstraction module), so that porting the code to a different device, or 
one running at a different clock rate or clock configuration only 
requires changing one function.

Note that if you poll a hardware timer, or a counter updated in an ISR 
from a timer interrupt, that variable or register must too be declared 
volatile. The register header you are using should already declare 
device registers volatile.

Clifford

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.