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

Konwersja char* -> float - problem [avr/atmega8][c/winavr

10 Lip 2009 02:59 5812 9
  • #1 6761097
    Konto nie istnieje
    Konto nie istnieje  
  • #2 6761189
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Końcówka pierwszego posta.

    https://www.elektroda.pl/rtvforum/topic1059204.html

    Dodatkowo należy nadmienić, że napisane jest o tym w dokumentacji do WinAVR, ale kto by to czytał...

    4\/3!!
  • #3 6764013
    AVRowiec
    Poziom 18  
    Dzięki za podpowiedź ale w WinAVR + PN2 nie ma dostępnych opcji linkera poza ustawieniami w makefile.

    Nie mam pewności czy to tutaj ale tylko tutaj jest coś o FLOATach. Dopisałem "-lm" w każde możliwe miejsce ale to nie pomogło. Skopiowałem całą tamtą instrukcje ale też nic to nie dało :(


    Oryginalny makefile wygląda tak:

    ---------------- Library Options ----------------
    # Minimalistic printf version
    PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min

    # Floating point printf version (requires MATH_LIB = -lm below)
    PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt

    # If this is left blank, then it will use the Standard printf version.
    PRINTF_LIB =
    #PRINTF_LIB = $(PRINTF_LIB_MIN)
    #PRINTF_LIB = $(PRINTF_LIB_FLOAT)


    # Minimalistic scanf version
    SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min

    # Floating point + %[ scanf version (requires MATH_LIB = -lm below)
    SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt

    # If this is left blank, then it will use the Standard scanf version.
    SCANF_LIB =
    #SCANF_LIB = $(SCANF_LIB_MIN)
    #SCANF_LIB = $(SCANF_LIB_FLOAT)


    MATH_LIB = -lm


    # List any extra directories to look for libraries here.
    # Each directory must be seperated by a space.
    # Use forward slashes for directory separators.
    # For a directory that has spaces, enclose it in quotes.
    EXTRALIBDIRS =



    Czy ktoś wie gdzie i co należy wpisać żeby konwertowało char do float? Może niekoniecznie w tym miejscu..? Może gdzieś w programie?
  • #5 6765619
    AVRowiec
    Poziom 18  
    Tak, wszędzie podstawiałem tą kombinacje:

    -Wl,-u,vfprintf,-lprintf_flt,-lm

    Gdzieniegdzie bez -lm na końcu lub bez przecinka między vfprintf i lpprintf_flt tak jak jest w oryginale. Krótko mówiąc sprawdzałem wszystkie możliwości a wynik nadal jest ten sam... :(

    Może ustawia się to jakoś inaczej?
  • #6 6765651
    arrevalk
    Poziom 25  
    A ja zadam inne pytanie, czy po dodaniu tego fragmentu z Twojego posta, dodałeś do linijek w makefile w miejscach gdzie wywoływany jest kompilator $(SCANF_LIB) oraz $(PRINTF_LIB)?. Bo co z tego ze zdefiniujesz zmienną w makefile jak jej nie wykorzystasz.
    Druga sprawa:
    
    # If this is left blank, then it will use the Standard printf version.
    PRINTF_LIB =
    #PRINTF_LIB = $(PRINTF_LIB_MIN)
    #PRINTF_LIB = $(PRINTF_LIB_FLOAT)
    

    oraz:
    
    # If this is left blank, then it will use the Standard scanf version.
    SCANF_LIB =
    #SCANF_LIB = $(SCANF_LIB_MIN)
    #SCANF_LIB = $(SCANF_LIB_FLOAT)
    

    Nawet jak byś w tej systuacji dodał SCANF_LIB do kompilacji to i tak nic się nie stanie bo wykomentowane są linijki z tymi przełącznikami.
    Należało by zakomentować tą pustą SCANF_LIB oraz PRINTF_LIB a odkomentować jedną z linijek która przypisuje im jakieś konkretne wartości
  • #7 6765886
    AVRowiec
    Poziom 18  
    Szczerze przyznam że budowa makefile jest dla mnie (ale pewnie nie tylko) magiczna. Owszem, wiem jak ustawić typ procka, taktowanie etc. Ale pozostałe instrukcje mogę się tylko domyślić czego dotyczą.
    Zmieniłem fragment dotyczący sscanf() (u siebie w programie używam w ten sposób: sscanf(s,"%f",&z); )

    Zaczeło działać dla takich ustawień w makefile:

    # Minimalistic scanf version
    SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min

    # Floating point + %[ scanf version (requires MATH_LIB = -lm below)
    SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt

    # If this is left blank, then it will use the Standard scanf version.
    SCANF_LIB =
    #SCANF_LIB = $(SCANF_LIB_MIN)
    SCANF_LIB = $(SCANF_LIB_FLOAT)


    Jedyna zmiana jakiej dokonałem to odkomentowanie wytłuszczonej linijki.

    Ruszyło. Teraz na lcd mam liczba z przecinkiem, ale....

    W takim fragmencie kodu:

    double z=0; // double lub float
    char *s = "3.1487";
    out= sscanf(s,"%f",&z);

    if (z==3.1487) lcd(10,2," ok"); else lcd(10,2,"err");

    // zamiana liczby na string i wyświetlenie
    dtostrf(z,5,6,bufor);
    lcd(1,2,bufor);


    Jak mówiłem na lcd jest prawidłowy wynik, tj 3.148700 (bo dtostrf wyświetla do 6 liczb po przecinku [trzeci parametr]).
    Gdybym jednak chciał sobie "zaokrąglić" (bo być może tylko przyciąć) wynik w ten sposób "%.2f" to ta instrukcja nie zadziała. Dodawanie -lm do SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt kończy się błędem kompilacji, w dodatku nieopisanym a co ciekawsze wyłażącym dopiero po Make Clean. W sumie i tak nie wiem co "-lm" oznacza więc robie to metodą chybił-trafił.

    Grunt że udało się przekonwertować stringa na zmiennoprzecinkową. Dziękuje za pomoc wszystkim. Ale jeśli ktoś ma opis makefile po polsku to niech tutaj zamieści. Tam jest poukrywane więcej rzeczy niż mi się zdawało.
    (Prosze nie zamykać tematu. Jeszcze poeksperymentuje i zamieszcze tu jakieś podsumowanie)
  • #8 6768886
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Manual do GNU make:

    http://www.gnu.org/software/make/manual/

    Po polsku nie znajdziesz, więc nawet nie ma większego sensu szukać.

    Co do -lm to w skrócie dodaje on do kompilowanego programu bibliotekę libm.a, która zawiera wszystkie funkcje z nagłówka math.h. W mniejszym skrócie - jeśli w swoim katalogu bibliotek masz plik o nazwię libXYZ.a, to aby dodać go do kompilowanego programu trzeba do wywołania linkera dodać -lXYZ

    4\/3!!
  • #9 7226420
    Piotrek_I
    Poziom 12  
    Panowie ja mam troszkę inny problem z konwersją. Konwertuje mi ale tylko do dwóch miejsc po przecinku. Czego to może być wina?
    Ja potrzebuję cztery miejsca. Zawsze mogę przecinek przesunąć a potem podzielić liczbę przez 100 ale wolałbym tak nie robić.
    Wszystko z tego tematu i tego z linka próbowałem i ciągle to samo.
    Konwertuje mi z łańcucha tylko dwa miejsca po przecinku.
  • #10 7465538
    AVRowiec
    Poziom 18  
    That's why atof() nie działało:

    zabrakło:

    #include <stdlib.h>
REKLAMA