for loops and _delay_ms dont work

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

it seems there is some error in my compiler neither my for loops nor my _delay_ms function work wherever i use for loops or _delay_ms it seems that the statements are completely ignored coz if forr loops are used and iam trying to control a servo , the serco just jitters and it also seems like my delay_ms function also doesnt work

#include  //for 8mhz internal oscillator controlling servo by centering it 
#include  
#include 


int main (void) 
{ 
 
   unsigned int i;
   DDRD |= _BV(5); // Set PORTD5 as output
   DDRC =0x01; 

   TCCR1B |= (1 << WGM13); // phase and frequency correct mode
   
   ICR1=10000;
   
   TCCR1A|=(1<<COM1A1);//clear oc1a when upcounting and set Oc1a while downcounting

   TCCR1B |=(1<<CS11); // Start timer at Fcpu/8
   PORTC=0X01;
   
   while(1)
    {
	
	  
	  for(OCR1A=300;OCR1A<1100;OCR1A++)
	    {
		  _delay_ms(1);
		}
		
		for(i=1;i<=1000;i++)
	 {
	 _delay_ms(10);
	 }
		
		
		
	  for(OCR1A=1100;OCR1A>300;OCR1A--)
	    {
		 _delay_ms(1);
		}
     for(i=1;i<=1000;i++)
	 {
	 _delay_ms(10);
	 }
	}
return(0);
   
   
} 

if i dont use the for loops or the delay_ms the servo rotates fine but if i use the delay_ms function and the for loops , it just jitters ,the for loop and the delay _ms function should give me a delay of 10 s but that never happens the servo just jitters after going to the extreme left. I have been having this problem with for loops and delay_ms since the beginning, the same code written by me works well with compilers of the same version in a different computer. The compiler used by me is the Winavr gcc version 20071221

can anyone tell me what is the problem.

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

Possibly the for loops don't work for the same reason that _delay_ms() doesn't work.

What optimisation level are you using? Some of the delay functions do not work with optimisation set to 0. Read util/delay.h or the FAQ on the AVRlib site for details.

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

optimization is S in the makefile

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

superchiku wrote:
optimization is S in the makefile
I will assume that you mean "-Os" (that's a little "s").

I don't see any serious problems. In your previous posts you were using an ATmega16, which I assume you are still using.

I compiled the following using WinAVR 20071221 and AVRStudio 4.13 SP2. The generated code looks correct, but then I don't have an ATmega16 to try it out and the simulators are notoriously bad with timers.

#include  //for 8mhz internal oscillator controlling servo by centering it
#include 
#include 


int main (void)
{
 
	unsigned int i;
	DDRD = _BV(5); // Set PORTD5 as output
	DDRC = 0x01;

	TCCR1B = (1 << WGM13); // phase and frequency correct mode

	ICR1 = 10000;
	OCR1A = 300;

	TCCR1A = (1<<COM1A1);//clear oc1a when upcounting and set Oc1a while downcounting

	TCCR1B = (1<<CS11); // Start timer at Fcpu/8
	PORTC  = 0X01;

	while(1)
	{
		for(OCR1A=300;OCR1A<1100;OCR1A++)
		{
			_delay_ms(1);
		}
      
		for(i=1;i<=1000;i++)
		{
			_delay_ms(10);
		}
      
		for(OCR1A=1100;OCR1A>300;OCR1A--)
		{
			_delay_ms(1);
		}
		for(i=1;i<=1000;i++)
		{
			_delay_ms(10);
		}
	}

	return(0);
} 

Note that I changed your setup of the timer control registers from "|=" to "=". I told you about this in your previous post. You should use the "|=" only when you know the previous state of the register and intend to change just a bit. Since you do not know the state of these control registers (since you just woke the processor up), it is safer to force the state to a known condition. While I do not think this is your problem, this is safer.

I also initialized the OCR1A value to 300 before the loops. Again, not strictly necessary, but desirable.

I don't see why the _delay_ms(1) would not work in your case. I can only think that your optimization is not set correctly.

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

yes u were right the optimization wasnt s it was 1 and how it bcame 1 i dont know, i debugged the code ,it works fine and from now on ill use ur technic of using only = not |= where i am going to force it where i want, Thanks.

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

Taken from util/delay.h:

Quote:
\note When using _delay_us() and _delay_ms(), the expressions
passed as arguments to these functions shall be compile-time
constants, otherwise the floating-point calculations to setup the
loops will be done at run-time, thereby drastically increasing
both the resulting code size, as well as the time required to
setup the loops.

Could this have something to do with delay_ms not working?

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

Quote:
Could this have something to do with delay_ms not working?

First, he has already fixed his problem. Second, he is using compile-time constants.

Regards,
Steve A.

The Board helps those that help themselves.