EmbDev.net

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


von Sobak Ava (Guest)


Rate this post
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?

von jl (Guest)


Rate this post
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

von Marcus H. (mharnisch)


Rate this post
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/

von Clifford S. (clifford)


Rate this post
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

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.