Go Down

Topic: delay_ms not as expected (Read 322 times) previous topic - next topic

kogg

May 18, 2018, 08:28 pm Last Edit: May 18, 2018, 08:58 pm by kogg
Hi All

I been digging around in Atmel studio 7 so I can code the sam3x8e using registers plus c++. My problem is when I use delay_ms the code seems to go into some infinite loop on the delay_ms function. It steps through the code fine with F10 but soon as I press F5 the built in LED goes constant orange.

Anyone know what the issue is with delay_ms. Tried a few suggestions from other sites like including delay_init(), didn't hep. Someone else suggested #define F_CPU 84000000, didn't help, another said using a delay less than 300ms, no look there. So like a computer I'm in some need of input.


        PMC->PMC_PCER0=(1<<12);
   REG_PIOB_PER |= PIO_PB27; 
   REG_PIOB_OER |= PIO_PB27; 
   REG_PIOB_CODR |= PIO_PB27;
   REG_PIOB_OWER |= PIO_PB27;
   
   while(1) {
      

      
      REG_PIOB_SODR = PIO_PB27; //Enable output
      
                delay_ms(300);
      
      
      REG_PIOB_CODR = PIO_PB27;
      
   }

ard_newbie


The 2 functions below, either Delay() or Sleep() should compile:

Code: [Select]

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}


void loop() {
  PIOB->PIO_ODSR ^= PIO_ODSR_P27;
 
  //Delay(1000);
  Sleep(1000);

}

void Delay(int num)

{

  volatile float f = 1.0f;

  for (volatile int i = 0; i < 1024 * num; ++i )

    f *= 1.1f;

}



kogg

Thanks for the reply ard_newbie, yes that code works as you intended it to be used. But do you know why if I just use your Delay routine in my code it doesn't work. i.e

while(1) {
      
      REG_PIOB_SODR = PIO_PB27;
      
                Delay(500);
      
      REG_PIOB_CODR = PIO_PB27;
      
   }

So whats so different from this apart from the xor:

while(1) {
      
      REG_PIOB_SODR = PIO_PB27; //Enable output
            
      Delay(500);
   
      REG_PIOB_CODR = PIO_PB27; //Disable output
              }


And the following actually works:
      
   while(1) {
      
      
      REG_PIOB_SODR = PIO_PB27;
      
      
      for (i=0;i<1000;i++)
      {
         for (j=0;j<2000;j++) k = i-j;   
      }
      
      REG_PIOB_CODR = PIO_PB27;
      
                 for (i=0;i<500;i++)
      {
         for (j=0;j<2000;j++) k = j-i;
      }
   }

kogg

Haha just found if I use your delay_ms(500); as follows it works:

while(1) {
      
      
      REG_PIOB_SODR = PIO_PB27; //Enable output

      delay_ms(500);
      
         
      REG_PIOB_CODR = PIO_PB27; //Disable output

                delay_ms(500);
      
   }


Very strange behavior!! But it works with inbuilt delay.

weird_dave

Why is that strange behaviour? (rhetorical question, hint, it isn't)

In the code that 'doesn't work', you only have one delay, so as soon as the output was disabled, it gets enabled again. In both version that 'work', you have two delays, one after the enable and one after the disable.

Go Up