Society of Robots - Robot Forum

Software => Software => Topic started by: Admin on March 05, 2007, 04:11:37 PM

Title: AVR timer problem
Post by: Admin on March 05, 2007, 04:11:37 PM
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: [Select]
PORT_ON(PORTD, 6);
for (i=1000; i>0 ; i--);
FLIP_PORT(PORTD, 6);
for (i=100; i>0 ; i--);
Code: [Select]
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--);
Code: [Select]
PORT_ON(PORTD, 6);
for (i=15000; i>0 ; i--);
FLIP_PORT(PORTD, 6);
for (i=130; i>0 ; i--);

but then if i try this i get a square wave of 1kHz - shows that im compiling right and measuring the right pin . . .
Code: [Select]
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);

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: [Select]
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);

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: [Select]
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);

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?!?!?  :(
Title: Re: AVR timer problem
Post by: Admin on March 05, 2007, 04:54:16 PM
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: [Select]
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;
}
}

but simply by removing 'unsigned' this code causes a 31kHz symmetric square wave ???:
Code: [Select]
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;
}
}

the main inputs were this for both:
PORT_ON(PORTD, 6);
delay_us(100);
FLIP_PORT(PORTD, 6);
delay_us(10);
Title: Re: AVR timer problem
Post by: Admin on March 05, 2007, 05:06:57 PM
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 :(
Title: Re: AVR timer problem
Post by: JesseWelling on March 05, 2007, 05:57:16 PM
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
Title: Re: AVR timer problem
Post by: Admin on March 05, 2007, 06:20:07 PM
would it make sense to have an optimization level that understands and therefore allows looping waits?

Quote
Don't know why I did't think of that
cause you didnt spend 10 hours over 2 days trying to figure it out :P
Title: Re: AVR timer problem
Post by: dunk on March 05, 2007, 06:22:52 PM
i tell you what,
wait 25 days and submit it to the GCC developers as a bug....

i did exactly the same thing the first time i tried to get a delay while using a compiler.
(pity i didn't read this after your first post hu?)
it makes sense when you think about it. the optimisation is looking for unnecessary loops in your code that it can remove to increase performance (ie, speed the thing up again).

a far nicer way to program is to use one of the on board timers. it takes a little work to figure them out but it's well worth the effort.

dunk.
Title: Re: AVR timer problem
Post by: dunk on March 05, 2007, 06:25:20 PM
Quote
would it make sense to have an optimization level that understands and therefore allows looping waits?
not really.
optimization is looking for anything that will speed up execution time.
if you are using a loop for timing you clearly don't want to speed up the program so OPT=0 is the right option.

dunk.
Title: Re: AVR timer problem
Post by: JesseWelling on March 05, 2007, 07:26:04 PM
IIRC you can make it so it doesn't optimize loops....but I can't remember the argument that you feed into the compiler.
I'll look around awhile for it.
Title: Re: AVR timer problem
Post by: JesseWelling on March 05, 2007, 07:43:50 PM
here is what man avr-gcc had to tell me about optimization an loops
Code: [Select]
-floop-optimize
           Perform loop optimizations: move constant expressions out of loops, simplify exit test conditions and optionally do strength-reduction and loop unrolling as well.
           Enabled at levels -O, -O2, -O3, -Os.

But if you look at what -O does:
Code: [Select]
-O turns on the following optimization flags:-fdefer-pop -fmerge-constants -fthread-jumps -floop-optimize -fif-conversion -fif-conversion2 -fdelayed-branch -fguess-branch-probability -fcprop-registers
So what you could do is just copy paste every thing in except for the -floop-optimize. althought it might be one of the branching options that's messing with the loop.
Title: Re: AVR timer problem
Post by: NOOBinDistress on April 12, 2007, 07:41:22 PM
SPeaking of AVR Admin can you take a look at the posts I have made about programing the robot I built from your 50$ robot tutorial? THANKS
Title: Re: AVR timer problem
Post by: dunk on April 13, 2007, 02:23:37 AM
Admin's traveling round europe at the moment.
you'll have to wait a few weeks for him to get back.

with a bit of patience i'm sure someone else who has used windows AVR software will get back to you.

dunk.