SLEEP mode při TIMER2 v asynchroním modu

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Odpovědět
Zpráva
Autor
Uživatelský avatar
sewerman_cz
Příspěvky: 289
Registrován: 13 úno 2011, 01:00
Bydliště: Brno
Kontaktovat uživatele:

SLEEP mode při TIMER2 v asynchroním modu

#1 Příspěvek 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?

Uživatelský avatar
WLAB
Příspěvky: 867
Registrován: 13 zář 2005, 02:00
Bydliště: Praha

#2 Příspěvek od WLAB »

A co ma byt ta probouzeci udalost, ktera nefunguje?
de omnibus dubitandum est

Uživatelský avatar
Atlan
Příspěvky: 4499
Registrován: 10 kvě 2004, 02:00
Bydliště: Košice

#3 Příspěvek 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.

Uživatelský avatar
sewerman_cz
Příspěvky: 289
Registrován: 13 úno 2011, 01:00
Bydliště: Brno
Kontaktovat uživatele:

#4 Příspěvek 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;
			     }
				 
							 
         }

Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 02:00

#5 Příspěvek od Andrea »

A tenhle kód máš umístěnej kde?

Uživatelský avatar
sewerman_cz
Příspěvky: 289
Registrován: 13 úno 2011, 01:00
Bydliště: Brno
Kontaktovat uživatele:

#6 Příspěvek od sewerman_cz »

V Main
za while(1)

Uživatelský avatar
sewerman_cz
Příspěvky: 289
Registrován: 13 úno 2011, 01:00
Bydliště: Brno
Kontaktovat uživatele:

#7 Příspěvek 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í.

Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 02:00

#8 Příspěvek 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.

Uživatelský avatar
sewerman_cz
Příspěvky: 289
Registrován: 13 úno 2011, 01:00
Bydliště: Brno
Kontaktovat uživatele:

#9 Příspěvek 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

Uživatelský avatar
sewerman_cz
Příspěvky: 289
Registrován: 13 úno 2011, 01:00
Bydliště: Brno
Kontaktovat uživatele:

#10 Příspěvek 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í.

Uživatelský avatar
AB1
Příspěvky: 312
Registrován: 23 lis 2009, 01:00

#11 Příspěvek 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))
Naposledy upravil(a) AB1 dne 19 bře 2013, 16:27, celkem upraveno 1 x.

Uživatelský avatar
rnbw
Příspěvky: 32312
Registrován: 21 bře 2006, 01:00
Bydliště: Bratislava

#12 Příspěvek od rnbw »

Neviem, aky mas prekladac, ale GCC s -Wall hodi pri tomto pouziti warning (lebo je to takmer vzdy chyba).

Uživatelský avatar
AB1
Příspěvky: 312
Registrován: 23 lis 2009, 01:00

#13 Příspěvek 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.

Uživatelský avatar
rnbw
Příspěvky: 32312
Registrován: 21 bře 2006, 01:00
Bydliště: Bratislava

#14 Příspěvek 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.

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“