ATNEL tech-forum
https://forum.atnel.pl/

AVR TWI - konfilkt zapisu-odczytu
https://forum.atnel.pl/topic22411.html
Strona 1 z 1

Autor:  MarKl [ 15 lip 2019, o 14:52 ]
Tytuł:  AVR TWI - konfilkt zapisu-odczytu

Witam wszystkich!

Jest to mój pierwszy post na tym forum, gdybym coś nie po kolei zrobił - proszę o zrozumienie i poprawienie ;)


Pracuję nad małym projektem sterowania oświetleniem w zależności od dnia miesiąca, godziny, oszczędnie z energią na ile się da. Sam projekt na razie nie jest tu ważny.

Do tego projektu używam Atmegi32A (wbudowany oscylator RC 1MHz), LCD HD47780 i RTC DS3231 (ostatnie dwa kupione kilka lat temu w chińskim sklepie). To wszystko mam połączone na zestawie uruchomieniowym ZL3AVR, a jak coś trzeba to obok na płytce stykowej.
Biblioteki (lcd, twi) pisałem w oparciu o niebieską książkę Pana Mirka, a początek biblioteki do RTC na podstawie jego filmu, czyli:
- LCD jest sterowane w trybie czterech pinów, bez obsługi pinu RW
- DS3231 jest przez TWI (50kHz).

Do wykrywania impulsu 1Hz używam na razie przerwania INT0 na zbocze rosnące, podciągnięte, z obsługą sprzętową, nie programową w pętli while. Sygnał z DS'a też jest podciągnięty do VCC.
Z rtc będę potrzebować na pewno alarm(y) do wybudzania mikrokontrolera, ale chcę też wykorzystać generowany przez niego 1Hz, gdy będzie potrzeba wyświetlenia czasu na lcd. Napisałem więc funkcję, która włącza/wyłącza ten sygnał. Chcąc ją przetestować, w pętli while ustawiam na przemian włączenie/wyłączenie tego sygnału z przerwami _delay_ms od setek milisekund do paru sekund (przy użyciu for). I tu następuje problem - program się zawiesza.
Co udało mi się ustalić przy "debugowaniu" diodami (używam eclips'a i usbasp), to:
- wyłączenie programowe przerwania eliminuje zawieszenie
- odłączenie pinu przerwania tak samo eliminuje problem
(dwa powyższe sprawdziłem na oscyloskopie, sprawdzając sygnał SQW z DS3231 - pojawia się i znika według ustawień w while)
- zacinanie się jest losowe - w programie dodałem sobie licznik zliczający ilość przerwań od początku programu, czasami jest to pierwsze przerwanie, czasami 20, zależy od "przypadku" i ustawionych przerw w while ("okrągłe" 100, 250ms i "nieokrągłe" 143, 149ms).
- program wiesza się:
1. w pętli while(!(TWCR & (1<<TWINT))) czekającej na zapis/odczyt bajtu
2. i/lub zapisie kilku bajtów funkcją TWI_writeBuf
które pierwsze - 1 czy 2 - to nie wiem, ponieważ oscyloskop mam analogowy, z jedną sondą
- dodanie w obsłudze przerwania pętli oczekującej na zapis jak wyżej nie pomaga, program wiesza się na tym

To na razie tyle, co udało mi się ustalić. Podejrzewam, że podczas zapisu przez TWI wypada przerwanie, które chce odczytać kiedy slave jest w trybie zapisu, lub odwrotnie, lub coś około tego. Szukałem już jakichś podobnych wątków na ten temat, również w języku angielskim, ale nie znalazłem nic pożytecznego.
Gdybym mógł poprosić, pod jakim hasłem szukać rozwiązania, co dodać/usunąć lub jeśli rozwiązanie jest trywialne - to o podanie go.

Za pomoc z góry dziękuję! :)

Obsługa TWI:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obsługa DS3231 (w funkcji DS3231_1Hz_SQW ręcznie ustawiłem wartości do wpisania do rejestru, żeby wykluczyć niedziałającą funkcję do ustawiania/zerowania bitu w bajcie; alarmów nie sprawdzałem jeszcze):

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obsługa przerwań:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Main (zapis daty i czasu działa):
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Autor:  Adam12 [ 15 lip 2019, o 17:32 ]
Tytuł:  Re: AVR TWI - konfilkt zapisu-odczytu

Czy ja dobrze widzę, że w obsłudze przerwania masz całe wyświetlanie na LCD?? To są bardzo długotrwałe operacje. Przede wszystkim wywal to z przerwania. W przerwaniu najlepiej ustawiaj tylko jakąś flagę, a odczyt daty, czasu i wyświetlanie na LCD załatwiaj w głównej pętli.

Autor:  mirekk36 [ 15 lip 2019, o 18:30 ]
Tytuł:  Re: AVR TWI - konfilkt zapisu-odczytu

Adam12 napisał(a):
Przede wszystkim wywal to z przerwania.

Ło Matko, kolega ma sokole oko !.... bardzo słuszna uwaga

Autor:  MarKl [ 15 lip 2019, o 19:23 ]
Tytuł:  Re: AVR TWI - konfilkt zapisu-odczytu

Adam12 napisał(a):
Czy ja dobrze widzę, że w obsłudze przerwania masz całe wyświetlanie na LCD?? To są bardzo długotrwałe operacje. Przede wszystkim wywal to z przerwania. W przerwaniu najlepiej ustawiaj tylko jakąś flagę, a odczyt daty, czasu i wyświetlanie na LCD załatwiaj w głównej pętli.


O kurcze, rzeczywiście... Nie wpadłem na to :P Dzięki :)
Źródła problemu szukałem w funkcjach do komunikacji TWI albo w tych do DS3231. Na szybko zrobiłem, zostawiając tylko odczyt (potem go wrzucę do głównej pętli) i przełączanie diody - działa.

Ale jak już poruszyłem temat, to gdybym teoretycznie miał dużą ilość danych do wysłania po TWI, a ponadto miał jakieś przerwanie, którego obsługa byłaby absolutnie priorytetowa, zajmowała chwilę (nie tak długą jak ten LCD, ale jednak znaczną) i nie mogła być wykonana przez flagę - w jakim kierunku powinna iść implementacja tego?

Edit:
Poza tym, czy jeżeli przerwanie INT0 jest na zbocze narastające, to poprawnym jest podciągnięcie tego pinu? Teraz działa, ale nie jestem pewny poprawności i bezawaryjności tego

Edit 2:
Nawet funkcja odczytania czasu w przerwaniu zawiesza program (implementacja flagi w drodze)

Autor:  MarKl [ 16 lip 2019, o 15:34 ]
Tytuł:  Re: AVR TWI - konfilkt zapisu-odczytu

Mam problem z tą flagą.

Wszystkie funkcje, jakie sobie tworzę, przerzuciłem do zewnętrznego pliku źródłowego funkcje_do_programu.c. (dalej będę to nazywał funkcje.c)
Spodziewam się, że będę potrzebował dużo flag, więc w pliku nagłówkowym funkcje_do_programu.h zdefiniowałem typ TFLAGS z 8 jednobitowymi flagami (jak będzie rzeczywiście dużo, to zmienię sobie tylko rozmiar "typu"). Jako że flag zamierzam używać w funkcje.c i main.c, w nagłówku zdeklarowałem od razu zmienną flagi1 typu TFLAGS.

W funkcje.c mam obsługę przerwania do obsługi SQW, o którym pisałem w pierwszym poście - oznacz flagę, a dla debugowania przełącz diodę (dioda się przełącza).
W pętli głównej w main.c mam prostego if'a, który przy oznaczeniu flagi ma (narazie) wyzerować ją i przełączyć inną diodę - i tutaj już dioda się nie przełącza. Kombinowałem różnymi sposobami, fladze przypisywałem (i sprawdzałem) wartości dziesiętne i szesnastkowe. Utworzyłem tymczasową zmienną uint8_t która miała być tymczasową flagą, kombinowałem z deklaracją jej jako extern - nic nie pomogło.

Wrzucam fragmenty kodów, jak na obecną chwilę wygląda program, flaga tymczasowa jest zakomentowana.

Tak jak wcześniej, byłbym wdzięczny za wskazanie, pod jakim hasłem szukać jakiś materiałów na ten temat, albo jeśli rozwiązanie jest trywialne - to o podanie go (obstawiam pomieszanie widoczności zmiennych albo inną bździnę). Poza tym, pytania o ten konflikt zapis-odczyt i o podciągnięcie z poprzedniego wpisu nadal aktualne ;)

Main.c:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


funkcje_do_programu nagłówek:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


..i plik źródłowy:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Autor:  Adam12 [ 16 lip 2019, o 17:30 ]
Tytuł:  Re: AVR TWI - konfilkt zapisu-odczytu

Może tak:
volatile uint8_t flaga_tmp;

Masz talent do komplikowania sobie życia w momencie kiedy trzeba wszystko uprościć żeby znaleźć źródło problemu. Jeśli dalej program będzie się zawieszał, nie twórz nowych plików tylko przeciwnie to z czym jest problem wrzuć do main.c czyli główną pętlę, obsługę przerwania, podstawowe inicjalizacje i funkcję odczytu daty_czasu. Potem jeśli dalej nie działa wywal np. wszystko związane z LCD itd. Taki okrojony kod łatwiej będzie też komuś analizować na forum.

Poza tym polecam zakup analizatora stanów logicznych. Sam szybko znalazłbyś odpowiedź na pytanie o konflikt zapis-odczyt generując jakieś zakłócające przerwanie i podglądając co się dzieje na liniach TWI.

Co do podciągnięcia INT0 - zajrzałem do noty i na pierwszej stronie jest jak byk schemat z rezystorem podciągającym więc podciągnięcie programowe jest ok.

Autor:  MarKl [ 16 lip 2019, o 18:10 ]
Tytuł:  Re: AVR TWI - konfilkt zapisu-odczytu

Czyli tak jak myślałem - bździna. Już nadrobiłem rozdział o volatile w niebieskiej książce.

Działa z volatile uint8_t flaga_tmp, jak i dla volatile TFLAGS flagi1. Odświeża też czas.

Z tym komplikowaniem to zgodzę się i nie. Funkcje, definicje, deklaracje itp. stopniowo przerzucałem z main.c do innych plików, za każdym razem sprawdzając, czy program się skompiluje i czy wciąż działa tak jak wcześniej. Jak już wszystko przeniosłem, to chciałem dodać obsługę flagi. No i tu był chyba błąd, bo zamiast w main.c to od razu tworzyłem w funkcje.h i funkcje.c. Później jak obsługa flagi w głównej pętli nie działała, to pierwsze co wywaliłem to właśnie obsługa rtc i lcd, później zamiast struktury flag utworzyłem jedną zmienną tymczasową, a na końcu dodałem diodę.
Pozostałe rady co do kodu - dzięki za rady, przydadzą się na pewno.

Może wyposażę się w ten analizator - na moje potrzeby lepszy od oscyloskopu cyfrowego - tańszy a bardziej przydatny.

Chyba się nie zrozumieliśmy z podciągnięciem przerwania. Wnioskuję, że Ty piszesz o DS3231, bo tam jest na pierwszej stronie ten schemat.
Przerwanie INT/SQW z DS3231 mam podciągnięte przez rezystor do 5V. Moje pytanie dotyczy podciągania programowego wejścia PD2/INT0 Atmegi32A (przerwanie na zbocze narastające). Teraz przyszło mi na myśl jeszcze jedno pytanie - czy gdybym podciągnął tylko wejście uC, to wyjścia RTC nie muszę w sumie już podciągać, prawda?

Autor:  Adam12 [ 16 lip 2019, o 19:05 ]
Tytuł:  Re: AVR TWI - konfilkt zapisu-odczytu

Właśnie to chciałem napisać, że podciągnięcie tylko wejścia uC jest poprawne i jest wystarczające.

To, że działa z flagą to znaczy, że już się nie wiesza?

Autor:  MarKl [ 17 lip 2019, o 16:59 ]
Tytuł:  Re: AVR TWI - konfilkt zapisu-odczytu

Ok, dzięki.

Tak, nie wiesza się. Specjalnie nawet zapchałem główna pętlę delayami, zapisami do RTC, całość około 2 sekundy - i co tyle się odświeża, więc flaga działa.

Strona 1 z 1 Strefa czasowa: UTC + 1
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/