Autor: Dondu
Ponieważ co jakiś czas otrzymuję pytania dot. problemu znaku zapytania przy konwersji za pomocą funkcji z rodziny printf, sprintf, itp.:
Anonimowy
... kiedy importuje projekt do ATMEL Studio 6.1, linkuje 2 biblioteki libprint_flt.a i libm.a i wgrywam to już zamiast rps i ms/obr pokazują się pytajniki. Mógłbyś mi powiedzieć co robię źle?
... kiedy importuje projekt do ATMEL Studio 6.1, linkuje 2 biblioteki libprint_flt.a i libm.a i wgrywam to już zamiast rps i ms/obr pokazują się pytajniki. Mógłbyś mi powiedzieć co robię źle?
Anonimowy
... potem podczas proby wysylania cyfry w wyniku otrzymuje wyswietlony na ekranie znak zapytania.
... potem podczas proby wysylania cyfry w wyniku otrzymuje wyswietlony na ekranie znak zapytania.
Anonimowy
wysłanie liczby daje efekt w postaci "?"
wysłanie liczby daje efekt w postaci "?"
Anonimowy
Chciałbym na ekranie telefonu (chodzi o system Android - dop. red.) wyświetlać wartości odczytywane przez mikrokontroler z czujnika temperatury, niestety sposób przedstawiony powyżej generuje na ekranie pytajniki.
Chciałbym na ekranie telefonu (chodzi o system Android - dop. red.) wyświetlać wartości odczytywane przez mikrokontroler z czujnika temperatury, niestety sposób przedstawiony powyżej generuje na ekranie pytajniki.
postanowiłem skrobnąć ten krótki artykuł.
Chodzi o moment, w którym obliczoną liczbę typu float (zmiennoprzecinkową) konwertujemy za pomocą funkcji printf, sprintf, itp. do postaci ciągu znaków ASCII, w celu np. jej wyświetlenia na LCD, czy też wysłania za pomocą jakiegoś interfejsu np. RS-232C do odbiornika np. komputera.
Anonimowy
Na LCD wyświetla mi się"U=? [V]". Natomiast wartość nieprzeliczona wyświetla się normalnie.
Na LCD wyświetla mi się"U=? [V]". Natomiast wartość nieprzeliczona wyświetla się normalnie.
Objawy
Zamiast otrzymania za pomocą w/w funkcji prawidłowo sformatowanego wyniku w postaci ciągu znaków otrzymujemy znak zapytania.
Przykład - Spodziewasz się ładnie sformatowanych liczb:
Przykład prawidłowej konwersji liczb float na ciągi znaków. Pochodzi z artykułu: RS-232: Komunikacja ATmega8 z komputerem |
a otrzymujesz jedynie znaki zapytania (przykład dostarczony przez Anonimowego):
Przykład nieprawidłowej konwersji liczb float na ciągi znaków. |
Powyższy przykład pokazuje wysyłanie danych z mikrokontrolera w formie znaków ASCII przez RS-232 do komputera. Ale jak już wspomniałem wcześniej te same objawy dot. LCD, itp.
Rozwiązanie
Należy wykonać dwie czynności dodając w opcjach projektu:
1. dodanie bibliotek libm.a oraz libprintf_flt.a
Wersja dla AVR Studio:
Przykład dla AVR Studio 4.xx |
Wersja dla Atmel Studio:
Atmel Studio - ustawienia projektu. |
Atmel Studio - dodanie bibliotek. |
2. dodanie opcji linkera:
Wersja dla AVR Studio:
Przykład dla AVR Studio 4.xx |
Na niebiesko zaznaczyłem pole, w którym po kolei powinieneś wpisać wszystkie parametry i klikając przycisk Add, dla każdego parametru osobno. Efekt końcowy ma być taki jak na powyższym screen-ie - kolejność parametrów nie ma znaczenia.
Aby nie było wątpliwości co do literek:
-WI
-lprintf_flt
-lm
-u
vfprintf
Zauważ, że vfprintf jako jedyny nie ma poprzedzającego znaku minus (myślnika).
Szczegóły w zakresie opcji linkera znajdziesz pod niniejszym linkiem: <stdio.h>: Standard IO facilities
Wersja dla Atmel Studio:
Atmel Studio - opcje linkera. |
Nie zapomnij zapisać ustawień :-)
Witam
OdpowiedzUsuńUżywam Atmel Studio (wersja 6.0), dodałem biblioteki libm.a oraz libprintf_flt.a zgodnie z instrukcją (chociaż była już dodana domyślnie jedna biblioteka oznaczona "m" - usunąłem ją), nie mogę jednak wykonać drugiego kroku - nie mam w ogóle opcji Use vprintf libary. Co na to poradzić?
Z góry dziękuję za wszelką pomoc
Witaj. Jaką wersje AS masz zainstalowaną?
UsuńMam wersję 6.0.1703 - beta
UsuńFaktycznie za problem była odpowiedzialna wersja mojego Atmel Studio - po aktualizacji problem się rozwiązał. Dzięki Dondu, sam nie wiem dlaczego nie zwróciłem na to uwagi :)
UsuńDodałem bibliotekę libprintf_flt.a w atmel studio wersja 6.2 kilka dni temu w jednym projekcie i było ok. Teraz robię kolejny projekt i nie przyniosło to spodziewanego efektu. :/ Pamiętam że w pierwszym projekcie też miałem z tą biblioteką problemy ale jakoś ruszyło, teraz nie chce. Czy oprócz dodania biblioteki "libprintf_flt.a" bo libm już mam trzeba wykonywać jeszcze jakieś dodatkowe czynności ?
OdpowiedzUsuńZaznaczyć w opcjach linkwera Use vprintf library.
UsuńJest to pokazane w tym artykule na grafice z podpisem: "Atmel Studio - opcje linkera."
UsuńW eclipse należy pstąpić dokładnie tak samo jak to zostało opisane w artykule. Oczywiście inaczej wyglądają okienka w których dodaje się biblioteki i definiuje symbole. Rozwiązanie pokazane przez ciebie nie jest równoważne z użyciem sprintf - zapewnia konwersję float na ASCII lecz nie formatuje łańcucha.
OdpowiedzUsuńZaczęło działać, jednak teraz wynik na wyświetlaczu mi się zamraża na wartości pierwszej zmierzonej zaraz po uruchomieniu i przy zmienianiu pozycji pokrętła potencjometru nie zmienia się, jedynie od czasu do czasu spontanicznie się zmieni lub po dłuższym czasie. Przy wyświetlaniu samych kroków (adc bez modyfikacji) taka sytuacja nie ma miejsca. Czym to może być spowodowane?
OdpowiedzUsuńNiewielkie zmniejszenie czasu opóźnienia poprawiło sytuację jednak niewiele. Dodam, że dla mniejszych wyświetlanych wartości proces przebiega znacznie lepiej. Czy to możliwe, żeby funkcja sprintf() była aż tak zasobożerna?
UsuńJednak funkcja sprintf() nie ma na to wpływu. Problem pojawił się gdy mojemu mikrokontrolerowi przyszło wykonywać operację na zmiennych typu float wobec może to komentarz pod niewłaściwym postem, ale czy ktoś zna rozwiązanie tego problemu?
UsuńBez poznania Twojego programu nie mamy jak pomóc.
UsuńAnonimie, dodawałeś funkcję sei() przed rozpoczęciem pętli while(1) ?
UsuńPozdrawiam
Próbowałem zarówno sposobem Anonimowego, jak i sposobem wstawienia wartości -WI
OdpowiedzUsuń-lprintf_flt
-lm
-u
vfprintf
do opcji C/C++ Build
Korzystam z Eclipse, próbowałem to zrobić w sposób następujący:
Project Properties -> C/C++ Build -> Zakładka: Builder Settings -> Odhaczyć "Use default..." -> wybrać z listy wartości "-lprintf_flt... itd"
Jeśli gdzieś zbłądziłem, lub robię coś źle, to proszę o pomoc. Bo próbowałem też wielu innych rzeczy i nic nie pomaga.
Pozdrawiam
Nie pamiętam jak się to robi w Eclipse, ale gdy go używałem, to dało się to prawidłowo ustawić. Zastanów się jednak nad zmianą środowiska na oryginalne Atmel Sudio tym bardziej, że ma wbudowany symulator.
OdpowiedzUsuńDzięki za szybką odpowiedź :)
OdpowiedzUsuńNiestety Atmel Studio nie ma możliwości obsługi USBasp, wiem że napisałeś fajny poradnik jak to ustawić, ale niestety czegoś nie do końca zrozumiałem i odpuściłem gdy nie działało. Może kiedyś (wygląda na to że niedługo :P ) jeszcze raz nad tym usiądę i spróbuję ponownie. Póki co walczę z tym Eclipse.
Ritchie'go i Karnighana znalazłem implementację funkcji void itoa(int n, char s[]). Ma ona pewne wady, ale może warto spróbować...
*W książce Ritchiego
OdpowiedzUsuńWybaczcie, zmęczenie :P
Witam ponownie :)
OdpowiedzUsuńProblem rozwiązany, szczerze mówiąc nie ma potrzeby dodawania opcji w linkerze podanych w artykule powyżej (oczywiście są one na dłuższą metę przydatne).
Rozwiązaniem problemu konwersji i znaków zapytania jest zastosowanie funkcji:
char* dtostrf(double WartoscKonwertowana, signed char _width, unsigned char _prec, char *ŁancuchZnakowy);
Całość wyjaśniona jest w książce Pana Tomasza Francuza Język C dla mikrokontrolerów (str 91 wyd. Helion)
Pozdrawiam
Skąd wziąć te biblioteki?
OdpowiedzUsuńBo albo jestem ślepy albo ich nigdzie nie widzę bo za każdym razem jak wporwadze je z katalogu WinAvr i wprowadze te funkcje do linker options to dostaje błąd
c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/bin/ld.exe: cannot find -l\libm