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

atmega16 - reset po kilkudziesieciu przerwaniach

badzero 06 Wrz 2010 17:18 1443 6
REKLAMA
  • #1 8482221
    badzero
    Poziom 10  
    witam. od kilku dni probuje rozwiazac pewien problem. mianowicie ucze sie programowac avr'y i postanowilem zrobic budzik. jednak problem zaczal sie gdy zaczalem dzialac na przerwaniach. na wejscie int2 podany mam sygnal o czestotliwosci 1Hz. ma on co sekunde powodowac przerwanie w ktorym jest odczyt zegara oraz wyswietlenie go na wyswietlaczu 2x20 znakow. wszystko dziala dobrze az tu co niecale 60 przerwan atmega sie resetuje(czas nie ma znaczenia bo gdy robilem przerwania czesciej lub rzadziej to zawsze po danej liczbie przerwan byl reset). ktos ma jakies pomysly? dodam tylko ze: watchdog jest wylaczony, wszystkie inne przerwania takze sa wylaczone, atmega resetuje sie tylko gdy uzywam funkcji do obslugi wyswietlacza. gdy nie uzywam wyswietlacza wszystko jest w porzadku. wyswietlacz jest podlaczony do portu d. dzialam na plytce z propoxu evbavr 05. i jeszcze jedno: w rejestrze ktory pokazuje co bylo zrodlem resetu nic nie ma (tak jakby w ogole nie nastapil)
  • REKLAMA
  • #2 8482258
    gaskoin
    Poziom 38  
    może jakiś kod ?
  • REKLAMA
  • #3 8482329
    badzero
    Poziom 10  
    
    
    ISR (INT2_vect) 
    {	
            clear();	                                  //czysci lcd
    	display_time();                              //odczytuje czas i wyswietla go na lcd
    	gotoxy(2,0);
    	display_date();                             //odcztytuje date i wyswietla ja na lcd
     
    	sei();
    	__asm__ __volatile__ ("sleep\n\t"::);
    		
    }
    
    
    
    
    int main(void)
    {	
    	lcd_init();
    	
    	DDRA = 0x02;
    	PORTA = 0xff;
    	DDRB = 0xfb;
    	PORTB = 0xff;
    
    	lcd_display_string("reset");
    	_delay_ms(1500);
    		
    	GICR |= (1<<INT2);					// int2 enable
    
    	WDT_off();
    	
    	MCUCR |= (1<<SE);					//sleep enable
    	sei();
           __asm__ __volatile__("sleep\n\t"::);
    
    	
    	while(1);	
    
    	return 0;
    }
    



    jak widac nic szczegolnego. mysle ze przyczyna nie tkwi w kodzie
  • REKLAMA
  • Pomocny post
    #4 8482360
    szelus
    Poziom 34  
    Jak to nie. Przez sekwencję sei+sleep nigdy nie wychodzisz z obsługi przerwania, tzn. rozpoczynasz obsługę następnego przerwania zanim skończysz poprzednią. W efekcie przepełnia Ci się stos.
    Takich rzeczy po prostu się nie robi. Ogólnie rzecz biorąc, wyświetlanie z poziomu obsługi przerwania też jest niezgodne ze sztuką, chociaż tutaj nie spowoduje problemu. Obsługa przerwania powinna sprowadzać się do absolutnego minimum, było tyle razy.

    Ten sleep w programie głównym to powinien być wewnątrz while, a nie przed.
  • REKLAMA
  • #5 8489402
    kubus_puchatek
    Poziom 18  
    To prawda tak wolnych procesów jak obsługa LCD NIE WOLNO obskakiwać w przerwaniach.
  • #6 8489493
    gaskoin
    Poziom 38  
    wszystko zależy, ale raczej nie powinno się
  • #7 8495456
    badzero
    Poziom 10  
    dzieki za rady. wcielilem wszystkie w zycie i juz jest ok
REKLAMA