Software > Software

AVR timer problem

(1/3) > >>

for the life of me im totally confused why this isnt working . . .

im trying to generate a simple square wave, using my oscope to measure it. below i list three sets of code, which for some really really odd reason gives me the exact same square wave! (142 kHz perfect symmetric square wave)

--- Code: ---PORT_ON(PORTD, 6);
for (i=1000; i>0 ; i--);
FLIP_PORT(PORTD, 6);
for (i=100; i>0 ; i--);

--- End code ---

--- Code: ---PORT_ON(PORTD, 6);
for (i=1000; i>0 ; i--);
for (i=1000; i>0 ; i--);
for (i=1000; i>0 ; i--);
for (i=1000; i>0 ; i--);
FLIP_PORT(PORTD, 6);
for (i=100; i>0 ; i--);

--- End code ---

--- Code: ---PORT_ON(PORTD, 6);
for (i=15000; i>0 ; i--);
FLIP_PORT(PORTD, 6);
for (i=130; i>0 ; i--);

--- End code ---

but then if i try this i get a square wave of 1kHz - shows that im compiling right and measuring the right pin . . .

--- Code: ---void delay_us(unsigned long int time_us)
{
int i;
long int j=time_us;
for(i=1;i>0;i--)
{
while(j>=0)
j--;
j=time_us;
}
}

//and in main i have:
PORT_ON(PORTD, 6);
delay_us(1000);
FLIP_PORT(PORTD, 6);
delay_us(100);

--- End code ---

and yet then if i remove the for loop (which doesnt actually do anything anyways), i get the same exact 142 kHz perfect symmetric square wave I mentioned earlier!

--- Code: ---void delay_us(unsigned long int time_us)
{
int i;
long int j=time_us;
//for(i=1;i>0;i--)
//{
while(j>=0)
j--;
j=time_us;
//}
}

//and in main i have:
PORT_ON(PORTD, 6);
delay_us(1000);
FLIP_PORT(PORTD, 6);
delay_us(100);

--- End code ---

im using WinAVR and the compiler that comes with it . . . this makes no sense!!!!!!!!!!!

so then I get the genious idea of using the AVRlib timer code, which DOES NOT work (it gives me a perfect 35kHz symmetric square wave even though my delays are not):

--- Code: ---void delay_us(unsigned short time_us)
{
unsigned short delay_loops;
register unsigned short i;

delay_loops = (time_us+3)/5*CYCLES_PER_US; // +3 for rounding up (dirty)

// one loop takes 5 cpu cycles
for (i=0; i < delay_loops; i++) {};
}
//in main i call:
PORT_ON(PORTD, 6);
delay_us(100);
FLIP_PORT(PORTD, 6);
delay_us(10);

--- End code ---

and is if i call this in main with the AVRlib code, i still get the same exact square wave (weird!!!!):
PORT_ON(PORTD, 6);
delay_us(10);
FLIP_PORT(PORTD, 6);
delay_us(10);

im starting to blame it on the compiler . . . is there a bug in it or something or am i just being really really dumb?!?!?  :(

ran some more tests to add to the mystery . . .
i checked the frequency with my multimeter and confirmed the oscope reading (so the oscope isnt causing this).

this code causes NO squarewave (the pin just stays high)

--- Code: ---void delay_us(unsigned long int time_us)
{
int i;
unsigned long int j=time_us;
for(i=1;i>0;i--)
{
while(j>=0)
j--;
j=time_us;
}
}

--- End code ---

but simply by removing 'unsigned' this code causes a 31kHz symmetric square wave ???:

--- Code: ---void delay_us(unsigned long int time_us)
{
int i;
long int j=time_us;
for(i=1;i>0;i--)
{
while(j>=0)
j--;
j=time_us;
}
}

--- End code ---

the main inputs were this for both:
PORT_ON(PORTD, 6);
delay_us(100);
FLIP_PORT(PORTD, 6);
delay_us(10);

I figured it out (yaaaaaay!!!!!!)

It turns out there is a HUGE bug in the gcc optimization!!!

How do I know this? Well, after wasting 10 hours trying to figure this out, I turned optimization off in the make file (OPT=0). When doing so, it works!

And when I turn optimization on (OPT=1, OPT=s, or any other type) it totally breaks (like a squirrel eating a nut).

This really sucks though, because now my compilation cant be optimized :(

JesseWelling:
Don't know why I did't think of that but yea optimization will detroy any looping waits. Because they technicaly arn't doing any thing. So it's not a 'bug' , it's the actual feature :P