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:
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):
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Obsługa przerwań:
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):
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.