Wake up from Power Down Mode

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

Hello.
I want to wake up the AT90S2313 from power down mode by external pulse.,INT0.

There are no problems setting the power-down-mode.

if my program as follows:

void Shut_Power(void)
{
pwr_sta = 1;
sleep_mode(); //Sleep
}

I can wake up the 2313. the Power Consumption is >30MA

but as follows:
{
pwr_sta = 1;
cli();
outp(0xff,DDRB);
outp(0xff,PORTB);
//PD口初始化
outp(0xff,DDRD);
outp(0xff,PORTD);
outp(0x00,UCR);
outp(0x00,UBRR);
sbi(ACSR,7);
sei();
sleep_mode(); //Sleep
}

I can not wake up the 2313,but the Power Consumption is 70MS

Why? Can anybody help?
Thanks very much.

admin's test signature
 

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

INT0 is on PORTD, and you set it as output.

Reagrds,

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

It doesn't matter if the INT0 pin is set to output (see pg 22 in datasheet).

But maybe enabling the INT0 interrupt in the GIMSK register would help.

Gerrard

admin's test signature
 

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

Thanks.
:(, I can wake up the 2313 now ,and I did not change the program.why?

admin's test signature
 

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

Gerrard, you are sure, but if there are used pullups then.....

Regards,

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

All I can think of at this moment is the duration of the interrupt signal on the INT0 pin. Although according to the datasheet a minimum length of 26 ms should be enough.

Gerrard.

admin's test signature
 

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

Hello, I use atmega16, and can't wake up it from power dwown mode. It should wake up the I press INT0. Code just blink my LEDs, and turn off..


#include 
#include 
#include 
#include 
#include 
#include 

	void sleepNow()         
		{
			GICR |= (1<<INT0)|(1<<INT1)|(1<<INT2);
			MCUCR |= ((1<<ISC10)|(1<<ISC00));
		    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
		    sleep_enable();
		    sleep_mode();          
		    sleep_disable();
		}

	int main(void)
	{
		while(1)
		{
		DDRB = 255;
		PORTB = 0xff;
		_delay_ms(6000);
		PORTB = 0x00;
		_delay_ms(6000);
		sleepNow();
		}
	}

What's bad in my code..

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

Try as I might I cannot spot the sei() in that which would turn on the global interrupt system?

On the other hand you haven't provided ISR()s to catch the three interrupts you were enabling so maybe this is just as well ?!? ;-)

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

INT0 works, because it turn off leds, but it can't wake up form power down mode.. Why?:/


void sleepNow()         
   {
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);
      sleep_enable();
      sleep_mode();         
   }

     ISR(INT0_vect)
   {
      DDRB = 0x00;     //turn off led
      sleep_disable(); //wake up
   }

   int main(void)
   {
   GICR|=(1<<INT0); //External Interrupt Request 0 Enable
   MCUCR|=(1<<ISC00)|(1<<ISC01); //The rising edge of INT0 generates an interrupt request.
   DDRD=0x00;
   PORTD=0xff;
   sei();
     while(1)
     {
     DDRB = 0xff;
     _delay_ms(3000);
     PORTB = 0xff;
     _delay_ms(3000);
     PORTB = 0x00;
     sleepNow();
     }
   } 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

DDRB = 0x00; //turn off led

Wrong - suggest you re-read about the use of PORTB and DDRB.

I did wonder why you were setting DDRB inside the while(1)

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

clawson wrote:
Quote:

DDRB = 0x00; //turn off led

Wrong - suggest you re-read about the use of PORTB and DDRB.

I did wonder why you were setting DDRB inside the while(1)

I knew that DDRB mark a contact as input or output, and PORT on or off. Change as you wish :). I think problem is in sleep_disable function..

void sleepNow()         
   {
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);
      sleep_enable();
      sleep_mode();         
   }

     ISR(INT0_vect)
   {
      PORTB = 0x00;     //turn off led
      sleep_disable(); //wake up
   }

   int main(void)
   {
   GICR|=(1<<INT0); //External Interrupt Request 0 Enable
   MCUCR|=(1<<ISC00)|(1<<ISC01); //The rising edge of INT0 generates an interrupt request.
   DDRD=0x00;
   PORTD=0xff;
   DDRB = 0xff;
   sei();
     while(1)
     {
     _delay_ms(3000);
     PORTB = 0xff;
     _delay_ms(3000);
     PORTB = 0x00;
     sleepNow();
     }
   } 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The chip is not awaken with "sleep_disable()" but with interrupt itself.
And if I remember well the INT should be triggered with low level, not with edge.

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

Quote:

And if I remember well the INT should be triggered with low level, not with edge.

To be clear to the OP I think what Visovian means is that the only wake from sleep mechanism is a low-level INT0. The edges cannot be used as a wake from sleep mechanism.

In the datasheet where it gives that table of the sleep modes and the possible wake sources you should find there's a footnote about this.

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

Whats right! I read datasheet again and it work, thx!

Good code without library use!

void sleepNow()         
   {
      MCUCR|=(1<<SM1);// Power down     
	  MCUCR|=(1<<SE);// Sleep enable
	  asm volatile ("sleep"::);
   }

     ISR(INT0_vect)
   {
      PORTB = 0x00;     //turn off led
      MCUCR&=~(1<<SE);// Sleep disable
   }

   int main(void)
   {
   GICR|=(1<<INT0); //External Interrupt Request 0 Enable
   MCUCR|=(0<<ISC00)|(0<<ISC01); //The low level of INT0 generates an interrupt request.
   DDRD=0x00;
   PORTD=0xff;
   DDRB = 0xff;
   sei();
     while(1)
     {
     _delay_ms(3000);
     PORTB = 0xff;
     _delay_ms(3000);
	 PORTB = 0x00;
     sleepNow();
     }
	cli();
   }
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello. Thank`s. It works very well. I think if you change

MCUCR|=(0<<ISC00)|(0<<ISC01);

to

MCUCR &= ~((1 << ISC00) | (1 << ISC01));

as logically it`s better.

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

amirPro wrote:

Hello. Thank`s. It works very well. I think if you change

MCUCR|=(0<<ISC00)|(0<<ISC01);

to

MCUCR &= ~((1 << ISC00) | (1 << ISC01));

as logically it`s better.

 

very nice suggestion...16 years later :)