Aktywne Wpisy
Mega_Smieszek +270
toniemojekonto1 +147
Polscy mężczyźni jak zawsze gorsi od tych na zachodzie ( ͡º ͜ʖ͡º)
#p0lka #europa #statystyka #patologia
#p0lka #europa #statystyka #patologia
Skopiuj link
Skopiuj linkWykop.pl
Gdyby do momentu publikacji ktoś mi zarzucił że nic nie zrobiłem dla Polaków(jakby głosowanie w każdych wyborach na JKM nie wystarczyło), to wstawiam tu ten wydaje mi się wartościowy wpis z prawdziwym OPUS MAGNUM w kucowaniu na platformę #avr i nie tylko - biblioteką xprintf.
Jak mawiał klasyk i mój mentor Klocuch12:
I jak wykazała sonda uliczna - tak wygląda świadomość polskiego społeczeństwa na temat biblioteki xprintf:
https://www.youtube.com/watch?v=OO3FANjwKHY
No więc - xprintf to odpowiednik funkcji printf na dużych systemach dla mirkokontrolerów, jej autorem jest Pan posługujący się nickiem ChaN - bardzo utalentowany Japończyk, fan minimalizmu, ponadto twórca innej znanej biblioteki FatFS oraz Petit FatFS. Omawiana w tym wpisie wersja xprintf jest napisana w assemblerze, co oznacza że zajmuje minimum miejsca, i jest bardzo wydajna.
Co prawda jego strona http://elm-chan.org/ nie wygląda szałowo, ale content bardzo dobry, nawet chińskie bajki można mu wybaczyć.
Przeciętny nieświadomy kuc zapyta: NA CO MI TO?
Jak znam życie, to ten właśnie kuc pisząc swoje programy gdy będzie potrzebował wypisać przez UART choćby ilość załączeń swojego e-papierosa z grzałką sterowaną Arduino #pdk to będzie robił coś takiego:
char buf[16];
uart_print_str("eFajka start count: ");
itoa(cig_on, buf,10));
uart_print_str(buf);
uart_print_str("\n");
A tacy arduinowcy to myślicie lepsi? Gdzie tam, zrobią tak:
Serial.print("eFajka start count: ");
Serial.print(cig_on, DEC);
Serial.print("\n");
Posłuchajmy co na ten temat sądzi Pan Mariusz Pudzianowski - znany programista AVR:
https://www.youtube.com/watch?v=GisG7HRk-3k
Wiecie dlaczego pisanie jak wyżej jest #!$%@?? Z dwóch względów:
- do wypisania jednej liczby potrzebujecie 3, może 6 linijek kodu
- bajty z tego tekstu("eFajka start count:") lądują w cennej pamięci RAM
Jak wiadomo w niepisanych zasadach piwnicy jest taka jedna:
https://www.wykop.pl/cdn/c3201142/comment_rKQ6nslA6spAbP6l2a9Nu1BFP8ihzHX3.jpg
OSZCZĘDZAJ RAM GDZIEKOLWIEK JESTEŚ!
Na ten problem są 3 rozwiązania:
- w czystym C: dołożyć funkcję do wypisywania tekstów z pamięci programu i teksty obkładać makrem PSTR()
- w Arduino: dołożyć F() wokół tekstu: Serial.print(F(“Hello World”))
- użyć biblioteki xprintf jak człowiek z RiGCZem
Aby wypisać to co wyżej - na scenę wchodzi xprintf - cała na biało i myk:
xprintf(PSTR("eFajka start count: %d"), cig_on);
I tyle. Spoko nie?
Otóż wszystko czego potrzebuje ta biblioteka to funkcja putc wysyłająca znak przez dane medium - tak, dobrze czytacie, tu nie jesteśmy ograniczeni do UARTu, jak chcemy pisać po wyświetlaczu, to trzeba funkcji do wysłania znaku na wyświetlacz, jak chcemy drukować po betonie piaskiem to trzeba funkcji która wysypie jeden znak, xprintf zajmie się resztą.
No więc jak już mamy naszą funkcję do wysyłania znaku(może być z gotowej biblioteki):
załączamy nagłówek
#include "xprintf_asm/xprintf_asm.h"
inicjalizujemy normalnie nasz UART
uart_init(UART_BAUD_SELECT_DOUBLE_SPEED(19200,F_CPU));
I teraz najważniejsze - podajemy naszą funkcję do pisania bibliotece xprintf:
xdev_out(uart_putc);
Od tej pory możemy sobie wypisywać teksty tak jak na dużych systemach używając printf:
xputs(PSTR("NO WITAM WITAM\n"));
Pisać liczby dziesiętne:
'xprintf(PSTR("x=%d\n"),x);'
Opisywać punkty w 3D:
'xprintf(PSTR("x=%d y=%d z=%d\n"),x,y,z);'
Wypisywać w formacie szesnastkowym, lub binarnym:
xprintf(PSTR("x[hex]=%X x[bin]=%b\n"),x);
Wstawiać napisy warunkowo
xprintf(PSTR("x > 10? %s\n"), (x>10)?"YES":"NO");
Jest też jedna ważna zaleta tej biblioteki i w tym miejscu dobra rada, szczególnie dla arduinowców:
AVRy nie mają wbudowanego FPU i każda operacja na liczbach zmiennoprzecinkowych powoduje dołożenie do programu wieluset bajtów kodu wymaganego do liczenia, nie mówiąc o tym o ile to jest wolniejsze
Chcąc wypisać napięcie powiedzmy 4.060 w programie posługuj się milivoltami:
uint16_t milivolts = 4060;
I co teras?
A no wyciągniemy sobie cześć całkowitą i po przecinku:
xprintf(PSTR("milivolts %d.%d\n\n"), milivolts/1000, milivolts%1000);
Wypisało nam się takie cuś:
4060/1000=4V 4060%1000=60mV A no tak! policzyło dobrze, tylko w wypisywaniu brakuje zera na początku.
Papież Polak - Jan Paweł 2 zapytany czy biblioteką xprintf można dodać zera widące i ustawić ilość znaków na której liczba ma zostać wyświetlona odpowiedział:
https://www.youtube.com/watch?v=Scn4Gzqy0n4
Tak więc elegancko dodajemy %03d oznaczające: liczba będzie wyświetlana na 3 miejscach, jeśli nie ma 3 cyfr, to dopełnij z przodu zerami:
xprintf(PSTR("milivolts %d.%03d\n\n"), milivolts/1000, milivolts%1000);
I to by było tyle na dziś
Zapraszam na github po kod
https://github.com/QB4-dev/AVR-misc/tree/master/avr-xprintf-asm
Powyższe funkcje mają też przenośną implementację w C i można je wykorzystać na praktycznie każdej platformie na której brak domyślnego printf.
Kiedyś napiszę jak to spiąć z wyświetlaczem.
#mikrokontrolery #arduino #avr #stm32 #esp8266 #esp32 #qualitycontent #github #programowanie #qbadev
uint8t a = 10;
uint8t tab[10];
uint8t str[10];
itoa(a, (char*)(tab), 10);
sprintf(str, "%s.4.4 \n", (char*)(tab) );
Text.Write(str);
Akurat jak ktoś pisze na AVR to tam sprintf działa znakomicie. No chyba, że brakuje mu miejsca i chce się bawić. Za to sprintf jest potężną funkcją i ma mnóstwo opcji które na avr działają.
Ofc zjadło * przy rzutowaniu. Kompilator trochę się o to martwi.
No i jeszcze są funkcje dtostrf, dtostre
Z takich sposobów, to można jeszcze w podobny sposób jak opisany wyżej zmusić normalnego printfa do pisania na UART, czy gdziekolwiek tworząc własny strumień i przekierowując stdout do niego - tu na końcu jest:
http://hobby.abxyz.bplaced.net/index.php?pid=4&aid=8
Tak przy okazji - jest na vipok.ru taki mirek @msalamon który prowadzi bloga o STM32 - ja z nimi mało mam doświadczenia, a on bardzo ładnie i kulturalnie wszystko opisuje. Jeśli chcecie wiedzieć dlaczego używanie floatów na mikrokontrolerach jest przyrównywane do zbrodni wojennych, to tu bardzo dobry tekst z jego bloga
https://msalamon.pl/ile-kosztuje-uzywanie-float-i-co-daje-fpu/
http://elm-chan.org/fsw/strf/xprintf.html
Już nie mogę doczekać się kolejnych
Czekamy z niecierpliwością na link do githuba( ͡°( ͡° ͜ʖ( ͡° ͜ʖ ͡°)ʖ ͡°) ͡°
#include
#include
void printf_(const char *fmt, ...)
{
char buf[0x40];
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
wypchnij_bufor_na_co_tam_sobie_wymarzysz(buf);
}
zmieniasz se sygnaturkę na
void printf_(const PROGMEM char *fmt, ...)
Jak brakuje ci RAM-u, to zmieniasz mikrokontroler, kolego xD
Podobnie da się zrobić robiąc sobie własny strumień i przypisując do stdout a potem używać zwykłego printf