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

[ATTiny2313/C] Zajmowanie pamięci przez operacje na float

ADI-mistrzu 26 Gru 2009 14:57 1575 4
  • #1 7437677
    ADI-mistrzu
    Poziom 30  
    Witam!
    Głowie się z tym nie wiem którą godzinę i nie mogę dojść czemu tak się dzieje.
    Mam tego typu program:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
     float m_sekundy_wtrysk=0, m_sekundy_obr=0, wynik2=0;
     uint8_t i=0, k=0, znacznik=0;
     float wynik=0;
    
     ISR(INT1_vect){ //przerwanie od złącza PD3 (INT1)
    	TCCR1B |= _BV(CS10); //start timera (przerwanie przez zrównanie)
    	sei(); //uruchomienie przerwań w przerwaniu
    	m_sekundy_wtrysk = 0;
    	k = 0;
    	i = 1;
    	while(i == 1){ //dopuki "i" równe 1... (blokada wyjścia z przerwania)
    		if( !(bit_is_set(PIND,3)) ){ //jesli brak sygnału na złączu PD3 to...
    			TCCR1B &= ~_BV(CS10); // zatrzymanie timera (przerwanie przez zrównanie)
    			i = 0; // "i" równe 0 (można wyjść z pętli)
    		}
    	}
    	TCNT1 = 0; //zerowanie licznika
    	TCCR1B |= _BV(CS10); //start timera (przerwanie przez zrównanie)
    	k = 1;
    	i = 1;
    	while(i ==  1){ //obliczanie czasu pomiędzy impulsami
    		if( bit_is_set(PIND,3) ){ //jeśli pojawił się sygnał na PD3 to...
    			TCCR1B &= ~_BV(CS10); // zatrzymanie timera (przerwanie przez zrównanie)
    			i = 0; // "i" równe 0 (można wyjść z przerwania)
    			znacznik = 1; // informacja że przerwanie miało miejsce
    		}
    	}
    	cli();	
    }
    
     ISR(TIMER1_COMPA_vect){ //przerwanie od zrównania licznika
    	TCNT1 = 0; // zerowanie licznika
    	if (k == 1){
    		m_sekundy_obr += 1; //zwiększ zmienną obrotów o 1   <============================= 1
    	}else{
    		m_sekundy_wtrysk += 1; //zwieksz zmienna czasu wtrysku o 1 <====================== 2
    	}
    }
    
    int main(){
    
    DDRD = 0x00; //Port D jako wejścia
    PORTD = _BV(PD2);
    
    DDRB = 0xFF; //Port B jako wyjścia
    PORTB = 0xFF;
    
    MCUCR |= _BV(ISC11) | _BV(ISC10); //Wzrastające zborze wyzwala przerwanie
    GIMSK |= _BV(INT1);// | _BV(INT0); //Włączenie przerwania od INT1 (PD3)
    
    TIMSK |= _BV(OCIE1A); //Przerwanie od zrównania z OCR1A
    TCCR1B = 0x00; //Timer wyłączony przy starcie
    OCR1A = 1000; //Przerwanie gdy wartość licznika równa 1000
    
    	sei();	//uruchomienie przerwania od sygnału
    
    	while(1){	//pętla nieskończona
    		if(znacznik){ //jesli nastąpiło przerwanie to...
    			cli(); //wyłącz przerwania
    ...
    			znacznik = 0; //wyzeruj znacznik przerwania
    			TCNT1 = 0; // zerowanie licznika
    			while(PIND & 3); //jeśli nadszedł sygnał, zaczekaj aż zniknie
    			sei(); //uruchom przerwania
    		}
    ...
    	}
    }
    


    Dwoma strzałkami zaznaczyłem mój problem.
    Ogółem program ma zliczać jak długo trwa sygnał i jak długa jest przerwa między sygnałami.
    Do tego celu stworzyłem pierwsze przerwanie które reaguje na pojawienie się sygnału i załącza drugie przerwanie, które pojawia się po zrównaniu licznika.
    Gdy się zrówna i wywoła drugie przerwanie, ma zwiększyć jedną z dwóch wartości.

    I nie wiem dlaczego, gdy są te 2 linijki program zwiększa się o jakieś 1.6kB. On próbuje tam coś konwertować ? Przecież to prosta operacja która ma tylko zwiększyć wartość zmiennej o 1.
  • Pomocny post
    #2 7437760
    boogdan
    Poziom 15  
    AVR nie ma operacji na liczbach zmiennoprzecinkowych (float). kompilator musi je jakoś emulować.
    jeśli nie jest to absolutnie konieczne nie stosuj zmiennych float.
  • #3 7437763
    janbernat
    Poziom 38  
    A na pewno potrzebujesz float?
    Operacje na czymś takim są pamięciożerne.
  • #4 7437836
    ADI-mistrzu
    Poziom 30  
    Ahaaa.... no tego to nawet bym się nie spodziewał.
    Żadne AVR nie obsługuje liczb zmiennoprzecinkowych ?

    Konieczne to takie nie jest, zawsze można liczbę zwiększyć o parę zer (i zwiększyć int'a) a potem tylko na wyświetlaczu odpowiednio wyświetlić.
  • #5 7437961
    boogdan
    Poziom 15  
    ADI-mistrzu napisał:
    Żadne AVR nie obsługuje liczb zmiennoprzecinkowych ?

    Wszystkie 8-bitowe mają ten sam rdzeń, więc żaden z nich nie obsługuje float-ów. nie wiem jak 32-bitowe, ich nie znam za dobrze.
REKLAMA