logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATmega32] tryb power-save

smiejko 22 Cze 2008 10:20 2895 9
REKLAMA
  • #1 5273412
    smiejko
    Poziom 11  
    Witam!

    Chciałbym się dowiedzieć jaki poziom poboru prądu udało się Wam uzyskać, w trybie Power-save wspomnianego µP, ponieważ u mnie wynik ten jest zdecydowanie słąby i zastanawiam się co robię źle. Jest to około 360 µA. Natomiast dla trybu aktywnego, tzn. np czekając na znak z portu szeregowego jest to już aż około 10,25 mA! (bez rezystorów podciągających - 12,16 mA). Z noty katalogowej wynika, że powinno to być znacznie mniej. Oto główna część testowego programu, dla którego mierzę pobór prądu wpinając się przed nóżką VCC µP. Zasilanie jest ze stabilizatora 7805, na którego podaję wyższe napięcie ze zwykłego zasilacza wtyczkowego.
    
    ...
    #define F_CPU 8000000UL
    ...
    //---------------------------------------------------
    inline void UART_init(void)	//inicjalizacja portu szeregowego
    {
    	UBRRL = 12;		   //F_CPU = 8MHz, BAUD = 38400 bps
    	sbi(UCSRB,TXEN);	//odblokowanie nadajnika
    	sbi(UCSRB,RXEN);	//odblokowanie odbiornika
    } 
    //---------------------------------------------------
    inline void TIMER2_init(void)	//inicjalizacja czasomierza 2 jako zegar czasu rzeczywistego
    {
      cli();				//wyłącz przerwania
      sbi(SFIOR,PSR2);	        //wyzerowanie preskalera
      sbi(ASSR,AS2);		//taktowanie asynchroniczne z TOSC
    
      sbi(TCCR2,CS22);			
      sbi(TCCR2,CS21);	      //ustawienie podziału sygnału zegarowego na CK/1024
      sbi(TCCR2,CS20);		//CK = 32768 Hz (przepełnienie co 10 sekund)
    
      loop_until_bit_is_clear(ASSR,TCR2UB); // czekaj na uaktualnienie rejestru TCCR2
    
      sbi(TIMSK,TOIE2);			//odblokowanie przerwania na przepełnienie czasomierza 2
      sei();				//włącz przerwania
    }
    //---------------------------------------------------
    ...
    //---------------------------------------------------
    SIGNAL(SIG_OVERFLOW2)
    {
    	UART_getchar();
    }	
    //---------------------------------------------------
    int main(void)
    {
    	DDRA = 0x00;      //wszystkie porty jako wejścia
    	DDRB = 0x00;
    	DDRC = 0x00;
    	DDRD = 0x00;
    
    	PORTA = 0xFF;    //z rezystorami podciągającymi
    	PORTB = 0xFF;
    	PORTC = 0xFF;
    	PORTD = 0xFF;
    
    	UART_init();		//inicjalizacja portu szeregowego
    	TIMER2_init();		//inicjalizacja czasomierza 2
    	
    	set_sleep_mode(SLEEP_MODE_PWR_SAVE);	//wybór trybu uśpienia
    	
    	do
    	{
    		sleep_mode();	//uśpienie procesora
    	}
    	while(1);		//nieskończona pętla
    }
    

    Fakt, że mieszałem też trochę we Fuse bitach :)

    Z góry dzięki za wszelką pomoc!
    Pozdrawiam!
  • REKLAMA
  • Pomocny post
    #2 5273422
    ZbeeGin
    Poziom 39  
    Dodatkowo wyłącz zasilanie ADC i ACI. Poza tym te podciąganie wejść też mi się nie podoba.
  • #3 5274172
    smiejko
    Poziom 11  
    Zmiana konfiguracji portół powoduje u mnie zmiany poboru prądu, ale tylko w stanie aktywnym (też jest bardzo duży - ponad 10mA - a praktycznie nic nie jest podłączone). Prąd w trybie Power-save jest bez zmian (ok. 0,37mA). Widocznie zadbał o to sam. Podobnie z komparatorem i przetwornikiem A/C - bez zmian. Może ustawienia Fuse-bitów są nieodpowiednie?
    [ATmega32] tryb power-save

    Już odkryłęm przyczynę! Okazało się, że pobór prądu znacznie zmalał jak odłączyłem od µP układ MAX232 (po prostu wyciągnąłem go z podstawki). Teraz prąd jest na poziomie 12µA dla zasilania z zasilacza 5V i 7µA przy zasilaniu z dwóch baterii (razem ok. 2,75V).
    Mimo jednak, że wiem co jest przyczyną, to jednak nie wiem za bardzo jak sobie z tym poradzić. Próbowałem różnych konfiguracji pinów RxD i TxD µP, ale nic to nie daje... Wie ktoś może jak móc korzystać z RS-a i zarazem usypiać µP?
  • REKLAMA
  • #4 5277652
    smiejko
    Poziom 11  
    Udało się rozwiązać problem :D

    Rozwiązanie znalazłem tutaj:
    http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=64949

    Należało wyłączyć układ USART zerując bity RXEN i TXEN przed uśpieniem i włączać go tylko, gdy był potrzebny :)

    Zamieszczam poprawiony kod programu - może się komuś przyda:
    
    ...
    #define F_CPU 8000000UL
    ...
    #define sbi(x,y) ( x|=_BV(y) )		// x = x | _BV(y)
    #define cbi(x,y) ( x&=~_BV(y) )	
    //---------------------------------------------------
    inline void UART_init(void)	//inicjalizacja portu szeregowego
    {
    	UBRRL = 12;		//F_OSC = 8MHz, BAUD = 38400 bps
    } 
    //---------------------------------------------------
    inline void TIMER2_init(void)	//inicjalizacja czasomierza 2 jako zegar czasu rzeczywistego
    {
      cli();				//wyłącz przerwania
      sbi(SFIOR,PSR2);			//wyzerowanie preskalera
      sbi(ASSR,AS2);			//taktowanie asynchroniczne z TOSC
    
      sbi(TCCR2,CS22);			
      sbi(TCCR2,CS21);			//ustawienie podziału sygnału zegarowego na CK/1024
      sbi(TCCR2,CS20);			//CK = 32768 Hz (przepełnienie co 10 sekund)
    
      loop_until_bit_is_clear(ASSR,TCR2UB); // czekaj na uaktualnienie rejestru TCCR2
    
      sbi(TIMSK,TOIE2);			//odblokowanie przerwania na przepełnienie czasomierza 2
      sei();				//włącz przerwania
    }
    //---------------------------------------------------
    ...
    //---------------------------------------------------
    SIGNAL(SIG_OVERFLOW2)
    {
    		sbi(UCSRB,TXEN);	//odblokowanie nadajnika
    		sbi(UCSRB,RXEN);	//odblokowanie odbiornika	
    	UART_getchar();
    		cbi(UCSRB,TXEN);	//zablokowanie nadajnika
    		cbi(UCSRB,RXEN);	//zablokowanie odbiornika
    }	
    //---------------------------------------------------
    int main(void)
    {
    	UART_init();		//inicjalizacja portu szeregowego
    	TIMER2_init();		//inicjalizacja czasomierza 2
    
    	set_sleep_mode(SLEEP_MODE_PWR_SAVE);	//wybór trybu uśpienia
    	
    	do
    	{
    		sleep_mode();	//uśpienie procesora
    	}
    	while(1);		//nieskończona pętla
    }
  • REKLAMA
  • #5 8974034
    tombus
    Poziom 15  
    Witam.
    Niestety, ale muszę odgrzebać temat. Nie ma sensu zakładać nowego.
    Problem dotyczy ATMEGA32-16PU. W normalnym trybie pracy pobiera 8mA. w trybie POWER_DOWN 3.95 mA. Dlaczego nie mogę zejść niżej? Układ zasilany jest 5V z komputera. Do Atmegi podłączony mam PCF 8583 oraz LCD n3310 (wyświetlacz także wyłączam) . Reszta to drobnica.
    Watchdog wyłączony. Wyjmowałem PCF i otrzymuję takie same rezultaty. Czy można wyłączyć TWI? Może to zaoszczędzi mocy. Układ zrobiony jest jako testowy a program będzie przeportowany docelowo do ATMega328P-AU i zasilany będzie baterią CR-2032.
    Pozdrawiam.
  • #7 8986517
    tmf
    VIP Zasłużony dla elektroda
    Jak masz TWI to same rezystory pull up na SDA i SCL mogą ciągnąć więcej niż twoje 4mA. Trzeba dodać do nich wyłącznik np. na MOSFETcie. Ale bez schematu i tak nic więcej się nie poradzi, bo to wróżenie z fusów.
  • REKLAMA
  • #10 8986857
    tombus
    Poziom 15  
    Faktycznie. Odłączyłem LCD i pobór podczas POWER_DOWN spadł do 10uA.
    LCD wyłączam tak:

    
    lcd_Command(LCDC_DC|0);  //wprowadź wyświetlacz w tryb uśpienia
    lcd_Command(LCDC_FS|LCDC_PWR_DOWN);
    


    gdzie:
    
    // Definicja komend LCD
    
    // H = 0 (BASIC)
    #define LCDC_DC 0x08
    #define LCDC_DC_BLANK 0
    #define LCDC_DC_NORMAL 0x04
    #define LCDC_DC_ALLON 0x01
    #define LCDC_DC_INVERT 0x05
    #define LCDC_PWR_DOWN 0x04
    
REKLAMA