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

[ATmega128][C]przerwania nie wracają, reset uC: fuse M103C

nelik1987 08 Gru 2009 19:28 2742 11
  • #1 7362805
    nelik1987
    Poziom 31  
    Witam mam kolejny problem z nieszczęsną atmega128. Napisałem program który działał na ATmega16 i chciałem go przenieść do atmega128 no i jest problem. Program w ogóle nie działa. W przerwaniu powinny się zwiększać wartości zmiennych. Niestety chyba nie zwiększają się :/ program wchodzi do przerwania bo wstawiłem tam naprzemienne ustawianie i kasowanie stanu jednego bitu i wszystko działa. Niestety jak wstawiłem mój tester do funkcji. próbowałem napisać innego if'a ale niestety też nie działa


    if(overflow_ADC>=overflow_ADC_max)
    {
    LED_TOGGLE //tester
    overflow_ADC=0;
    }

    dodaję cały program, wyrzuciłem z niego dalszą część ponieważ najprostsza funkcja nie chce działać. Są tam również deklaracje wielu zmiennych którą są teraz niewykorzystywane:

    
    #include <avr/io.h>
    #include <avr/interrupt.h> 
    #include <avr/signal.h>
    
    /////// SILNIK 1 //////////////// PORT - E
    
    #define OUT1a_ON 	PORTE |= 	 _BV(0);
    #define OUT1a_OFF 	PORTE &= 	~_BV(0);
    
    #define OUT1b_ON 	PORTE |= 	 _BV(1);
    #define OUT1b_OFF 	PORTE &= 	~_BV(1);
    
    #define OUT1c_ON 	PORTE |= 	 _BV(2);
    #define OUT1c_OFF 	PORTE &= 	~_BV(2);
    
    #define OUT1d_ON 	PORTE |= 	 _BV(3);
    #define OUT1d_OFF 	PORTE &= 	~_BV(3);
    
    /////// SILNIK 2 ////////////////  PORT - E
    
    #define OUT2a_ON 	PORTE |= 	 _BV(4);
    #define OUT2a_OFF 	PORTE &= 	~_BV(4);
    
    #define OUT2b_ON 	PORTE |= 	 _BV(5);
    #define OUT2b_OFF 	PORTE &= 	~_BV(5);
    
    #define OUT2c_ON 	PORTE |= 	 _BV(6);
    #define OUT2c_OFF 	PORTE &= 	~_BV(6);
    
    #define OUT2d_ON 	PORTE |= 	 _BV(7);
    #define OUT2d_OFF 	PORTE &= 	~_BV(7);
    
    
    /////// SILNIK 3 ////////////////  PORT - B
    
    #define OUT3a_ON 	PORTB |= 	 _BV(0);
    #define OUT3a_OFF 	PORTB &= 	~_BV(0);
    
    #define OUT3b_ON 	PORTB |= 	 _BV(1);
    #define OUT3b_OFF 	PORTB &= 	~_BV(1);
    
    #define OUT3c_ON 	PORTB |= 	 _BV(2);
    #define OUT3c_OFF 	PORTB &= 	~_BV(2);
    
    #define OUT3d_ON 	PORTB |= 	 _BV(3);
    #define OUT3d_OFF 	PORTB &= 	~_BV(3);
    
    /////// SILNIK 4 ////////////////  PORT - B
    
    #define OUT4a_ON 	PORTB |= 	 _BV(4);
    #define OUT4a_OFF 	PORTB &= 	~_BV(4);
    
    #define OUT4b_ON 	PORTB |= 	 _BV(5);
    #define OUT4b_OFF 	PORTB &= 	~_BV(5);
    
    #define OUT4c_ON 	PORTB |= 	 _BV(6);
    #define OUT4c_OFF 	PORTB &= 	~_BV(6);
    
    #define OUT4d_ON 	PORTB |= 	 _BV(7);
    #define OUT4d_OFF 	PORTB &= 	~_BV(7);
    
    
    /////// SILNIK 5 ////////////////  PORT - D
    
    #define OUT5a_ON 	PORTD |= 	 _BV(0);
    #define OUT5a_OFF 	PORTD &= 	~_BV(0);
    
    #define OUT5b_ON 	PORTD |= 	 _BV(1);
    #define OUT5b_OFF 	PORTD &= 	~_BV(1);
    
    #define OUT5c_ON 	PORTD |= 	 _BV(2);
    #define OUT5c_OFF 	PORTD &= 	~_BV(2);
    
    #define OUT5d_ON 	PORTD |= 	 _BV(3);
    #define OUT5d_OFF 	PORTD &= 	~_BV(3);
    
    /////// SILNIK 6 ////////////////  PORT - D
    
    #define OUT6a_ON 	PORTD |= 	 _BV(4);
    #define OUT6a_OFF 	PORTD &= 	~_BV(4);
    
    #define OUT6b_ON 	PORTD |= 	 _BV(5);
    #define OUT6b_OFF 	PORTD &= 	~_BV(5);
    
    #define OUT6c_ON 	PORTD |= 	 _BV(6);
    #define OUT6c_OFF 	PORTD &= 	~_BV(6);
    
    #define OUT6d_ON 	PORTD |= 	 _BV(7);
    #define OUT6d_OFF 	PORTD &= 	~_BV(7);
    
    ///// LEDY //////
    #define LED_ON PORTC |= _BV(0);
    #define LED_OFF PORTC &= ~_BV(0);
    #define LED_TOGGLE PORTC ^= _BV(0);
    
    
    volatile uint16_t overflow_ADC=0;
    volatile uint16_t overflow1=0;
    volatile uint16_t overflow2=0;
    volatile uint16_t overflow3=0;
    volatile uint16_t overflow4=0;
    volatile uint16_t overflow5=0;
    volatile uint16_t overflow6=0;
    
    volatile uint16_t overflow_ADC_max=100;
    volatile uint16_t overflow1_max=10;
    volatile uint16_t overflow2_max=30;
    volatile uint16_t overflow3_max=100;
    volatile uint16_t overflow4_max=38;
    volatile uint16_t overflow5_max=30;
    volatile uint16_t overflow6_max=50;
    
    volatile char sw1a=0;
    volatile char sw1b=0;
    
    volatile char sw2a=0;
    volatile char sw2b=0;
    
    volatile char sw3a=0;
    volatile char sw3b=0;
    
    volatile char sw4a=0;
    volatile char sw4b=0;
    
    volatile uint16_t value;  // zapisywana wartość przetwornika
    
    
    volatile unsigned char stan1 = 3;
    volatile unsigned char stan2 = 3;
    volatile unsigned char stan3 = 3;
    volatile unsigned char stan4 = 3;
    
    volatile unsigned int value;			// zmienna przechowują stan wyjścia przetwornika ADC
    volatile unsigned int zakres=150; 		// wartść po jakiej ma nastąpić załączenie
    
    volatile uint8_t test=20;
    
    
    
    ISR (TIMER0_OVF_vect)
    {
    
        TCNT0 = 120;                // Załaduj wartość początkową do timera 0
    	overflow1++;
    	overflow2++;
    	overflow3++;
    	overflow_ADC++;	
    	
    }
    
    int main (void)
    {
    
    
    DDRB = 255; // Ustawienie rejestru B jako wyjݣie na silnik
    DDRC = 255; // Ustawienie rejestru C jako TEST
    DDRD = 255; // Ustawienie rejestru D jako wyjݣie na silniki
    DDRE = 255; // Ustawienie rejestru E jako wyjݣie na silniki
    DDRF = 0; // Ustawienie rejestru F jako Wejścia z pad'a
    
    
    
    TIMSK = _BV(TOIE0);        // wӹcz obsԵgꡰrzerwa񠷹woԡne timerem 0
    
    TCCR0  = _BV(CS02) | _BV(CS02) ;			//Ustawia timer0 z preskalerem 32
    
    ADCSRA = _BV(ADEN)|_BV(ADSC)|_BV(ADPS0)|_BV(ADPS2)|_BV(ADFR); // ustaw przetwornik ADC
    
    sei();                        // włącz obsługę przerwań
    
    while(1)  // Program główny
    {
    
    	if(overflow_ADC>=overflow_ADC_max)
    	{	
                    LED_TOGGLE
    		overflow_ADC=0;
    	}
    
    } 	//zamyka while
    }	//zamyka main
    


    Dodano po 21 [minuty]:

    napisałem krótszy program i na ATmega16 działa bez zarzutu czyli program wchodzi do funkcji if(overflow_ADC>=overflow_ADC_max) po osiągnięciu odpowiedniej wartości przez overflow_ADC a na ATmega128 nie działa, sprawdzałem też na innych portach, to gdzie może być błąd?

    
    #include <avr/io.h>
    #include <avr/interrupt.h> 
    #include <avr/signal.h>
    
    ///// LEDY //////
    #define LED_ON PORTC |= _BV(0);
    #define LED_OFF PORTC &= ~_BV(0);
    #define LED_TOGGLE PORTC ^= _BV(0);
    
    volatile uint8_t overflow_ADC=0;
    
    volatile uint8_t overflow_ADC_max=10;
    
    ISR (TIMER0_OVF_vect)
    {
    
        TCNT0 = 250;                // Załaduj wartoś początkową do timera 0
    	overflow_ADC++;	
    	
    }
    
    int main (void)
    {
    
    DDRC = 255; // Ustawienie rejestru C jako TEST
    TIMSK = _BV(TOIE0);        // wӹcz obsԵgꡰrzerwa񠷹woԡne timerem 0
    TCCR0  = _BV(CS02) | _BV(CS02) ;			//Ustawia timer0 z preskalerem 32
    
    sei();                        // włącz obsługę przerwań
    
    while(1)  // Program główny
    {
    
    	
    	if(overflow_ADC>=overflow_ADC_max)
    	{	
    	LED_TOGGLE
    		overflow_ADC=0;
    	}
    
    } 	//zamyka while
    }	//zamyka main
    
  • Pomocny post
    #2 7363011
    _Robak_
    Poziom 33  
    Ojj widze ze chyba chcesz za duzo na raz zrobic...
    
    TCCR0  = _BV(CS02) | _BV(CS02) ;
    

    Ani w jednej ani w drugiej atmedze nie jest to dzielnik przez 32. Nawet jak by tak bylo, to i tak masz gdzies to co pisalem wczesniej. Zostalo by ci 150 taktow zegara na wyjscie z przerwania i wykonanie maina, czy jest wystarczajaco byc moze, ale nie sadze zebys to w ogole sprawdzil.
  • #3 7363071
    tmf
    VIP Zasłużony dla elektroda
    A drugi problem, ktory akurat produkuje inne ciekawe rzeczy, w efekcie twoj program nie moze dzialac poprawnie to atomowosc operacji na zmiennych overflow. Porownanie:
    if(overflow_ADC>=overflow_ADC_max)
    przy wlaczonych przerwaniach moze prowadzic do bledow - zastanow sie co sie stanie jesli przerwanie wystapi pomiedzy porownaniem jednego a drugiego bajtu zmiennych. Nic dobrego.
    Podobnie przypisanie:
    overflow_ADC=0;
    nie zawsze zadziala tak jak chcesz.
  • #4 7363117
    nelik1987
    Poziom 31  
    racja tam zrobiłem błąd ale zmiana preskalera nawet na 1024 nic nie pomaga. najdziwniejsze jest to, ze na mega16 ten program działa i nie wiem dlaczego :/ jakie mogą być różnice pomiędzy tymi procesorami które uniemożliwiają uruchomienie tak prostego programu?
  • #5 7363164
    _Robak_
    Poziom 33  
    W takim razie sprawdz czy rejestry sa takie same, Czasami niektore bity wedruja pomiedzy rejestrami w zaleznosci od procka.
    Cytat:

    if(overflow_ADC>=overflow_ADC_max)
    przy wlaczonych przerwaniach moze prowadzic do bledow - zastanow sie co sie stanie jesli przerwanie wystapi pomiedzy porownaniem jednego a drugiego bajtu zmiennych. Nic dobrego.

    A problem atomowosci nie jest w przypadku zmiennych >8 bit ? Przeciez porownanie dwoch zmiennych 8 bit to jedna instrukcja procesora, pozniej ewentualny skok, ale przeciez po powrocie z przerwania SREG sie nie zmienia, wiec skoczy tam gdzie ma skoczyc :>
  • Pomocny post
    #6 7363342
    zumek
    Poziom 39  
    nelik1987 napisał:
    ... najdziwniejsze jest to, ze na mega16 ten program działa i nie wiem dlaczego :/ ...

    Ja stawiam na fusebit M103C :-D
  • #7 7363421
    nelik1987
    Poziom 31  
    Kurdę no przerwanie jest wywoływane co 310us a to jest bardzoooo wiele cykli zegara na to by mogła się wykonać cała pętla while, cały czas nie rozumiem czemu na atmega 16 działa a na atmega128 nie chce działać :/ sprawdzałem bity ustawiające timer i przerwanie, są one takie same dla mega 16 i 128 więc nie wiem w czym jest problem :(

    Ten program działa na 100% na atmega 16 i bez problemu można regulować czas wywołania przerwania poprzez wpisanie do licznika dowolnej liczby

    
    #include <avr/io.h>
    #include <avr/interrupt.h> 
    #include <avr/signal.h>
    
    ///// LEDY //////
    
    #define LED_TOGGLE PORTC ^= _BV(0);
    
    volatile int overflow_ADC=0;
    
    volatile int overflow_ADC_max=10;
    
    ISR (TIMER0_OVF_vect)
    {
    
        TCNT0 = 100;                // Załaduj wartoś początkową do timera 0
    	overflow_ADC++;	
    	
    }
    
    int main (void)
    {
    
    DDRC = 255; // Ustawienie rejestru C jako TEST
    TIMSK = _BV(TOIE0);        // wӹcz obsԵgꡰrzerwa񠷹woԡne timerem 0
    TCCR0  = (_BV(CS00) | _BV(CS01)) ;			//Ustawia timer0 z preskalerem 32
    
    sei();                        // włącz obsługę przerwań
    
    while(1)  // Program główny
    {
    
    	
    	if(overflow_ADC>5)
    	{	
    	LED_TOGGLE
    		overflow_ADC=0;
    	}
    
    } 	//zamyka while
    }	//zamyka main
    


    Dodano po 7 [minuty]:

    a tej chwili ma tak ustawione bity, z tego co przed chwilą czytałem to ten bit jest związany z kompatybilnością atmega103 i atmega128

    [ATmega128][C]przerwania nie wracają, reset uC: fuse M103C
  • #8 7363465
    tmf
    VIP Zasłużony dla elektroda
    _Robak_ napisał:
    W takim razie sprawdz czy rejestry sa takie same, Czasami niektore bity wedruja pomiedzy rejestrami w zaleznosci od procka.
    Cytat:

    if(overflow_ADC>=overflow_ADC_max)
    przy wlaczonych przerwaniach moze prowadzic do bledow - zastanow sie co sie stanie jesli przerwanie wystapi pomiedzy porownaniem jednego a drugiego bajtu zmiennych. Nic dobrego.

    A problem atomowosci nie jest w przypadku zmiennych >8 bit ? Przeciez porownanie dwoch zmiennych 8 bit to jedna instrukcja procesora, pozniej ewentualny skok, ale przeciez po powrocie z przerwania SREG sie nie zmienia, wiec skoczy tam gdzie ma skoczyc :>


    Ale jego zmienne sa 16-bitowe!

    Zumek - zaloze sie, ze masz racje :)
  • #9 7363470
    janbernat
    Poziom 38  
    "Ja stawiam na fusebit M103C"
    Ja też- a jakie są zakłady?
    A napisałem Ci o innych pułapkach w ATmega128 które tylko czekają aby Cię dopaść.:D
  • #10 7363475
    _Robak_
    Poziom 33  
    Nie gdzie tam ;) Pewnie nie wiesz, ale bit zaprogramowany (ptaszek) to 0 ;) Teraz twoja atmega pracuje w trybie zgodnosci z mega 103

    Dodano po 5 [minuty]:

    Cytat:


    Ale jego zmienne sa 16-bitowe!

    fakt, w int zobaczylem uint8_t ;) Swoja droga, kiedys dwa tygodnie walczylem z programem w code vision bo tam int ma 8 bitow ;) Po tym sie wyleczylem z takiego deklarowania zmiennych :)
  • #12 7363606
    janbernat
    Poziom 38  
    nelik1987-ściągnięcie PDF Atmega128 nic nie kosztuje.
    A to był pierwszy procesor Atmela który przyzwyczajenia odwrócił do góry nogami.
    Naprawdę trzeba to przeczytać.
    Jeszcze jest port C domyślnie ustawiony na debugger.
    I rejestry poza normalnym obszarem I/O.
    I adresowanie pamięci 128 a nie 64.
    Więcej nie pamiętam- ale może ktoś pamięta.
    I scal te pytania na temat ATmega128
REKLAMA