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

Optymalizacja kodu w WinAVR - problem z działaniem na symulatorze

ta5man 19 Lis 2005 16:02 1540 7
REKLAMA
  • #1 2005419
    ta5man
    Poziom 11  
    Posty: 16
    Witam, mam pytanie odnośnie optymalizacji wielkości kodu. Więc mamy sobie jakiś programik :
    
    #include <avr/io.h>
    uint8_t impulsy1;
    uint8_t impulsy;
    float   obliczenie;
    int main(void)
    {
      DDRB=0xFF;
      PORTB=0xFF;
      DDRB = 0x00;
      while(1)
      {
    	impulsy=0;
    	impulsy1=0;
      	while(impulsy!=255)
      	{
            	if(bit_is_clear(PINB,PB0))
            	{
                    	impulsy1++;
    		}
    		impulsy++;
      	}
       obliczenie = (float)impulsy1/(float)impulsy;
      }
    }
    


    i teraz jak mam włączoną optymalizację kodu to plik wynikowy ma 106 bajtów, ale na symulatorze nie działa poprawnie tzn. nie wykonują się żadne obliczenia, ani warunek nie jest sprawdzany. Działa pętla. Jak wyłącze optymalizację to wszystko jest ok i plik zajmuje 836 bajtów. O co w tym chodzi bo nie rozumiem tego ? :cry:
  • REKLAMA
  • Pomocny post
    #2 2005468
    Samuraj
    Poziom 35  
    Posty: 2792
    Pomógł: 286
    Ocena: 619
    Dlatego zapewne ze nic nie robisz ze zmienną obliczenie tak więc kompilato uznaje ze jest ona zbędna, a to niesie za soba zmienną impuls itp.
    I z całego programu zapewne posostaje
    
      DDRB=0xFF; 
      PORTB=0xFF; 
      DDRB = 0x00; 
    
  • REKLAMA
  • #3 2005486
    ta5man
    Poziom 11  
    Posty: 16
    w sumie tak, dzięki za wyjaśnienie, ale mam kolejne pytanie. Jak zamienić liczbę zmiennoprzecinkową na ciąg znaków, żeby wyświetlić ją na lcd? jest do tego jakaś mała funkcja, bo sprintf zajmuje trochę dużo miejsca?
  • #4 2005989
    Samuraj
    Poziom 35  
    Posty: 2792
    Pomógł: 286
    Ocena: 619
    Nie znam winAVR ale moze jest komenda itoa
    Ewentualnie mozna rozebrac na pojedyńcze cyfry i dodac 30 wtedy dla cyfry 0 bedzie 3, 1 - 31 itp. a to juz odpowiada kolejnym znakom.
  • REKLAMA
  • #5 2006366
    ta5man
    Poziom 11  
    Posty: 16
    i właśnie się zastanawiam jak rozdzielić na cyfry. Jedyne co mi przychodzi do głowy to dzielenie po kolei przez 100,10,1,0.1 itd i dodawanie 0x30, ale to wymaga dużo instrukcji i czasu. Jest jakiś inny sposób?
  • REKLAMA
  • #6 2006489
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    ta5man napisał:
    i właśnie się zastanawiam jak rozdzielić na cyfry. Jedyne co mi przychodzi do głowy to dzielenie po kolei przez 100,10,1,0.1 itd i dodawanie 0x30, ale to wymaga dużo instrukcji i czasu. Jest jakiś inny sposób?

    A ile miejsc po przecinku ma być :?:

    Piotrek
  • #7 2007086
    duzamasa
    Poziom 14  
    Posty: 99
    Pomógł: 5
    Ocena: 1
    void uint_to_string(unsigned int liczba, unsigned int dzielnik, const unsigned int ulamek, char* string)
    // dzielnik i ułamek musi być potęgą liczby 10, dzielnik i liczba muszą spełniać nierówność:
    // liczba > dzielnik > liczba/10
    {
    	while ( dzielnik != 0 )
    	{
    		if ( dzielnik == ulamek )
    			*string++ = '.';
    		*string++ = liczba/dzielnik + '0';
    		liczba %= dzielnik;
    		dzielnik /= 10;
    	}
    	*string = '\0';		// zakończenie łańcucha w C
    }
    
    


    Przykład użycia:
    char tab[20];
    uint_to_string(125, 100, 1, tab);
    

    zapisuje do tablicy tab łańcuch:
    12.5
  • #8 2007243
    shg
    Poziom 35  
    Posty: 2289
    Pomógł: 339
    Ocena: 135
    Panowie, panowie, ale koledze chodzi o zamianę liczby ZMIENNOPRZECINKOWEJ.

    A więc proponuję zapoznać się z funkcją dtostre() z biblioteki stdlib.h
    Opis znajdziesz w pliku:
    /WinAVR/doc/avr-libc/avr-libc-user-manual/group__avr__stdlib.html

    Zajmuje mniej miejsca niż sprintf()
    Cyfry rozdzielisz już bardzo łatwo, bo w końcu to łańcuch znaków, a nie liczba.

Podsumowanie tematu

LABEL_AI_GENERATED
Problem dotyczy optymalizacji kodu w WinAVR dla mikrokontrolerów AVR, gdzie włączenie optymalizacji powoduje znaczne zmniejszenie rozmiaru pliku wynikowego (z 836 do 106 bajtów), ale kod nie działa poprawnie na symulatorze – nie wykonują się obliczenia ani warunki, działa tylko pętla. Przyczyną jest usunięcie przez kompilator zmiennych i kodu, które nie są używane (np. zmienna obliczenie nie jest dalej wykorzystywana), co skutkuje pozostawieniem tylko ustawień portów. W dalszej dyskusji poruszono temat konwersji liczb zmiennoprzecinkowych na ciągi znaków do wyświetlania na LCD. Zamiast zajmującej dużo miejsca funkcji sprintf, zaproponowano użycie funkcji dtostre() z biblioteki stdlib.h, która jest bardziej oszczędna pamięciowo. Alternatywnie omówiono metody konwersji liczb całkowitych na łańcuchy znaków, np. funkcję uint_to_string() oraz prostą konwersję cyfr przez dodanie wartości 0x30. Dyskusja podkreśla znaczenie optymalizacji kodu i odpowiedniego wykorzystania zmiennych w programach AVR oraz efektywne metody konwersji liczb do formatu tekstowego.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA