Elektroda.pl
Elektroda.pl
X
Filament
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

atmega8 ds1307 - Program sie zawiesza przy odczycie (C)

fanatykstaroci 17 Gru 2015 11:51 2733 36
  • #1 17 Gru 2015 11:51
    fanatykstaroci
    Poziom 12  

    Witam,
    Mam problem z komunikacja z zegarem DS1307.
    AVR Atmega8.
    Przy zapisie wszystko jest ok, uklad wydaje sie zaakceptowac dane. A przynajmniej atmega sie nie zawiesza. Jednak nie mam jak tego sprawdzic, bo w tym momencie program atmegi sie zawiesza.
    Probowalem juz 2 innych kodow do odczytywania danych, ale bez skutku.
    Ponizej przedstawiam listing sekcji odpowiedzialnej za I2C i sam odczyt z DS1307, z ktorego obecnie korzystam.
    Moze ktos bylby w stanie mi podpowiedziec, gdzie mam blad.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Link do listingu


    Oczywiscie inicjacja jest przeprowadzona poprzez wywolanie i2c_init.
    Funkcje dec2bcd i bcd2dec uproscilem, by wykluczyc problem wynikajacy z samej konwersji.

    A moze ktos moglby poratowac dzialajacym kodem?

    Z gory dzieki... chcialbym to skonczyc na swieta jako prezent.

    ps. niestety moj komputerek cos ostatnio odmowil wpisywania polskich znaczkow, wybaczcie :(

    0 29
  • Filament
  • Pomocny post
    #2 17 Gru 2015 13:20
    2675900
    Użytkownik usunął konto  
  • #3 17 Gru 2015 13:55
    fanatykstaroci
    Poziom 12  

    Rezystory są, SDA i SCK podciągające. SQW również podciągnięte do plusa, niewykorzystywane.
    Wyjście bateryjki zwarte z masą, w tej chwili jej nie mam podłączonej, do testów uznałem, że nie będę chwilowo podłączał. Zaleca się wtedy zwarcie do masy.
    SDA i SCK... raczej nie...
    5 pod 28, 6 pod 27.
    To może się tym objawiać? Czy mogłem uszkodzić RTC takim sposobem?

    Inicjacja przebiega pomyślnie.
    Zależnie od kodu, zawiesza się już przy próbie zapisu, albo dopiero przy próbie odczytu w dalszej części kodu.

    EDIT: chyba faktycznie pokiełbasiłem to... spróbuję je przestawić, chociaż łatwo nie będzie.. ciasno tu :/

    0
  • #4 17 Gru 2015 14:43
    2675900
    Użytkownik usunął konto  
  • #5 17 Gru 2015 15:40
    fanatykstaroci
    Poziom 12  

    Tak jak kolega wyżej wspomniał, miałem pomieszane piny SDA i SCK. Sam nie wiem jak to się stało. Udało mi się je zamienić.
    Program zapisuje czas i nawet zdarza mu się go odczytać..
    Niestety po którymś odczytaniu następuje znowu zawieszenie się całości :(
    Nie wiem co jest grane, czy przez to złe połączenie nie zpesułem czasem zegara.
    Obecne objawy to:
    1. po którymś odczytaniu zawiesza się
    2. odczytuje złe wartości... czasem pokazuje dobrze godzinę, ustawioną na sztywno "11:30". Za chwilę pojawiają się jednak inne liczby po odczytaniu. Miałem wrażenie, że to data, bo liczby podobne.
    Czy to możliwe, że cykl odczytywania się miesza? Jakiś wewnętrzny kursor nie da rady?
    Da się to zresetować?

    Odczyt daty i czasu, nieco zmieniony (inna biblioteka):

    Kod: c
    Zaloguj się, aby zobaczyć kod


    EDIT: te inne dane to w tej chwili same zera. nie pokazuje danych.
    Program pokazuje czas, poprawnie.. nawet minuty lecą. Ale nadal po którymś odczytaniu następuje zawieszenie się programu. Czasem robi się to po 1-2 odczytaniu, a czasem po którymś-nastym.. właśnie udało mi się puścić całość przez 3-4 minuty, do czasu jak się zawiesił. W między czasie średnio co 3-4 odczyt pokazał 00:00.. a za chwile znowu poprawny czas... 11:30, 11:31, 11:32, 11:33 ... i zawiecha...

    0
  • Filament
  • #6 17 Gru 2015 16:09
    2675900
    Użytkownik usunął konto  
  • #7 17 Gru 2015 16:25
    fanatykstaroci
    Poziom 12  

    Z tym wyświetlaniem to nie jest aż tak różowo :)
    Aby zobrazować mój problem podsyłam video - link do YT.

    https://youtu.be/Qpzcxg7hNpo
    (serię liczenia od 0 do 9 dodałem, by wiedzieć, czy układ startuje i w którym momencie się zawiesza. Wiem dzięki temu, że inicjalizacja i pierwszy odczyt idą bez problemu)

    Z wyświetlaniem zer i głupot co jakiś czas to sobie poradzę. Widać też, że generalnie RTC działa i liczy czas.
    Aha.. dodałem też baterię, po tym jak zaczął RTC działać. I faktycznie mierzy nadal czas.

    Problemem jest jednak to zawieszanie się co jakiś czas.
    Kompletnie nie wiem od czego to może zależeć.
    Jak to można chociażby obejść?

    Próbowałem to jakoś obejść, ale niestety nie ma znacznej poprawy.. tzn program nie zawiesza się już po kilku cyklach, ale w ostateczności jak widać na filmie, nadal się zawiesza..

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #8 17 Gru 2015 16:53
    2675900
    Użytkownik usunął konto  
  • #9 17 Gru 2015 17:16
    fanatykstaroci
    Poziom 12  

    Myślę, że nie sieje.
    Moje przypuszczenia opieram na tym, że najpierw zacząłem od uruchomienia poprawnego tych lamp.
    Program działający jako prosty licznik, który tylko dodawał i odejmował do liczby "minuty" wartość 1 i potem pokazywał to na wyświetlacz działał poprawnie. I nie wieszał się nawet po wielu minutach od włączenia. Sprawdzałem to też pod kątem tego, czy mi się zasilacze nie grzeją zbytnio.
    Także zanim dodałem obsługę I2C + DS1307 to wszystko działało sprawnie i nic się nie wieszało.

    Układ zbudowałem nieco w oparciu o schemat mirley'a, z lekką modyfikacją, bo wykorzystałem jeszcze "4028". Chciałem zostawić sobie trochę portów pod dodatkowe funkcje, których jednak nie będę dokładał. Nic więc nie jest podłączone nigdzie więcej poza wyjściami pod tranzystory, pod wspomniany 4028 i pod DS1307 oraz wejścia od przycisków, zbudowane w układzie eliminacji drgania styków (rezystorki podciągające + kondensator... schemat ze jakiejś stronki opisującej ten problem z atmegą w tle).
    Nawet do programowania wyciągam atmege z podstawki, bo nie mam wyprowadzeń do programowania zrobionych. Nie sądziłem, że będą mi potrzebne.. myślałem, że program uda się ogarnąć raz dwa.

    Odłączyć ich zbytnio też już nie dam rady. Z w/w powodu nie skorzystałem ze standardowych złączy (np goldpinów), tylko przewody są wlutowane w płytkę. A dla pewności tego, by mi się to nie porozłączało podczas nawet tymczasowego montażu, końcówki zalałem termoglutem.

    Gdybym miał zapasowy DS1307 to bym z przyjemnością to podłączyć pod jakąś inną płytkę, gdzie mam normalny wyświetlacz LCD i mógł sprawdzić dokładnie co się dzieje i kiedy..

    Nie ukrywam... trochę wyszła z tego rzeźba :(

    Jedynie co mi do głowy teraz przychodzi to układ zewnętrzny dodatkowy, który będzie mi sprawdzał, czy atmega się zawiesiła i ją resetować.. ale wolałbym tego uniknąć i zrobić to porządnie tak.. by mi się nie zawieszało w ogóle... :(
    Ale jak już wspominałem.. kompletnie nie mam pomysłu już na to, co jeszcze może być nie tak.

    0
  • #10 18 Gru 2015 10:24
    2675900
    Użytkownik usunął konto  
  • #11 18 Gru 2015 11:38
    fanatykstaroci
    Poziom 12  

    Hmm.. coś w tym może być.
    I nawet o tym myślałem, w kwestii ESD.
    Jednak procedura odczytywania I2C występuje po wygaszeniu wszystkich lamp.
    Stąd na filmiku charakterystyczne mruganie co jakiś czas. To właśnie było wygaszenie lamp by odczytać I2C.
    Spróbuję jeszcze może wydłużyć nieco okres od wygaszenia do odczytania I2C. Żeby przeczekać te skoki...

    Czyli czeka mnie zrobienie wszystkiego od nowa..a przynajmniej tej płytki z atmegą i RTC...

    Masz rację, bo to może być przez lampy i to, że nieco sieją, tylko nie mam w tej chwili jak tego sprawdzić. I może ich wyłączenie na czas odczytywania I2C to też za mało...
    Ale nie mam jak tego sprawdzić, czy procesor żyje bez lamp.
    Ani diod nie mam jak wpiąć, ani oscyloskopa nie mam...
    Zegar SCK już zmniejszałem. Najlepiej działał przy 10 kHz, tak jak pokazywałem. Przy wyższych niemal od razu staje.
    Jak wyczytałem po internernetach, powodów do siadania może być kilka.
    Za szybki SCK, zakłócenia na linii, także ESD (wyeliminowanie tego także wymagać będzie nowej płytki), brak rezystorów podciągających (mam około 3.5 k w tej chwili, czyli nieco mniej niż 4.7, ale chyba i tak za wiele.. bo wg dokumentacji Atmela, przy tej czestotliwości to powinny być chyba 1.5 k...), lub pomieszane piny (to już poprawiłem). Próbowałem też to wpinać w przerwania, w timer, ale było to samo, albo gorzej. Potem wyczytałem, że to zły pomysł umieszczać sterowanie I2C do przerwania. Po 22 stwierdziłem, że już mam dość... a od rana nad tym siedziałem.
    No ale nic.. jak trzeba zrobić od nowa to trzeba...
    Wiem jak można dość łatwo odseparować linie sygnałowe, muszę tylko wymyśleć, jak najlepiej odseparować zasilanie (masę). Za jakieś sprawdzone wskazówki będę wdzięczny. A nie chciałbym używać trafo.

    Jak ja tego nie lubię... jak innym działa a mi nie, mimo że układ niemal identyczny. Ale pewnie w tym tkwi problem... "niemal".

    ps. a jak ustawić time-out do I2C? watchdog mi niewiele pomógł.. więcej miałem resetów niż normalnej pracy.. a po resecie i tak często pokazywał zero, zamiast czasu :/ Mimo, że watchdog ustawiłem na 250 ms, potem na 1 s.

    0
  • #12 18 Gru 2015 13:12
    Andrzej__S
    Poziom 28  

    fanatykstaroci napisał:
    Zegar SCK już zmniejszałem. Najlepiej działał przy 10 kHz, tak jak pokazywałem. Przy wyższych niemal od razu staje.
    Chciałbym zauważyć, że sposób obliczania wartości TWBR przedstawiony w pierwszym poście jest nieprawidłowy, w związku z czym nie uzyskasz zakładanej częstotliwości 100kHz na magistrali, tylko dużo niższą. W ogóle przy taktowaniu F_CPU=1MHz nie da się szybciej niż 62,5kHz dla TWBR równego zero (każda większa wartość spowalnia transmisję).
    Być może nie jest to problem, bo układ DS1307 ma w nocie podaną minimalną częstotliwość taktowania równą 0. Chciałem Ci tylko uświadomić, że kod (przynajmniej ten z pierwszego postu) nie działa zgodnie z założeniem.

    fanatykstaroci napisał:
    Kod: c
    Zaloguj się, aby zobaczyć kod
    Właściwie nie można założyć, że układ slave zawsze odpowie bitem potwierdzenia, dlatego zawsze powinno się sprawdzać, czy ten bit został przez slave wysłany. Ty raz sprawdzasz, raz nie. Jak już sprawdziłeś, że slave nie potwierdził:
    Kod: c
    Zaloguj się, aby zobaczyć kod
    kończysz funkcję nie generując na magistrali warunku STOP. Jeśli faktycznie tak się zdarzy, że układ slave nie odpowie bitem potwierdzenia, a Ty nie wygenerujesz STOPu (lub REPEATED START), to maszyna stanu układu slave się pogubi, a skutki tego są trudne do przewidzenia. Podobnie zresztą będzie, jeżeli układ nie odpowie bitem potwierdzenia, a Ty tego nie sprawdzisz i będziesz nadal wysyłał dane na magistralę.

    W niektórych przypadkach nawet samo sprawdzanie bitu potwierdzenia nie jest wystarczające. Dobry driver I2C powinien wykrywać również inne problemy z transmisją poprzez odczyt rejestru statusu transmisji TWSR i odpowiednio na nie reagować.

    Nie wykluczam zakłóceń, ale proponowałbym popracować też jeszcze nad kodem. Przykładowy kod Atmela do obsługi I2C, jak i sposób jego użycia był przytoczony w tym wątku.

    0
  • #13 18 Gru 2015 21:17
    fanatykstaroci
    Poziom 12  

    Witam ponownie...
    Kolejny dzień walki z tym.. i nadal bez większych rezultatów.
    Udało mi się wprawdzie nie zawieszać już klocka przy próbie odczytania.. tylko, że wtedy nic się nie odczytuje.
    W załącznikach przedstawiam kody 1, 2, 3, jakie próbowałem. Kod 3 jest na podstawie tego co kolega Andrzej mi podesłał. Liczę, że mnie wesprze w dostostowaniu go tak, by to zadziałało. Ale to zaraz.

    Schemat
    Poczytałem trochę o DS1307, komunikacji I2C i problemie zakłóceń w układzie, masie, itd. Udało mi się też wcisnąć LED'a, którego zalecał mi kolega wypowiadający się wcześniej. Mam dzięki temu dodatkową sygnalizację stanu pracy mikrokontrolera.
    W kodzie pierwszym, w funkcji odczytywania czasu widać, gdzie się załącza. I tak też się zawiesza.
    Ponadto dodałem dwa duże kondensatory przy przetwornicy, żeby odfiltrować to co się może dziać przy jej pracy. Dodałem też kondensator 470 nF przy uC (był już tam wcześniej 100 n, tak jak przy RTC). Ponadto podłączyłem zasilanie strony analogowej, a także w programie wszystkie nieużywane piny są ustawione jako wyjścia z pull'up'em. Na wyjściu zasilacza 5 V także dodałem większy kondensator. Uporządkowałem też nieco przewody zasilające i te z masą. Zlutowałem obudowę kwarcu RTC z masą.
    Efekty widać na zrobionym dziś schemacie.
    Nieco uprościłem, bo nie chciało mi się wszystkie dublować, przez to na wyjściu 4028 jest narysowany jeden tranzystor (w układzie jest 10, po jednym na każdą katodę lampy), a część anodowa lamp, powinna być x4. Poza tym wszystko chyba zostało ujęte. Poza jednym szczegółem.. jest jeszcze LED wpięty za regulatorem 5 V, sygnalizujący obecność napięcia 5 V.
    Przetwornica HV jest taka jak na schemacie Mirley'a (Link). Działa dobrze. Dodałem tam tylko teraz kondensatory filtrujące na wejściu, jak widać na schemacie i o czym wspomniałem wcześniej.
    Ogólnie jak widać schemat mocno wzorowany na konstrukcji Mirley'a.

    Kod 1.
    W miejscu odczytywania dodałem załączanie się LED'a.
    W momencie zawieszenia się.. obecnie niemalże od razu, diodka się zapala i nie gaśnie.
    Eksperymentowałem i wydaje mi się, że zawiesza się już na pierwszej linijce.. "start_wait". Gdy zmieniłem na zwykły "start", program działał, ale nic się nie zaczytywało.
    Innym winnym jest I2C_Stop. Dlaczego?
    Ciekawostka: Program się zwiesza. Ale... gdy odłączam zasilanie, w momencie wygaszania się lamp, pokazuje się prawidłowy czas! Niby więc dane są odczytane. Ale nie są przekazane na wyświetlacz, bo program wisi.. W momencie wyłączenia, znika chyba najpierw zasilanie na DS1307, co odblokowuje linię I2C i program Atmegi mimo wszystko kontynuuje pracę... pokazując prawidłowy czas.
    Ciekawostka 2: Podłączając zwykły miernik pod nóżki atmegi widać, że na SDA jest jakieś napięcie, a na SCL jest masa, tj 0 V. Niemal w ogóle nie skacze. Jakby linia ta zablokowała się na masie. To może być wina za małych/dużych rezystorów podciągających?


    Kod 2.
    Idąc tropem zmniejszenie skomplikowania kodu, popełniłem takie coś. Program się nie zawiesza, ale też zupełnie nic nie odczytuje. Kod zaczerpnięty z jakiejś strony z neta, gdzie była Atmega8 + DS1307 + LCD.

    Kod 3.
    Na podstawie linka wrzuconego przez kolegę Andrzeja.
    Nie jestem pewny funkcji odbierania danych czasu.
    Owszem, tutaj również się program nie zawiesza. Ale też nic nie odczytuje.
    Na wyświetlacz dostaję 02 i 01. Odpowiednio dla godzin i dla minut. Czyli to co wpisuję w buff[1]. Wydawało mi się, że to kod dla rejestru, który chcemy odczytać, ale chyba się myliłem.. Nie wiem więc jak to wykorzystać lepiej :(
    Mam nadzieję, że otrzymam wsparcie w tej materii. Procedura odczytu widoczna jest na pozostałych kodach, chociaż i tu się różni. Jednak najwłaściwsza jest chyba w kodzie 1.

    0
  • #14 18 Gru 2015 22:12
    2675900
    Użytkownik usunął konto  
  • #15 18 Gru 2015 22:45
    fanatykstaroci
    Poziom 12  

    Rozumiem, że podpiąć linię do masy przez kondensator.. a mogę spytać jaki tamten kolega stosował? Duży jakiś? malutki? 1 nF będzie ok?
    Kondensator może też spowodować problemy potem komunikacyjne, z racji zmniejszenia narastania i opadania zboczy sygnałowych.. czy źle myślę?
    Ale w sumie.. to chyba nie zaszkodzi spróbować. Podpinamy do masy MCU, czy gdzieś dalej.. np. prosto pod zasilanie?

    0
  • Pomocny post
    #17 19 Gru 2015 11:39
    Andrzej__S
    Poziom 28  

    Na początek taka uwaga:
    Driver Atmela bazuje na przerwaniach, w związku z czym wymaga globalnego zezwolenia na przerwania, czyli ustawienia bitu I w SREG. Z tego też powodu nie można używać go (w sposób przedstawiony w przykładzie obsługi PCF8563 link) wewnątrz procedury obsługi przerwania, ponieważ wtedy flaga I w SREG jest wyzerowana.

    Odnośnie "kodu 3".

    Jeśli chodzi o Twoją funkcję DS1307_GetTime() przeczytaj komentarze:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    fanatykstaroci napisał:
    Kod 3.
    ..............
    Owszem, tutaj również się program nie zawiesza. Ale też nic nie odczytuje.

    To, że program się nie wiesza, to prawdopodobnie zasługa drivera, który pilnuje porządku na magistrali poprzez prawidłowe zakończenie transmisji w przypadku błędu. Jeśli jednak wystąpiły błędy, to powyższy kod ich nie wykrywa i nie reaguje na nie prawidłowo (efektem może być właśnie brak odczytu). Dlatego do powyższego kodu należałoby wprowadzić pewne modyfikacje, na przykład (nie mam w tej chwili możliwości przetestowania kod, więc nie mogę zagwarantować poprawności działania, nie twierdzę też, że to jedyne słuszne rozwiązanie :)):
    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #18 19 Gru 2015 17:37
    fanatykstaroci
    Poziom 12  

    Witam...
    Problem rozwiązany.. w dość głupi sposób.
    Tak mi się wydaje.
    Zastosowałem się do rad kolegi Piotrusa i dodałem ten kondensator. Może i on ma też pozytywny wpływ na to. Zwiększyłem też rezystory podciągające do 10 k. Gdzieś w internetach zalecili je zwiększyć, by wyeliminować problem szumów. Choć to chyba nielogiczne, ale nie zaszkodziło spróbować.
    Skorzystałem z kodu nr 1.
    Eksperymentowałem na różne sposoby.
    W efekcie czego powstało takie coś:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    To tylko wnętrze funkcji odczytywania czasu. Usunąłem pierwszy i2c_stop().

    Program ruszył. Zegarek przez godzinę działał, nie zawiesił się, zgodność czasu bardzo dobra, nie rozjechało się (wiem.. należało by sprawdzić po całym dniu albo tygodniu.. dojdę i do tego).
    Jednak próby odczytywania czasu powodowały bardzo wyraźne mruganie, momentami wręcz przeszkadzające (gdy się ściemniło).
    Postanowiłem odrobinkę skrócić czas oczekiwania na wygaśnięcie lamp. Z 25 ms zrobiłem 15 przed odczytaniem zegara i z 25 do 5 po odczytaniu zegara.

    Oczywiście problem zawieszania się powrócił niemal od razu. Po uruchomieniu... zawiecha od razu.
    Wróciłem do tamtych ustawień. Oczywiście nadal program się zawiesza. Mimo, że jest identyczny.

    Postanowiłem więc zrobić najgłupsze co mi przyszło w tym momencie do głowy..
    Wziąłem inną ATmegę. Nieco inną, ale podobną (Miałem Atmega8-16PU, nowa to Atmega8L-8PU). Więc na moje potrzeby różnicy nie ma żadnej, bo i tak pracuję na 1 MHz.

    Tada! Zegarek od razu odżył. Nie zawiesza się nawet po kilkukrotnym uruchomieniu. Czas się pokazuje, wszystko jest w porządku...

    Wygląda więc na to, że przez źle podłączone piny SDA i SCK na początku uszkodziłem jakąś wewnętrzną strukturę Atmegi.
    Sam układ przyda mi się do innych zabaw, już bez I2C.

    Szkoda, że nie wpadłem na to wcześniej.
    Dziękuję wszystkim za pomoc i rady.
    Za znalezienie błędów, za pomoc w redukcji szumów i za rzeczowe wyjaśnienie działania interfejsu I2C/TWI :)

    Niestety jest też i smutna wiadomość.
    Podczas 3 godzinnego testu poprawności działania, spaliła mi się jedna lampa.
    Zamówiłem więc nowe. Mam nadzieję, że do środy przyjdą.
    Od razu wziąłem 5, więc niewykluczone, że jeszcze tu do Was wrócę, przy okazji składania kolejnego zegarka. Mimo tylu problemów nabrałem ochoty na zrobienie kolejnego. Tym razem z poprawnym schematem od samego początku, by wykluczyć wszelkie szumy.
    Chętnie też spróbuję kodu obsługi TWI od Andrzeja. Mam nadzieję, że nie obrazi się, jak napiszę na PW w tej sprawie za jakiś czas :)

    0
  • Pomocny post
    #19 19 Gru 2015 17:53
    michalko12
    Specjalista - Mikrokontrolery

    fanatykstaroci napisał:
    Wygląda więc na to, że przez źle podłączone piny SDA i SCK na początku uszkodziłem jakąś wewnętrzną strukturę Atmegi.

    Takie kwiatki są niemożliwe. Problem jest gdzieś indziej i pewnie powróci. Dziwię się, że nikt nie zwrócił Ci uwagi na bezkrytyczne podejście do budowy tego zegara. Te kable sterujące NIXIE wypełniające całą obudowę zegara, to nie jest środowisko dla I2C.

    0
  • #20 22 Gru 2015 00:51
    fanatykstaroci
    Poziom 12  

    Kolega michalko12 ma trochę racji.
    Problem w pewnym sensie powrócił, nadal zdarza mu się zawiesić.. czasem po całym dniu, czasem po połowie dnia, a bywało że po 2 godzinach. Watchdog ustawiony na 2 sekundy załatwia sprawę (ciekawostka.. dla atmegi 8 to jest max ;)).
    Dodatkowo postanowiłem wykorzystać jeden z pomysłów, znaleziony na jednej ze stron. Wyjście gdzie podłączyłem diodę LED wykorzystam do tego, by zasilało ono układ zegara. Dzięki temu po zresetowaniu układ zegarka także straci główne zasilanie, co powinno gwarantować uwolnienie linii I2C/TWI. Układ będzie się załączał z opóźnieniem 150 ms i potem nastąpi ponowne odczekanie 150 ms i dopiero ruszy program mikrokontrolera. Funkcja w programie została uruchomiona, chociaż połączeń na samej płytce jeszcze nie zmieniałem. Póki co głównym "zabezpieczeniem" przed zawiechą jest wspomniany watchdog.

    Wracając do samego jeszcze projektu i uwagi kolegi michalko12.
    Fakt.. pierwotnie miała być tu płytka. Ale niestety skopałem dwie (albo i 3?) płytki, a na trzecią zabrakło mi już materiałów i cierpliwości.
    W docelowej obudowie postaram się (tzn na pewno dodam) jakieś ekranowanie dla płytki sterującej i postaram się też w podobny sposób "odgrodzić" te dyndające przewody.
    Mam jednak wrażenie, że największe zakłócenia powoduje sama przetwornica.
    Co ciekawe... układ niemal natychmiast się zawiesza, jak zwiększę napięcie przetwornicy. Na przetwornicy muszę mieć 200 V, by na lampach było 170 V. Musiałem też nieco obniżyć, bodajże do 165, aby zakłócenia nie powodowały zawieszania się MCU. Podniesienie ponad 175 (a tym samym zwiększenie jasności) powoduje niemal natychmiastowe zawieszenie się układu w momencie odczytywania danych.
    Jak już ktoś zauważył na tym forum (chyba w innym, sąsiednim temacie), nie jest to układ nadwyraz efektywny, ani poprawnie zabezpieczony. Mimo, że masę mam tam poprowadzoną po obwodzie (unikając pętli), nie sądzę, by stanowiło to wystarczającą (lub jakąkolwiek) ochronę.
    Także postaram się popracować pod tym kątem i liczę na jakieś wskazówki. Dotyczące zbudowania stosownych ekranów itd. Będę wdzięczny za wszelkie wskazówki, gdyż na dniach czeka mnie budowanie obudowy.
    A kolejne układy tego typu, o ile powstaną, obiecuję, że będą wykonane lepiej :)

    Nadal się uczę.
    Muszę też przyznać, że to mój pierwszy projekt od kilku lat... miałem dość długą przerwę niestety. Toteż parę rzeczy uleciało.

    ps. pytanko pomocnicze jeszcze, dotyczące projektu (schematu). Jest tu bowiem coś, co nie daje mi spokoju. Proszę zwrócić uwagę na płytkę/część/moduł odpowiedzialną za sterowanie anodą. Te dwa tranzystorki z rezystorkami. Mam tam doprowadzoną masę, która wychodzi od przetwornicy. Jest ona też wprowdzie połączona z główną masą... ale czy nie byłoby bezpieczniej (z punktu widzenia EMI), by ta masa była połączona bezpośrednio z masą wchodzącą tuż przy zasilaniu? Czy wręcz przeciwnie... jest dobrze, bo dzięki temu można odsiać zakłócenia tu powstające przez spore kondensatory (dwa równolegle 470 uF co by zmniejszyć ich wypadkowe ESR), które są przy przetwornicy i bezpośrednio połączone z tą masą?
    Nie wiem czy nie skomplikowałem zbytnio mojego pytania :)

    0
  • #21 23 Gru 2015 00:06
    2675900
    Użytkownik usunął konto  
  • #22 23 Gru 2015 00:19
    michalko12
    Specjalista - Mikrokontrolery

    Piotrus_999 napisał:
    Ja daje 10 bo przy dziewięciu czasami nie odwieszało.

    Trzeba taktować aż do momentu kiedy slave wystawi poziom wysoki i wtedy wysłać STOP. Stan wysoki pojawia na pewno wtedy kiedy slave po transmisji bajtu oczekuje sygnału ACK.

    0
  • #23 23 Gru 2015 00:59
    2675900
    Użytkownik usunął konto  
  • #24 23 Gru 2015 10:58
    michalko12
    Specjalista - Mikrokontrolery

    Trochę źle napisałem w poprzednim poście, bo to nie sam sygnał STOP powinien być wysłany, a sekwencja STRAT STOP, sam sygnał STOP jest raczej trudno wysłać w takim momencie. Każde urządzenie na szynie I2C powinno tak działać, że w dowolnym momencie (asynchronicznie) może zdekodować sygnał START i STOP po których powinny ustawić się odpowiednio automaty stanu. Warunkiem poprawnego nadania tych sygnałów jest utrzymywanie się linii magistrali w stanie wysokim. Podanie impulsu H-L-H na linii danych SDA przy wysokim stanie linii SCL powinno być odebrane przez układy slave jako sekwencja START STOP, a co za tym idzie zresetowanie automatów stanu i synchronizację magistrali.

    0
  • #25 23 Gru 2015 12:02
    Andrzej__S
    Poziom 28  

    michalko12 napisał:
    ...nie sam sygnał STOP powinien być wysłany, a sekwencja STRAT STOP...

    Zastanawiam się tylko, czy to na pewno jest zawsze bezpieczne (zda egzamin). Właściwie specyfikacja mówi:
    Cytat:
    A START condition immediately followed by a STOP condition (void message) is an illegal format.
    i chociaż w niektórych specyfikacjach jest też napisane:
    Cytat:
    Many devices however are designed to operate properly under this condition.
    to jednak jest to "many" a nie "all"...

    ...ale nigdy tego sposobu nie stosowałem, więc nie chcę wyrokować.

    Piotrus_999 napisał:
    A jak odbiera?

    ...to nad linią SDA ma kontrolę master, więc problem raczej nie powinien wystąpić. Sam START powinien zresetować logikę (maszynę stanów) układu slave.

    0
  • #26 23 Gru 2015 15:43
    2675900
    Użytkownik usunął konto  
  • #27 23 Gru 2015 20:08
    Andrzej__S
    Poziom 28  

    Piotrus_999 napisał:
    I tu jest własnie pies pogrzebany ze tak jest tylko teoretycznie - po zawieszeniu magistrali bardzo czesto slave trzyma SDA nisko

    Raczej powiedziałbym, że to właśnie trzymanie przez układ slave linii SDA w stanie niskim jest powodem zawieszenia magistrali.

    Opiszę to może dokładniej:

    Procedura, o której piszesz jest konieczna tylko wtedy, kiedy z jakichś powodów transmisja (a właściwie sygnał zegarowy na linii SCL) zostanie przerwana w momencie wysyłania przez układ slave danych (bitu 0) lub bitu potwierdzenia. Właśnie wtedy maszyna stanów układu slave zostanie zatrzymana na "wysyłanie bitu 0" lub "wysyłanie potwierdzenia" i będzie czekała na następne zbocze na linii SCL.

    W momencie kiedy slave odbiera dane, musi pozostawić linię danych w stanie wysokim dla układu master (by mógł wysyłać dane), więc nie dojdzie do "zawieszenia". W związku z tym, jeśli transmisja zostanie przerwana w trakcie odbierania przez slave bajtu danych, to nie trzeba jej "odwieszać", wystarczy wygenerować warunek START. To spowoduje zresetowanie maszyn stanów wszystkich układów slave na magistrali i transmisja wróci do normy.

    Kiedy transmisja zostanie przerwana podczas wysyłania przez układ slave bitu 1, także nie ma potrzeby stosowania procedury "odwieszania", bo linia SDA pozostanie w stanie wysokim.

    I nie jest tak tylko teoretycznie, praktycznie też ;)

    0
  • #28 23 Gru 2015 20:42
    2675900
    Użytkownik usunął konto  
  • #29 23 Gru 2015 21:00
    michalko12
    Specjalista - Mikrokontrolery

    Ale tutaj cały czas jest mowa o tym "oszukuwaniu". Trzeba "ręcznie" taktować SCL, aż do napotkania wysokiego stanu na SDA i ani jednego cyklu więcej. Potem można "ręcznie" wygenerować START STOP, ale jak słusznie zauważył @Andrzej__S jest pewne ryzyko, że ten przypadek może być nieobsługiwany przez wszystkie układy slave. Więc najlepszym rozwiązaniem jest "ręczne" taktowanie, aż do napotkania stanu H na SDA i następnie przełączenie się już w tryb normalnej transmisji.

    0
  • #30 23 Gru 2015 21:03
    2675900
    Użytkownik usunął konto