Stránka 1 z 1

SLEEP mode při TIMER2 v asynchroním modu

Napsal: 18 bře 2013, 21:59
od sewerman_cz
Navrhl jsem si hodiny se 7-segmentovkami a Atmega8
Hodiny běží pomocí RTC s TIMER2 v asynchronním modu. Hodiny mi běží ale řeším záložní napájení.

Napájení je ze sítě + záložní baterie, oddělené diodami. Napájení je detekováno Log1 na jednom pinu.
Nedaří se mi nastavit SLEEp mod POWER SAVE při napájení z baterie

Kód: Vybrat vše

if(READ_SUPPLY_PIN==0)
            {
            //Napájení odpojeno, zrušit povolení přerušení od TIMER0,
            //odpojit segmenty,zapnutí SLEEP mod POWER SAVE
                //Zakázat přerušení od TIMER0
                TIMSK&=~(1<<TOIE0);
                //Vypnutí segmisegmentovek
                SEVEN_SEGMENT_PORT=0X00;
                SEGMENT_PORT&=~((1 << _SEG_HOD_10) | (1 << _SEG_HOD_01) | (1 << _SEG_MIN_10) | (1 << _SEG_MIN_01));
                //Kontrola TIMER2
                while (!(ASSR & ((1<<TCN2UB)|(1<<TCR2UB)|(1<<OCR2UB))));
            //nastaveni SLEEP modu
            set_sleep_mode(SLEEP_MODE_PWR_SAVE);
            sleep_mode();
         
              //Povolení přerušení od čassovače TIMER0
              TIMSK|=(1<<TOIE0);
             TCNT0=0;
         }

TIMER0 používám na multiplex segmentovek, proto jej chci vypnout. Pokud nevypnu přerušení od TIMER0 segmenty svítí dál. Pokud to mám nastaveno tak jajk je uvedeno tak se mi Atmega již neprobudí.
Dokážete poradit?

Napsal: 18 bře 2013, 22:15
od WLAB
A co ma byt ta probouzeci udalost, ktera nefunguje?

Napsal: 18 bře 2013, 22:18
od Atlan
sice neviem ci ti to pomoze kedze ja som dal full sleep

Kód: Vybrat vše

   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
   if (sp)  {clrb(PORTD,3);            //ma byt len sp
            clrb(PORTC,3);
            clrb(PORTD,6);
            clrb(PORTB,2);
            UCSRB &= ~(1 << RXCIE);   //zakazat prerusenie od rs232
            GICR = (1 << INT0);      //povolit prerusenie od int0
            sei();
            sleep_mode();
            GICR = (0 << INT0);      //zakazat prerusenie od int0
            UCSRB |= (1 << RXCIE);   //povolit prerusenie od rs232
            setb(PORTB,2);
            m=2;
            wait=2;
      
             }


tak ze zmena na pine INT mi zobudi procesor.

Napsal: 18 bře 2013, 22:29
od sewerman_cz
Blbě jsem se vyjádřil.
Při napájení na baterii by měl pouze fungovat timer2 který počítá čas
Po znovu zapnutí napájení by měly svítit segmenty.
Trochu jsem to upravil

Kód: Vybrat vše

  if(READ_SUPPLY_PIN==0)
            {
            //Napájení odpojeno, zrušit povolení přerušení od TIMER0,
            //odpojit segmenty,zapnutí SLEEP mod POWER SAVE
                //Zakázat přerušení od TIMER0
                TIMSK&=~(1<<TOIE0);
                //Vypnutí segmisegmentovek
                SEVEN_SEGMENT_PORT=0X00;
                SEGMENT_PORT&=~((1 << _SEG_HOD_10) | (1 << _SEG_HOD_01) | (1 << _SEG_MIN_10) | (1 << _SEG_MIN_01));
                //Kontrola TIMER2
                while (!(ASSR & ((1<<TCN2UB)|(1<<TCR2UB)|(1<<OCR2UB))));
            //nastaveni SLEEP modu
            set_sleep_mode(SLEEP_MODE_PWR_SAVE);
            sleep_mode();
         }
         else
         {
              //Povolení přerušení od čassovače TIMER0
              if (TOIE0==0)
              {
                TIMSK|=(1<<TOIE0);
                TCNT0=0;
              }
            
                     
         }

Napsal: 18 bře 2013, 22:38
od Andrea
A tenhle kód máš umístěnej kde?

Napsal: 18 bře 2013, 22:41
od sewerman_cz
V Main
za while(1)

Napsal: 18 bře 2013, 22:45
od sewerman_cz
Problém asi není ve SLEEP ale ve vypínání a zapínání Timer0, který se stará o segmentovky

Kód: Vybrat vše

if(READ_SUPPLY_PIN==0)
            {
            //Napájení odpojeno, zrušit povolení přerušení od TIMER0,
            //odpojit segmenty,zapnutí SLEEP mod POWER SAVE
                //Zakázat přerušení od TIMER0
                TIMSK&=~(1<<TOIE0);
                //Vypnutí segmisegmentovek
                SEVEN_SEGMENT_PORT=0X00;
                SEGMENT_PORT&=~((1 << _SEG_HOD_10) | (1 << _SEG_HOD_01) | (1 << _SEG_MIN_10) | (1 << _SEG_MIN_01));
                //Kontrola TIMER2
              //  while (!(ASSR & ((1<<TCN2UB)|(1<<TCR2UB)|(1<<OCR2UB))));
            //nastaveni SLEEP modu
            //set_sleep_mode(SLEEP_MODE_PWR_SAVE);
            //sleep_mode();
         }
         else
         {
              //Povolení přerušení od čassovače TIMER0
              if (TIMSK & (1<<TOIE0)==0)
              {
                TIMSK|=(1<<TOIE0);
                TCNT0=0;
              }
            
                     
         }

Po znovu připojení na síť se prostě segmenty nerozsvítí.

Napsal: 18 bře 2013, 22:55
od Andrea
A if (TOIE0==0) má dělat co? TOIE0 je přece číslo bitu, ne? (už jsi to opravil)
V datašítu píšou, že mezi probuzením a opětovným uspáním musí uběhnout alespoň jeden takt TOSC1, máš to vždy dodržené? Já před uspáním, zapisuju do OCR2 (stejnou hodnotu, jaká už tam je) a pak teprve testuju OCR2UB, tím je ten jeden takt zaručený vždy.

Napsal: 18 bře 2013, 23:18
od sewerman_cz
Problém asi nebude v uspávání. To jsem zakomentoval a stejně to neběží. Problém bude zřejmě s vypínáním a opětovným zapínáním povolení přerušení od timer0

Napsal: 19 bře 2013, 00:00
od sewerman_cz
Chyba byla v podmínce
if (TIMSK & (1<<TOIE0)==0)
správně je
if ((TIMSK & (1<<TOIE0))==0
Zvláštní je, že to překladači nevadilo.
Zítra budu řešit to uspávání.

Napsal: 19 bře 2013, 16:10
od AB1
Zvláštní je, že to překladači nevadilo.

Protože zápis je syntakticky správný. Logické chyby překladač samozřejmě neodhalí.

Operátor == má větší prioritu než &.
Proto
(TIMSK & (1<<TOIE0)==0)
je totéž jako
(TIMSK & ( (1<<TOIE0)==0))

Napsal: 19 bře 2013, 16:26
od rnbw
Neviem, aky mas prekladac, ale GCC s -Wall hodi pri tomto pouziti warning (lebo je to takmer vzdy chyba).

Napsal: 19 bře 2013, 16:36
od AB1
Ano, zkusil jsem a překladač vydá varování.
Problém je asi v tom, že část bastlířů varováním nevěnuje pozornost.

Napsal: 19 bře 2013, 17:54
od rnbw
Radsej vsetko kompilujem s -Wall -Wextra a kazde varovanie riesim. Predide sa tym mnohym zbytocnym problemom. Ale programujem pre PC, nie pre MCU.