W związku z pewnym wątkiem na elektrodzie, gdzie pewien ŚPEC, chciał pokazać jaki to on mądry oceniając wszystkich jako dzieci, przedstawił pewien wzór na obliczanie wartości UBRR (na potrzeby UART'a) tyle że jak to bywa zwykle u takich śpeców, nawet nie raczył wyjaśnić innym o co chodzi. Ja stwierdziłem w tamtym temacie że dobry jest także inny wzór (zresztą zgodny z notą PDF procków), który sam stosuję na co dzień czyli:
ale rzeczywiście w pewnym zakresie miał rację ten śpec, i trudno żebym nie przyznał się do błędu gdy trzeba. Otóż ten wzór zadziała perfekcyjnie dla taktowania procesora za pomocą tzw: "kwarców przyjaznych dla RS232" czyli ... tych o wartościach:
1.8432 MHz
3.6864 MHz
7.3728 MHz
11.0592 MHz
14.7456 MHz
18.4320 MHz
Natomiast dla tych które mają że tak powiem okrągłe wartości jak np: 1 MHz, 4 MHz, 8 MHz, 16 MHz czy 20 MHz i podobnych ten wzór może powodować przekłamania na tyle spore, że wyliczona wartość do rejestrów UBRRH i UBRRL spowoduje ustawienie bardzo odchylonej prędkości BAUD RATE czyli innymi słowy mówiąc zwiększy nam procent błędu bardzo mocno na tyle że czasem może to powodować kłopoty z komunikacją jeśli chcemy stosować tego typu "okrągłe" kwarce przy transmisji RS232.
Niech za przykład posłuży zadanie jakie mi zadał śpec czyli próba obliczenia wartości UBRR za pomocą tego wzoru, którego stosowałem na co dzień, gdybym zechciał użyć właśnie np kwarca 20 MHz i prędkości baudrate = 115200. Rzeczywiście wyjdzie to tak - zobaczcie:
20 000 000 / 16 / 115200 - 1 = 9.85
a gdy zerkniecie do noty PDF do tabelki na ostatniej stronie rozdziału UART dla taktowania 20 MHz to sami zobaczcie wartość do UBRR powinna być = 10. Tymczasem nasza obliczona wartość 9.85 za pomocą tego wzoru zostanie obcięta do wartości 9. Niestety nie nastąpi zaokrąglanie gdyż działamy na liczbach całkowitych więc części ułamkowe zostają po prostu odrzucane.
zwróćcie uwagę proszę, na wartości powyżej z tabeli. Widać że nawet dla wartości UBRR = 10 i tak mamy 1,4% błędu. Ale to nadal poniżej 2% więc można śmiało korzystać nie obawiając się o kłopoty podczas transmisji. Tak jest dla błędów sięgających w wartości bezwzględnej od 0 do 2%. Przy większych błędach można już się czasem liczyć z kłopotami przy transmisji między urządzeniami. Więc przy okazji wiecie już jak dobierać sobie taktowanie procesora i prędkość Baudrate. Przy tej okazji widzicie też co oznacza nieformalne określenie "kwarc przyjazny dla RS232" bo jak obejrzycie inne tabelki w tym rozdziale to zauważycie właśnie te kwarce "nie okrągłe" wymienione przeze mnie wyżej jak np mój ulubiony 11,0592MHz. Zwróćcie uwagę że dla nich przy każdej prędkości baudrate procent błędu = 0. Z tego prosty wniosek, że jeśli chcecie w urządzeniu, które dajecie do klienta stosować PEWNĄ transmisję RS232 to warto procka zaopatrzyć w kwarc zewnętrzny o jednej z takich "przyjaznych" wartości ;)
I właśnie w przypadku tego typu kwarców wzór który stosuję i który podałem w swoich książkach ZAWSZE SIĘ SPRAWDZI. Nadmienię tutaj także, że innym powodem sięgnięcia po kwarc zewnętrzny gdy mamy robić transmisję RS232 jest także fakt, że nasze urządzenie będzie miało docelowo pracować w skrajnie różnych temperaturach, mówię tu np o pracy na zewnątrz, gdzie temperatury w zimę mogą spadać np do -20 st C a w lato mogą osiągać +30 st C. Niestety taka rozpiętość temperatur będzie negatywnie wpływać na pracę wewnętrznego oscylatora RC w procesorze, gdybyśmy go zastosowali a przez to może się znacznie zmieniać taktowanie F_CPU no i jak się domyślacie rozjeżdżać się prędkość baudrate. Dlatego wtedy TRZEBA bezwzględnie dawać zewnętrzny kwarc do procesora. Chyba że jeśli urządzenie ma pracować w pomieszczeniach zamkniętych w temperaturze pokojowej czyli ok 25 st C (plus/minus 10 st) to wtedy można popędzać sobie procka na wewn. oscylatorze RC wykonując jednocześnie transmisję RS232 i przy założeniu też, że nie jest to jakieś np urządzenie od którego zależy życie ludzkie ;) bo wtedy lepiej jednak znowu sięgnąć po zewn. kwarc.
Ale dobrze - zakładając więc że stosujemy okrągłe kwarce z jakichś względów, i chcemy mieć transmisję RS232 to ten wzór nie będzie jednak działać poprawnie jak pokazałem wyżej:
Musimy coś z tym zrobić, jednak zastanówmy się najpierw w szczegółach do czego może doprowadzić nas ta wyliczona wartość UBRR = 9 zamiast prawidłowej jak w nocie 10, i z czego to wynika.
Otóż znając UBRR i taktowanie możemy wyliczyć sobie w drugą stronę ze wzoru w nocie PDF
jaką otrzymamy tak na prawdę prędkość baudrate zamiast oczekiwanej 115200 a dzięki temu z kolejnego wzoru
policzymy jaki wyjdzie nam procent błędu. Zatem do dzieła obliczamy sobie baudrate:
20 000 000 / ( 16 * ( 9 + 1) ) = 125000 !!! (widzicie aż 125000 zamiast 115200)
więc liczymy procent błędu zgodnie z drugim wzorem:
((125000 / 115200 ) - 1 ) * 100% = 8,5% błędu !!!!
jak widzicie to dużo więcej niż dopuszczalne 2% (o czym wspominałem wyżej) .... więc narażamy się nawet na to że taka transmisja może być obarczona błędami. Może ale nie musi gorzej byłoby jeszcze gdyby procent błędu wyszedł na poziomie > 20% ... wtedy to już KLOPS. Ale ok chyba i te 8,5% nam się nie podoba prawda ?
Z czego to wynika ? spójrzmy jeszcze raz na obliczenie podane na początku:
20 000 000 / 16 / 115200 - 1 = 9.8506944444
gdyby tak udało się nam jakoś zaokrąglić tą liczbę zgodnie z zasadami zaokrąglania to przecież wyszłaby nam oczekiwana wartość = 10 zgadza się ? ;) No ale to niemożliwe ponieważ przecież posługujemy się do obliczeń TYLKO liczbami całkowitymi :( .... hmmmmm czy to jednak oznacza, że nie ma wyjścia ?
Owszem jest - ale zanim pokażę nowy wzór chciałbym żeby każdy zrozumiał dokładnie o co tu chodzi. Otóż pomyślcie zastosujemy taki mały TRICK. Wyobraź sobie na początek taki przypadek, chcemy dokonać podziału kilku liczb przez 10 :
79 / 10 = 7.9 ---- wynik = 7
76 / 10 = 7.6 ---- wynik = 7
74 / 10 = 7.4 ---- wynik = 7
71 / 10 = 7.1 ---- wynik = 7
gdy wykonamy te działania na liczbach całkowitych to zdajesz sobie sprawę, że w wyniku za każdym razem otrzymamy wartość = 7 ponieważ część ułamkowa zostanie po prostu obrzydliwie odrzucona. W związku z czym dwa pierwsze działania są nie zaokrąglone prawidłowo - zgadza się? te na czerwono. Ale możemy teraz zastosować lekkie zwiększenie precyzji dla naszych potrzeb na liczbach całkowitych zgodnie z takim wzorem:
wynik = ( a + b/2 ) / b
spróbujmy więc wg tego wzoru wykonać dokładnie powyższe działania
( 79 + 10/2 ) / 10 = 8.4 ---- wynik = 8
( 76 + 10/2 ) / 10 = 8.1 ---- wynik = 8
( 74 + 10/2 ) / 10 = 7.9 ---- wynik = 7
( 71 + 10/2 ) / 10 = 7.6 ---- wynik = 7
widzisz co się teraz "cudownego" stało ;) ???? .... zobacz okazało się że taki wzór powoduje prostą rzecz - wynik zostaje zawsze zwiększony o 0.5 !!! ;) SUPER i o to nam chodziło. Zapamiętaj to sobie bo może ci się taki sposób przydać podczas programowania w języku C, szczególnie tam gdzie chcemy unikać typów float i double a jednocześnie właśnie zaokrąglać prawidłowo liczby, które są wynikiem działań na liczbach całkowitych. Zamiast więc stosować tak jak dotąd:
wynik = a / b
gdzie pozbywamy się zaokrąglania, możesz spokojnie zastosować
wynik = ( a + b/2 ) / b
mam nadzieję że to widzisz ??? w związku z tym wzór z noty PDF na obliczanie tym razem UBRR:
Możemy teraz zamienić zgodnie z tym co wyżej napisałem na taką postać:
( ( FOSC + (16 * BAUD) / 2 ) / (16 * BAUD) -1 )
dlaczego tak? Ponieważ nasze:
a = FOSC
b = 16BAUD
dlatego będzie prościej zapisać to w ten sposób ostatecznie
( FOSC + BAUD * 8UL ) / (16UL * BAUD) -1
mi teraz na to fajnie się patrzy i co ważniejsze taki wzór zadziała już absolutnie prawidłowo z każdą częstotliwością taktowania. Dlatego przykłady w kodzie można zmienić na:
#define UART_BAUD 9600
#define __UBRR ((F_CPU+UART_BAUD*8UL) / (16UL*UART_BAUD)-1)
i będzie OK ;)
gdyby ktoś jeszcze czegoś nie zrozumiał to proszę śmiało pytać - chętnie pomogę.
A przy okazji pokażę link do strony na pewnym zagranicznym forum, gdzie na spokojnie ludzie potrafili to sobie wyjaśnić:
http://www.mikrocontroller.net/topic/170617#1631916
a nie tak jak to robią takie śpece u nas w Polsce, przez co dyskusje na naszych forach zamieniają się w sieczkę. Tak więc żeby śpec nie płakał to pokazałem link z którego sobie troszkę poczytałem i przekazałem tam zdobyte informacje.
Przy okazji na KONIEC - ponieważ niektóre osoby już zadały mi pytanie czy nie prościej byłoby zamiast TAK DZIWNEGO wzoru po prostu odejmować 0.5 zamiast 1 i to powinno rozwiązać sprawę - czyli rzekomo tak:
UBRR = F_CPU / 16 / BAUD - 0.5 ------- ( ŹLE )
To zapraszam jednak do sprawdzenia tego sobie na żywo i wyświetlenia wyniku UBRR. Niestety tak nie można i nie przyniesie to żadnego rezultatu. Działamy tu na liczbach całkowitych a próba odjęcia wartości 0.5 chociaż z ciekawości możecie spróbować odjąć 0.4 albo 0.1 ZAWSZE przyniesie ten sam efekt - czyli tak jakbyście próbowali odjąć 1.0 niestety. Ja też w pierwszym momencie wpadłem na taki pomysł na szybko, ale tak samo szybko wybiłem go sobie z głowy ;)
UPDATE ;)
jeszcze inny użytkownik elektrody o nicku: michalko12
zaproponował jeszcze inne równie ciekawe alternatywne rozwiązanie i bardzo fajne:
( FOSC / 16.0 / BAUD - 0.5 )
Ja próbowałem z samym 0.5 no ale trzeba było jeszcze wymusić użycie liczb zmiennoprzecinkowych poprzez zapis 16.0 Tak więc mamy dwa alternatywne i bardzo dokładne sposoby/wzory do użycia.
------------------------------------------------
UPDATE! 27 marca 2013r
Uwaga! w związku ze sporą ilością pytań odnośnie faktu, iż rzekomo nie działają podane wyżej prawidłowe sposoby obliczeń UBRR dla wszystkich częstotliwości taktowania oraz wszystkich prędkości baudrate - zamieszczam tę aktualizację artykułu i wyjaśniam - odpowiadam na kilka najczęściej zadawanych pytań i stawianych zarzutów. Postaram się wyjaśnić dlaczego osoby pytające , poddające w wątpliwość omawiane tu sprawy - mylą się i wyjaśnię gdzie popełniają błąd w swoich rozważaniach. Mam nadzieję, że to pomoże też innym - zapraszam:
Otóż najczęstsze pytanie jest tego typu jak z naszego forum:
Kłopot pytającego polega na tym iż próbuje on dokonywać obliczeń wg tego wzoru:
( FOSC + BAUD * 8UL ) / (16UL * BAUD) -1
zaprzęgając do pracy albo zwykły kalkulator albo np Excela .... no i nieszczęście gotowe ;) .... dlaczego ? ano dlatego że zarówno kalkulator jak i Excel nie dokonują tych obliczeń na liczbach CAŁKOWITYCH tylko używają "po drodze" własnych zaokrągleń i stąd przeliczenia wychodzą źle.
Tymczasem mikrokontroler w podanym niżej przykładzie czy też preprocesor w ogóle nie używają zaokrągleń i działają w pełni na liczbach całkowitych .... jak się zatem o tym przekonać ale tak hmmm PRAKTYCZNIE - bo myślę że taki sposób wyjaśnienia będzie najlepszy zamiast próba nawet wnikania w głąb samych obliczeń. Proszę poniżej przedstawiam krótki kod źródłowy, który napisałem dla AVR i który to spowoduje prześliczne obliczenie po kolei dla KAŻDEJ z podanych w PDF na ostatniej stronie rozdziału UART (każdej noty pdf avra) .... wartości UBRR więc możecie nawet sami go skompilować, odpalić i porównać jak procek to robi ;) .... ale to nie wszystko pokusiłem się także o wyliczenie rzeczywistej prędkości baudrate zakładając że wychodzi błąd podany w tabelach w % ale także wartość samego błędu ;) zgodnie zresztą ze wzorami w każdej nocie PDF. Więc macie wszytko podane pięknie - i każdy może sam to sobie sprawdzić jak coś - pomimo to że pokażę niżej wyniki tych obliczeń. A gdzie postanowiłem wyświetlić wyniki obliczeń ? ano w terminalu .... a co ? skoro jest pod ręką ;) więc proszę - porównać zrzuty ekranu poniżej z tabelami w PDF.
Uwaga! gdyby ktoś chciał zobaczyć przykład z życia wzięty, jak i kiedy może się przydać i DLACZEGO taki sposób o którym tu piszę, to proszę sobie zajrzeć np do tego wątku na naszym forum:
poniżej przykładowe zrzuty ekranów:
A poniżej proszę kod źródłowy :
-----------------------------------
-----------------------------------
Burak z ciebie wyłazi Mirku, a słoma z butów, zgodnie z twoim wykształceniem w Akademii Rolniczej w Szczecinie. Kompleksy braku wykształcenia zostaw dla siebie, a swoją frustrację wyładowuj na rodzinie.
OdpowiedzUsuńJa tobie kolego z uczelni, również życzę wszystkiego najlepszego w nowym roku ;)
UsuńKolego z uczelni może pochwalisz się swoim wykształceniem i osiągnięciami bo po tym co piszesz, to wiadć że wystaje Ci słoma z butów, a burak z kieszeni. Chyba po wczorajszej imprezie dopadł Cię kompleks dnia jutrzejszego czyli dzisiejszego, dopadleś kompa i wyładowałeś swoją frustrację. Życzę Ci dużo zdrowia, rozwagi i zorsądku, braku kompleksów i frustracji, przyda Ci się w Nowym 2013 roku.
UsuńKolega z uczelni pewnie w samotności spędził sylwestra, tylko patrzył jak inni się bawią, spędzają czas z rodzinami/znajomymi. Smutno mu się zrobiło i musiał jakoś odreagować. Teraz, po napisaniu komentarza jest szczęśliwy, sylwestra może zaliczyć do jednych z lepszych w jego życiu. Pozdrawiamy Cię kolego z uczelni. Szczęśliwego nowego roku.
Usuńkolega z uczelni pewnie doktor srabilitowany , cierpisz panie na pewną chorobę co sie nazywa przerośnięte ego, ego większe od tego bebzona co go chowasz pod stołem , takie ludzie to najgorsze ścierwo , sam studiuje na politechnice i często obserwuje takich nadentych bufonów co oczywiście znają się na rzeczy ale robią z siebie dalajlame 14 i wymagają do siebie szacunku jak do pozłacanego bożka. Pan Mirosław wyszedł do ludzi ze swoją wiedzą i za to bardzo go szanujemy , to Pan Mirosław jest ojcem Polskiej elektroniki a nie takie nadenty gbur.
UsuńPrzykro się czyta takie wpisy jak "Kolega z uczelni". W Polsce w ten sposób dyskutuje się.
OdpowiedzUsuńZawsze zastanawiam się skąd wynika takie zachowanie jak kolegi "Kolega z uczelni". Może z zazdrości? Nie mam pojęcia ale to jest tak prostackie, że aż śmieszne.. Zamiast podziękować to ehh.. Szkoda gadać..
OdpowiedzUsuńDzięki Mirku za kolejny poradnik. Można się tutaj wiele nauczyć..
Po prostu jakis ćwok chciał choć przez chwilkę poczuć się ważny... Najlepszym sposobem docenienia jego ambitnej twórczości niech będzie całkowita ignorancja...
OdpowiedzUsuńGratulacje dla autora, dzięki takim wpisom mnóstwo początkujących nie będzie popełniać tego typu błędów.
Mirku dzięki za poradnik i że z uporem maniaka przekazujesz tak cenną wiedzę. Wszystkiego najlepszego w nowym roku.
OdpowiedzUsuńArek
Witam serdecznie kolegów to mój pierwszy wpis na tym forum i co trafiam na takie fajne pogadanki o burakach i słomie , normalnie czuje się prawie jak u siebie na wsi bo z stamtąd pochodzę i się tego nie wstydzę.
OdpowiedzUsuńKolego z uczelni jeśli chcesz komuś przygadać to pokonaj go na tym samym poziomie choćby wychowania i kultury osobistej bo inaczej oberwie ci się od forumowiczu , znane zjawisko z innych skupisk ludzkich myśli jakim jest forum.
Panie Mirku, pisze Pan: "ale rzeczywiście w pewnym zakresie miał rację ten śpec". Ciekawi mnie w jakim zakresie nie miał racji ten człowiek, który podał Panu to rozwiązanie. Mógłby Pan to wyjaśnić? Kiedy wzór przez niego podany działa źle?
OdpowiedzUsuńProszę przeczytać uważniej tekst wyżej i się nie zacietrzewać. Napisałem że miał rację po części - wymyślając mi że napisałem całkowitą bzdurę, i wyjaśniłem że wzór którym ja się posługiwałem działa bezbłędnie dla kwarców przyjaznych "RS232" przyznając jednocześnie, że popełniłem BŁĄD, i sam przez to zachowałem się jak śpec .... Bo korzystając zawsze z kwarców przyzjaznych RS232 nigdy nie pokusiłem się tak na prawdę o sprawdzenie wyników tego wzoru dla tych kwarców o okrągłych wartościach. Przecież PISZĘ o tym wyżej w artykule. WCALE nie pisałem że ŚPEC nie miał racji i proszę mi nie wciskać czegoś czego nie powiedziałem. A nazwałem go ŚPEC bo zachował się poniżej krytyki na forum przez co zresztą cały ten temat trafił tam do KOSZA i słusznie.
UsuńAle doprecyzuję skoro pytanie zadane jest kulturalnie i nie tendencyjnie. Otóż ŚPEC podał wzór który działa dla KAŻDEJ częstotliwości taktowania i to BEZBŁĘDNIE. I obliczyłem zgodnie z jego sugestią UBRR dla 20MHz i baudrate 115200 moim wzorem i wyszła KICHA, a jego wzorem wyszło OK. Tyle że określił wszystkich mianem dzieci i nawet nie podjął się próby wyjaśnienia o co chodzi innym osobom.
Dlatego ja nie miałem przy jego podejściu do ludzi na forum, nawet ochoty pytać go ani wdawać się w polemikę. Sam zacząłem szukać po necie i znalazłem fajne wytłumaczenie na stronie pewnego niemieckiego forum i podałem kurka wodna wyżej LINK - nie widać ?
Widać! ... jak ktoś sobie przetłumaczy z niemieckiego to zobaczy jak spokojnie, przyjaźnie i bez żadnego obrażania innych czy wyśmiewania ludzie tłumaczą tam to zagadnienie jeden drugiemu nawet jeśli po drodze ktoś przez kilka postów nie może tego zrozumieć. ZERO naśmiewania się lub pisania takich tekstów jak SPEC napisał .... po tym gdy ukazało się moje wyjaśnienie na moim blogu. Otóż przyczepił się, że odebrałem mu chwałę ;) ... SZOK, więc go zapytałem dlaczego sam nie wyjaśnił - tylko nazwał pytających DZIEĆMI!. A mi odpowiedział na to - że nie wyjaśnił bo nikt go o to nie zapytał. I tu się różnimy - mnie NIKT nie musi pytać jak JAŚNIE WIELMOŻNEGO PANA, ja sam z siebie bez pytania chętnie opisuję to co wiem i dzielę się wiedzą. Nie mam tej wiedzy dużej, być może mniejszą niż ŚPEC, jestem początkujący w tej dziedzinie i wciąż się uczę. Ale ŚPEC wtedy powiedział dalej - że nawet nie było co tłumaczyć - bo po co ?????? po co - skoro to matematyka z klasy podstawowej ;) ... to jest podejście prawidłowe do innych ??? może porównaj to podejście z podejściem na forum niemieckim do którego podałem link - bo O TO SAMO CHODZI ... a pięknie i klarownie wytłumaczone. Wręcz opisane jako TRICK - bo tak jest w istocie - tylko trzeba wpaść na ten pomysł. A nie każdy jest gieniuszem jak ŚPEC.
I dlatego OPISAŁEM TUTAJ o co chodzi w tym wzorze i podałem wyjaśnienia precyzyjne. A zainteresowanych tamtym biciem piany zachęcam to poszukania w koszu tego forum - to znajdą to o czym mówię.
Powiem więcej, pojawił się też inny użytkownik w tej dyskusji - wspomniany przeze mnie wyżej: michalko12, którego to sposób jeszcze inny również podałem - a ty panie kolego (pewnie znasz ten link i go tu wklejałeś co chwilę) .... zobacz sobie także jak jego potraktował ŚPEC - w zasadzie każdego trak traktował kto miał inne zdanie niż on. Dla mnie ludzie takiego pokroju to ŚPECE.
A ja ? jestem jeszcze raz przypomnę - zwykłym człowiekiem, nie geniuszem, i popełniam błędy i potrafię jak widać się do nich przyznać.
NA TYM KOŃCZĘ ten temat - i każdy następny wpis o ŚPECU usunę bezwzględnie. KONIEC.
Może jeszcze dla kolejnych osób niedowidzących tego że przyznałem się do błędu - proszę obrazek na potwierdzenie - bo zdaje się że słabo czytają niektórzy:
Usuńhttp://forum.atnel.pl/_obrazki/o/54_d11f77d345dae7e6452dadc1b290d447.jpg
Dziękuję za wyjaśnienie. Nie wiem co prawda, dlaczego zarzuca mi Pan zacietrzewienie, ale korzystając z Pana sugestii zajrzałem na to niemieckie forum i rzeczywiście jestem pod dużym wrażeniem. Kiedy ten Niemiec podał wzór, to nikt na niego nie naskakiwał, że ten prostszy wzór jest dobry i nikt nie kwestionował tego, co on podał. Faktycznie niektórzy Polacy mają się czego uczyć od Niemców.
OdpowiedzUsuńTo nie jest wpis o śpecu, więc ufam, że go Pan nie usunie.
Pozdrawiam i dziękuję za wyjaśnienie.
Nie usunę i przepraszam bo się chyba pomyliłem - myślałem że to kolejny raz ten sam anonimowy co z uporem maniaka wklejał tu link do kosza na forum z tamtą dyskusją "biciem piany"
UsuńSuper że zwróciłeś właśnie uwagę na to podejście na niemieckim forum. Ale pewnie wiesz że to nie tylko specjalność Niemców - weź sobie chociaż anglojęzyczne forum znane AvrFreaks i wiele wiele innych - praktycznie NIGDY nie spotkasz się tam z TAKIM podejściem jak u nas w POLSCE - no MASAKRA. Dlatego bezwzględnie z tym walczę - hmmm może jak z wiatrakami ale co by nie mówić to jednak nasze forum przyciąga sporo osób myślących podobnie i mających dość takich ŚPECÓW właśnie wszelkiej maści.
Nie oceniam przy tym innych forów w tym elektrody - jak mi też ktoś kiedyś zarzucił. Co można zarzucać elektrodzie ? największemu forum w Polsce ? NIC - to tylko ludzie je tworzą i bywają okresy gdy więcej bywa tych normalnych - ale też bywają okresy jak ostatnio gdzie aż roi się od ŚPECÓW, których naczelnym zadaniem jest pokazać co to nie oni.
Dlatego gdybym miał źle mówić o elektrodzie to bym tam nigdy nie wchodził - a jednak jestem bo i tam znam sporo fajnych osób - aczkolwiek ostatnio siedzą raczej tylko jako obserwatorzy i czekają aż minie ta śpec-fala. Bo tak to jest że co kilka lat przychodzi ale w końcu jak śpece zostają we własnym gronie to sami się wybijają w diabły ;) i znowu można również tam spokojnie prowadzić dyskusje. Powiem więcej korespondowałem z Gulsonem i czasem sam denerwowałem się na tamtejszych niektórych moderatorów ale niepotrzebnie - bo po prostu nie rozumiałem ile oni mają do roboty, a robią to społecznie i nie zawsze mają czas na osądzanie kto miał rację w sporach ... i wywalają wszystko do kosza i może i dobrze - wystarczy spojrzeć ilu tam jest userów ;) i ile może zdarzyć się w takiej fali śpeców w jakimś okresie.
Śpec hahaha. Jak sie Mirek czyta to określenie w każdym prawie zdaniu, to człowiek zaczyna się normalnie śmiać sam do monitora. Śpec to śpec. Hah! Zarozumiali ludzie na elce nie powinni sie w ogóle odzywać. Zamiast zgrywać cwanika lepiej zamknąć jape. Bo to w realu są takie leszcze, co mądrzy są tylko w klikaniu w Internecie. Łatwo jest krytykować innych. Sami niech pokażą jak sie tworzy poradniki i artykuły, to chetnie porównamy. Zawsze można coś zrobić lepiej od drugiego, ale trzeba zacząć coś robić, a nie tylko pierdolić. Trollowanie to nie styl bycia, a swego rodzaju schorzenie wynikające z braku akceptacji wśród otaczającego społeczeństwa i samotności spowodowanej egzystowaniem jako pan i władca. Wyładowują sie na forach, bo poza Internetem nikt ich nie może słuchać. Olać śpeców.
OdpowiedzUsuńPróbowałem użyć tego ostatniego wzoru w jednym starym projekcie na starym procesorze, ale kompilator napisał coś jak "floating point not supported". Potem spróbowałem zrobić to samo w urządzeniu z ATmega8 i też porażka - kompilacja przeszła, ale kod spuchł tak, że nie wchodzi w 8K pamięci. Dlaczego?
OdpowiedzUsuńPozdrawiam
SN
Dlaczego? Używaj nowszych narzędzi, czyli najnowszej wersji WinAVR albo Atmel Toolchain. Nic nie poradzę ci na to że lubisz starocie, to już twoja sprawa.
UsuńNie mówiąc już o tym, że się czepiasz bo masz pierwszy wzór i z niego korzystaj na starociach.
UsuńNo bo tam wpisujesz potajemnie float a nie int i wątpię, żeby to zadziałało w ogóle. Najlepiej sobie zrobić coś takiego:
Usuń#define BAUD 9600 //Prędkość transmisji
#define _UBBR ( FOSC / 16.0 / BAUD - 0.5 )
A potem przy inicjalizacji:
uint16_t _ubr = _UBBR ; //Dla U2X = 0
/*Ustawienie prędkości*/
UBRRH = (uint8_t) (_ubr >> 8);
UBRRL = (uint8_t) _ubr;
Na ATmega używam Atmel Studio 6. Jakie nowsze narzędzia możesz polecić, żeby program po dodaniu tego wzoru zmieścił się w ATmega8? Wcześniej zajmował trochę ponad 8K. Optymalizację mam włączoną, ale nie pomaga.
OdpowiedzUsuńJeśli pierwszy wzór działa dobrze, to po co ten drugi, co nie działa?
SN
Oczywiście zajmował trochę ponad 7K, a nie 8K.
OdpowiedzUsuńTo nie zależy od Atmel Studio czy od Eclipse bo to są TYLKO edytory panie kochany. Więc nie do końca jak widzę wiesz co porównujesz i co robisz. To jedno. Poza tym skąd ja mogę wiedzieć co ty tam masz w tym kodzie i jak to jest napisane ? Po trzecie zarówno przy użyciu WinAVR z 2010r czyli jego ostatniej wersji pod Win, ale także Atmel Toolchain 3.4 (czyli tego, który jest w AVR Studio 6) ... wzór działa dobrze i to niezależnie czy się go wykorzystuje na poziomie preprocesora czy kodu źródłowego przy wyłączonej obsłudze liczb zmiennoprzecinkowych. Ale jak masz kłopoty z użyciem go w kodzie to albo zastosuj pierwszy albo zrób ten drugi jak się uparłeś "nie wiedzieć czemu" chociaż ja ptaszku wiem czemu się uparłeś ale mniejsza o to ;) ... to zastosuj go na poziomie preprocesora.
UsuńPanie Mirku.
OdpowiedzUsuńTrochę jestem zdezorientowany bo na tego bloga trafiłem przypadkiem i dopiero po jakimś czasie zorientowałem się że jest Pan autorem ostatnich 2 książek które zakupiłem :) "Słoma w butach" ?
To chyba zazdrość albo jakaś forma rozładowywania emocji.
Tylko to by oznaczało że mamy do czynienia z kobietą :) Zdesperowana fanka ? :) Normalny mężczyzna ma zupełnie inne zakodowane mechanizmy rozładowywania stresu.
Staram się czytać Pana książki w każdej wolnej chwili. Niestety nie mam tych chwil za dużo bo przed nimi jest cała masa obowiązków i praca ..praca .. i praca.
Postanowiłem jednak wrócić do swojego życiowego hobby i podładować się pozytywną energią.
Przyznam się szczerze że trochę Panu "zazdroszczę" .. przynajmniej "dedykacji" do 1 książki :) Ja niestety muszę działać w bardzo kwaśnym środowisku i jestem mocno tępiony za swoje pasje :(
Trzymając się powiedzenia że każdy mężczyzna "musi wybudować dom .. spłodzić syna i posadzić drzewo " .. dodałem jeszcze od siebie " i zbudować robota !"
Niestety muszę już kończyć bo mam dyżur i właśnie słyszę płacz mojego następcy :) Na szczęście ma TAAAK wielkie ciągoty do pakamerki, że nawet żona jest zaskoczona :) Już oznajmiliśmy że się tam (niedługo) zamkniemy "na dłużej" .. :) i uciekniemy przed tymi "babami" .. niech sobie gadają i rozładowują emocje .. we własnym gronie .. :)
Bardzo dziękuję za przekazywaną wiedzę. To pocieszające, że zdecydował się Pan podążać za swoja Pasją :) Oby takich ludzi było więcej i oby mieli możliwości z tego wyżyć :)
Pozdrawiam
Kordian
Niesamowicie miło czytać mi, że moje książki były jakąś inspiracją do powrotu do swojej pasji, hobby etc ;)
UsuńNastępca dopiero rośnie ;) ale jak podrośnie ... i załapie bakcyla, zarazi się tym ..... no to krótko mówiąc będzie albo przybędzie nam dwóch kolejnych zarażonych ;) i tego koledze życzę.
Tak przy okazji zapraszam również na nasze przyjazne forum, które ostatnio gromadzi właśnie takich pasjonatów ;)
www.forum.atnel.pl
gdzie można sobie na prawdę fajnie podyskutować i wymieniać doświadczenia w tym zakresie.
Ehh Mirek. Też parokrotnie doświadczyłem na naszym rodzimym "znanym portalu elektronicznym" takiego potraktowania, że jakbym mógł to bym cwaniaczka przez kabel telefoniczny wciągnął do swojego monitora i Paintem paszczękę nieco przerobił.
OdpowiedzUsuńNiestety takie sytuacje doprowadzają do tego, że pomocy szuka się gdzie indziej. W przypadku Twojej witryny jest o tyle fajnie, że zarówno na Twoim forum jak i bezpośrednio od Ciebie zawsze uzyska się pomoc.
To jest właśnie powód dla którego swego czasu z przeproszeniem olałem udzielanie się w "znanym portalu" i założyłem własną witrynę, na której żaden pseudo "mundry" dzieciak neostrady nie jedzie po mnie jakbym był Frankiem spod budki z piwem.
Kawał świetnej roboty wykonujesz! I oby nie podcinali Ci skrzydeł malkontenci:) (Na szczęście masz duży dystans do siebie i z humorem to przyjmujesz)
Święte słowa powiadasz z tymi "rodzimymi cwaniaczkami" ... Dlatego masz rację z własną witryną bo na niej można się ich pozbywać i oddzielać jak plewy od ziarna. Tymczasem na forach trudno ich wyplenić .... są jak chwasty, na które nie działa już żaden RANDAP ;)
UsuńSwego czasu w obiegu był Cyklon B... Sorry za mój wisielczy humor. =P
OdpowiedzUsuńhahahaa dobre, ale obawiam się, że ta polska mutacja malkontenta to sproszkowany cyklon B zajada na śniadanie a płynny Randap jako herbatkę stosuje ;) ..... oni są odporni ;)
UsuńDlatego Mirek - w życiu kieruję się prostą zasadą: zawsze idź swoją drogą, nie daj satysfakcji wrogom. :)
OdpowiedzUsuńZostałem mile zaskoczony, bo przypadkiem trafiłem na Twój blog i jak sądzę to mój temat na forum elektrody wywołał tak gorliwą dyskusję, że aż napisałeś o tym artykuł.
OdpowiedzUsuńDziękuję!
Nie ma za co, po prostu na Śpeców z ele nie ma co liczyć , dlatego poszukałem trochę informacji tu i ówdzie a następnie podzieliłem się tym ;)
UsuńJa w mojej medze32 z kwarcem 16 MHz obliczam zgodnie z opisem datasheet i działa komunikacja prawidłowo, sprawdzone dla różnych prędkości:
OdpowiedzUsuń#define F_CPU 16000000UL
#define BAUD 9600
#define MYUBBR ((F_CPU/(BAUD*16UL))-1)
Niestety robisz same błędy. Pierwszy NAJPOWAŻNIEJSZY to fakt, że definiujesz w kodzie #define F_CPU xxxx, to jest niestety BEZ SENSU :(
UsuńDruga sprawa - jeśli chodzi o to co napisałem i wzór którego używasz i którego ja zwykle używałem - to mocno nadal czegoś nie rozumiesz albo nie chciało ci się przeczytać dokładnie artykułu i ew prób własnych zrobić.
Więc przypomnę - ten wzór który jest na początku artykułu i ten który używasz jest generalnie prawidłowy i jak obliczasz go na PC czy na kalkulatorze to ZAWSZE wyjdzie ci prawidłowa wartość - a to z uwagi na precyzję obliczeń na liczbach zmienno-przecinkowych i odpowiednie zaokrąglenia. Tymczasem gdy próbujesz to zrobić w kodzie albo za pomocą preprocesora - to niestety obliczenia odbywają się na liczbach całkowitych i następuje spora różnica w wynikach dla wielu różnych częstotliwości taktowania i prędkości baud rate. Opisałem to i pokazałem dokładnie wyżej wraz z przykładami.
Napisałem też, że dla standardowych kwarców przyjaznych dla RS232 akurat zawsze ten wzór zadziała nawet przy obliczaniu na liczbach całkowitych, ale już dla innych częstotliwości taktowania przy niektórych prędkościach baud rate wystąpią znaczne błędy związane z błędnym zaokrąglaniem ....
nie chce ci się sprawdzić ? lubisz się przejechać na własnych błędach a nie na cudzych? - proszę bardzo każdy może ;)
ale sorki - nie patrz przez czubek własnego nosa - że coś ci tam akurat działa. Akurat dla częstotliwości którą używasz i baud rate może działać - chociaż nie wiem dlaczego pominąłem akurat 16MHz w przykładach - warto sobie jednak zrobić próbę - a pokazałem nawet kod źródłowy... tyle że trzeba chcieć się czegoś dowiedzieć, nauczyć .... a nie w kółko powtarzać
"a mi działa"
Dobrze. Dziękuje za odpowiedź. Dodam, że próbowałem z wzorem UBRR=F_CPU/16/BAUD -1 i nie działało dla 16 MHz, natomiast ((F_CPU/(BAUD*16UL))-1) zadziałał. Ale ok. Przeczytałem wątek z forum, który podałeś w swoim artykule i wykorzystałem do obliczenia UBRR bibliotekę setbaud.h dołączoną do atmel studio. Dodam, że wykorzystuje ona nowy wzór, który tutaj podałeś w swoim artykule. Jednak wymaga ona definicji F_OSC, jak to zrobić w takim przypadku, żeby nie było to jak to stwierdziłeś błędem i bez sensu tak jak w przypadku, który umieściłem poprzednio??? Proszę o wyrozumiałość.
UsuńPozdrawiam i dziękuje za rozmowę Paweł
No widzisz w ECLIPSE robi się wszystko o wiele łatwiej, szkoda że nie chcesz spróbować ECLIPSA ? gorąco polecam - chociaż sprawdzić a zobaczysz że będzie żyło się lepiej ;) Zresztą w Eclipse też można korzystać z setbaud.h itp
Usuńwracając do F_OSC .... no to trzeba zdefiniować sobie to F_OSC ..... jeśli to F_OSC czy pomyliło ci się z F_CPU ? pytam bo ja zwykle nie korzystam z tego setbaud.h ... dlatego nie pamiętam...
Generalnie w AtmelStudio musisz zdefiniować samo F_CPU we właściwościach toolchaina - trzeba się tam dogrzebać...
W Eclipse nie ma w ogóle problemu z F_CPU ponieważ częstotliwość taktowania ustawiasz RAZ we właściwościach projektu tam gdzie wybierasz procka i masz dostępne F_CPU przez makefile (gdzie zostaje to dodane automatycznie) dostępne w całym projekcie
poczytaj proszę o Eclipse na tym blogu jak coś ok?
Dzięki Mirku,
UsuńWybrałem Atmel Studio ze względu na shell Visual Studio ponieważ wcześniej trochę w nim pracowałem. ECLIPSE nie próbowałem ale nie mówię nie, na tą chwile po prostu wcale go nie znam, w wolnym czasie może wypróbuje.
Co do F_OSC to chodziło faktycznie o F_CPU, które wymagane jest przez setbaud.h, mój błąd.
Po napisaniu tego komentarza poszperałem trochę po internecie i znalazłem odpowiedź na pytanie dlaczego moja wcześniejsza definicja okazała się błędna i jakie wiążą się z tym konsekwencje, szczególnie przy większych programach. Również w Atmel Studio doszedłem jak to zrobić. Dzięki, bo nie wiedziałem o tym. Uczę się sam i później wychodzą braki. Na szczęście aplikacje, które tworzę do tej pory startują bez problemu, z czego się cieszę, w czym na pewno pomogło programowanie w C# mimo, że obiektówka i C to dwa inne światy.
A o Eclipse poczytam na pewno :)
Pozdrawiam Paweł
Witam Panie Mirku. Mam pytanie. tz. czy mogę podłaczyć poprzez mój uC atmega168A-PU i jego USART oraz konwerter RS232(TTL)->USB PENDRIVA?? A dokładnie podłączyłem juz sam uC do konwertera i łącze się z komputerem poprzez Hyperterminal. Odbieram i wysyłam dane (init_uart działa poprawnie). Ale chce zrobic to samo bez PC czyli komunikować się z PENDRIVEM i odebrać plik txt w którym mam np. tekst po prawidłowym odebraniu którego zapali mi się np dioda. Dodam że mam możliwość zasilenia konwertera zasilaniem zewnętrznym(wyprowadzone piny Vcc oraz GND)
OdpowiedzUsuńDodam jeszcze że jeśli wysyłam ów plik txt poprzez hyperterminal to dioda zapala się, czyli zwykłe odbieranie pliku txt i zapisywanie pod odpowiednie miejsca w tablicy, a potem ich warunkowanie działa również poprawnie.
OdpowiedzUsuńOj, koledze coś się musiało totalnie ale to totalnie pomylić chyba ... albo coś źle opisałeś i ja nic z tego nie rozumiem.
UsuńPowiem tylko jedno ... podłączyć procka ATmega168 do pendrive poprzez konwerter USB/RS232 ???? to jest TOTALNE nieporozumienie :(
zapomni kolega o tym na wieki ... trzeba poczytać troszkę sobie o USB, o tym co to jest Host w USB. Poza tym ... przejściówka USB/RS232 to przejściówka USB/RS232 ..... a nie przejściówka do Pendrive - bo co? Pendrive miałby wg kolegi jak terminal działać ? .. nie nie sorki nie idźmy w ogóle tą drogą i nie próbujmy nawet wyjaśniać - to nieporozumienie.
Jeśli chcesz z poziomu procesora zapisywać coś na Pendrive to tak będzie to możliwe ale weź w ręce odpowiedni typ procesora ARM, który będzie miał wbudowany sprzętowy moduł Hosta USB. Wtedy będziesz musiał nauczyć się programować przez USB (zapomnij o tym co robisz w terminalu) ... i wtedy też będziesz sobie działał z plikami na pendrive.
hmm. Ja nie chce zapisywać nic na pendrivie. Chce jedynie odczytać zawartość jedynego pliku znajdującego się na pendrivie. I jest to plik txt, a dokładnie ciąg znaków np 1234, który to ciąg zostanie wpisany do tablicy jako klucz a następnie jeśli klucz jest prawidłowy to wykonaj coś.. np zapal diode. Nic więcej. Czy jest to możliwe bez kombinowania z tym Hostem USB.
OdpowiedzUsuńAle to kompletnie nieważne co kolega chce tam zrobić :( totalne pomieszanie pojęć niestety. Pendrive to nie terminal :( ....
Usuńnie dość że procek musi obsługiwać HOST'a USB to jeszcze zapis czy odczyt pliku wcale nie polega na tym co kolega robi teraz - czyli że coś tam wysyła do terminala lub z niego odczytuje. :(
Tz. Jeśli chce komunikować sie z pendrivem to MUSZE zakupić moduł hosta.ok . ale czy z poziomu uC moge komunikowąć sie z Hostem za pomocą UART??
OdpowiedzUsuńJeśli taki Host USB dostaniesz to pewnie tak ale nie myśl że to będzie polegało na wysłaniu danych z procka jak do terminala :(
UsuńUżywam przejściówki ATB-USB-RS232 oraz modułu ATB- BTM-222 moduł wpięty do przejściówki), więc myśle że nie ma mowy o złym podłączeniu. W porównaniu z komunikacja RS-232 wyciągłem tylko zworkę TTL . Mam mianowicie taki problem, że chcąc wpisywać literę np'A', pojawia się 5 literek A, co jakićczas krzaczek, co jakiś czas inna litera. Kod:
OdpowiedzUsuń#include
#include
#include
#include
#include
#define UART_BAUD 19200
#define _UBRR (F_CPU/16/UART_BAUD-1)
void usart_Init(uint16_t baud) //inicjalizacja USART
{
UBRRH=(uint8_t)(baud>>8);
UBRRL=(uint8_t)baud;
UCSRB=(1<<RXEN)|(1<<TXEN);
UCSRC=(1<<URSEL)|(3<<UCSZ0);
}
void usart_Transmit(char data); //wysyłanie jednego znaku
void usart_TransmitString(char *str); //wysyłanie ciągu znaków -stringów
int main()
{
usart_Init(_UBRR);
usart_Transmit(16); //wysyłanie znaku A -przy każdym resecie
while(1)
{
usart_Transmit('N');
_delay_ms(1000);
}
}
void usart_Transmit(char data)
{
while (!(UCSRA&(1<<UDRE)));
UDR=data;
}
void usart_TransmitString(char *str)
{
uint8_t dlugosc;
uint8_t k=0;
dlugosc=strlen(str);
for (k=0; k<dlugosc; k++) {
usart_Transmit(str[k]);
}
}
Proszę o pomoc wygląda na to iż jest to problem z prędkością?
Przykro mi ale jak można pomóc na blogu gdzie nawet kodu nie widać :(
UsuńToż ma kolega i nasze forum:
www.forum.atnel.pl
ma kolega maila do mnie
ma również kolega namiar na Skype do mnie (nick: mirekk36)
absolutnie nie będę analizował tutaj tego problemu - bo jest źle opisany. Zapraszam albo na forum, albo na Skype albo na telefon - wtedy szybciej i skuteczniej pomogę
Podziwiam ludzi takich jak Pan Mirek, za bezinteresowną pomoc innym użytkownikom oraz czas poświęcony na prowadzenie bloga, forum itp. Oczywiście nie twierdzę Panie Mirku, iż chciał Pan kogoś obrazić jednakże doszukuję sie pewnej ironi w słowie ŚPEC, przez co ktoś mógłby odebrać Pana słowa jako obraźliwe, a Pan wyszedłby na uszczypliwego, zarozumiałego eksperta, który pozjadał wszystkie rozumy. Oglądając Pana filmy wiem, iż w swojej wypowiedzi używa Pan wielu figur retorycznych jednakże niekiedy (jeżeli zwraca się Pan do osoby w formie uczeń nauczyciel, mentor) warto powstrzymać się (ze względu na Pana autorytet) i porzucić comparatio. Pozdrawiam.
OdpowiedzUsuńKłopot polega na tym, że jakoś nie wszyscy mogą zrozumieć a nawet nie chcą zaakceptować tego co powtarzam nie raz otwartym tekstem, i przypomnę to także tym razem. Ja nigdy, nie robię z siebie żadnego eksperta, tym bardziej (broń Boże mentora itp) .... Nigdy też do nikogo się nie zwracam jak do ucznia, bo ja nie uczę ....
UsuńJa sam się uczę, sam jestem początkujący, nie znam się na wielu rzeczach, a po prostu staram się przekazywać na gorąco tym czego sam się dowiedziałem. Nie zawsze jest to idealny przekaz, popełniał błędy i liczę tylko na odrobinę wyrozumiałości gdy się pomylę w tym co mówię. Cieszę się, że jest wiele osób, które to rozumieją i potrafią docenić a także kulturalnie zwrócić mi uwagę .... bez obrażania i wszczynania kłótni. Wtedy ja również się uczę ....
Daleko mi do bycia nauczycielem .... ale jeśli ktoś chce mnie posłuchać jako znajomego , czasem nawet gawędziarza i gadułę, jako początkującego, który być może jest czasem kilka kroków przed np niektórym widzem, jako kolegę - to szczerze zapraszam ...
Witam.
OdpowiedzUsuńSzukam szukam i nie mogę znaleźć, jak ktoś będzie miły i mi wskaże miejsce gdzie znajdę dlaczego UBRRH i UBRRL ustawia się w następujący sposób to będzie fajnie.
UBRRH = (uint8_t) (_ubr >> 8);
UBRRL = (uint8_t) _ubr;
Pozdrawiam.
To się nazywa jawne rzutowanie, w tym przypadku do typu uint8_t. Proponuję poczytać książkę http://atnel.pl/mikrokontrolery-avr-jezyk-c.html to więcej rzeczy się wyjaśni niż tylko to rzutowanie
Usuńczuję się trochę jakbym odgrzewał baaardzo starego kotleta i jeśli to robię po raz kolejny to proszę o wyrozumiałość. Ale czy zmodyfikowany przez Mirka wzór:
OdpowiedzUsuńUBRR = ( FOSC + BAUD * 8UL ) / (16UL * BAUD) -1
nie "ładniej" byłoby zapisać w formie:
UBRR = ( FOSC / 8UL / BAUD - 1) / 2
??
Moim zdaniem taki zapis jest bardziej czytelny, i od razu widać skąd się bierze ta (słuszna zresztą) modyfikacja.
Moim zdaniem - tzn może inaczej - dla mnie ta druga forma właśnie w ogóle jest nieczytelna ;) ale to dla mnie. Pewnie dla wielu innych również. Za to z pewnością również dla wielu innych będzie czytelna ta postać wzoru, którą przedstawiłeś więc każdy teraz może sobie wybrać sam co uzna za stosowne ;)
UsuńWitam.
OdpowiedzUsuńMam pytanie.
W lini kodu:
#define __UBRR ((F_CPU+UART_BAUD*8UL) / (16UL*UART_BAUD)-1)
użyta jest wartość F_CPU.
W jakim pliku projektu w eclipse mogę znaleźć F_CPU( skąd pobiera je preprocesor )?
W bluebooku jest napisane że w pliku makefile ale niestety ja nie mogę tam znaleźć F_CPU.
Pozdrawiam.
W Eclipse w ustawieniach projektu ustawiasz częstotliwość, Eclipse dodaje to automatycznie do makefile i później masz to dostępne jako stałą F_CPU w KAŻDYM pliku projektu
Usuń