logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATmega32][C] zmienne globalne, struktury i obsluga zegara PCF8563

hexen2k 13 Kwi 2011 20:25 3084 6
  • #1 9397169
    hexen2k
    Poziom 16  
    Witajcie,

    mam problem nad którym siedzę juz kilka dni i zatrzymałem się nie wiedząc gdzie tkwi problem. Otóż chcę obsługiwać zegar RTC PCF8563 po I2C - czytać i zapisywać z niego dane (datę i czas). Projekt mam podzielony na kilka plików, całość pisana w Code Blocks 10.5 i kompilowana w AVR GCC.
    Mam zdefiniowaną strukturę do zapisu danych z zegara do przechowywania aktualnych zawartości poszczególnych rejestrów z czasami PCF8563. Struktura ta tworzona jest w plikach pcf8563 i wedle założeń ma być zmienną globalną. Do wysyłania i odpierania po I2C służy mi bufor tI2CBuffer (zdefiniowany w i2c.c i deklaracja w pliku nagłówkowym) który też jest zmienna globalną.

    Układ uruchamiany działa mniej więcej tak że mamy 5 przycisków: ŚRODKOWY (ENTER), LEWO,PRAWO, GORA, DOL
    Naciskając Enter wchodzimy do ustawiania zegara (jeszcze to nie napisane w pełni) i mamy możliwość przesuwania kursora na wyświetlaczu za pomocą zmiennych pozycjax i pozycjay (używając klawiszy LEWO PRAWO) do miejsc w których przy użyciu klawiszy GORA DOL można zwiększać bądź zmniejszać wartość pojedynczego pola (cyfry). (wiem, kod jest okropnie zagmatwany ale na razie tylko takie rozwiązanie mi przyszło do głowy).
    Po ponownym naciśnięciu Enter chcę zapisywać ustawiony czas do PCF i dalej go potem wyświetlać w pętli.


    Testując sobie program chcę wpisać czas do PCF8563 i gdy robię to w miejscu gdzie zaznaczyłem linią gwiazdek (linia kodu 178 w pliku main.c) to po naciśnięciu przycisku GORA (SET_UP) uC idzie w krzaki (zawiesza się) i nic nie zapisuje do PCF'a. Natomiast poniżej naciskając DOL w pętli głównej for(;;) wpisuje mi do zegara datę i potem kontynuuje wyświetlanie zapisanego na sztywno w kodzie do struktury czasu na LCD.

    Z czego wynikać może to błędne działanie ? Błędna deklaracja zmiennych ? Jakieś przepełnienia stosów (pojęcie o tym mizerne) ?

    Jak ew. zrealizować to inaczej/prościej/lepiej ?

    Pomóżcie proszę bo już mi brzydnie to a nie wiem od czego teraz zacząć przy tym zacięciu ;)

    Poniżej kod main.c
    oraz cały projekt w archiwum jako załącznik.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #2 9400594
    Krauser
    Poziom 26  
    W każdym pliku gdzie używasz zmiennej z innego pliku należy się odwołać do jej deklaracji np. extern struct Time...
  • #3 9400978
    hexen2k
    Poziom 16  
    czyli np. extern TIME Time; mam zdefiniowane w pliku pcf8563.h i za pomocą include włączam go do main.c
    W ten sposób chyba nie musze już drugi raz w main deklarować w ten sposób.
    Dobrze myśle ?
  • #4 9406413
    Krauser
    Poziom 26  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Tak więc myślę że zmienna Time musi mieć przypisane po zdefiniowaniu wartości dla niektórych pół które zgodnie ze specyfikacją PCF8563 nie są i nigdy nie będą zerami np. bcdDay, bo być może jeśli zapisujesz złą datę RTC nie daje ACK na który czekasz.
  • #5 9408992
    hexen2k
    Poziom 16  
    ...ale na początku programu czytam wartości z PCF więc złych danych odczytać nie mogę, dodatkowo zarówno przy odczycie jak i przy zapisie PCF8563 maskuję nieużywane bity w odpowiednich rejestrach, więc o wartościach zerowych raczej nie ma mowy (struktura zadeklarowana jest jako globalna).
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #6 9410479
    Krauser
    Poziom 26  
    Masz rację. Proponuję dorzucić obsługę UARTa i wyrzucać na port wartości zmiennych flaga buforLCD1 buforLCD2 i tekstu w stylu "Stan programu przed zapisem czasu" itp. Akurat tutaj lepiej sprawdzi się obsługa UARTa bez buforów i obsługi przerwań, bo nie zakłóci działania Twojego programu tylko doda niewielkie opóźnienie potrzebne do wysłania kilkudziesięciu znaków.
  • #7 9459616
    hexen2k
    Poziom 16  
    Witajcie,
    opisuje bo może komuś się przyda :) (i nie spędzi wielu nocy nad taką pierdołą :P )

    Otóż problemem nie były zmienne globalne ani nic innego związanego z samą składnią kodu C. Przesiadując kolejne kilka godzin, wypijając litry kawy i rwąc włosy z głowy wydukałem jeszcze jeden "DROBNY" szczegół który powodował nieprawidłowe zachowanie całości a które objawiało się w momentach które wskazywać by mogły na co innego :), chodzi dokładnie o brak warunku kończącego transmisję a dokładniej generowania warunku STOP na magistrali TWI (I^2C), brakowało mi pętli while która czekała na poprawne wygenerowanie STOP transmisji zatem cała magistrala zachowywała się dość nieprzewidywalnie tworząc masę problemów... Co ciekawe problem nie objawiał się tak mocno (lub wcale) innym użytkownikom którzy taktowali uC zegarem 8MHz, w moim przypadku 16MHz spowodowało że uC leciał za szybko dalej i brak warunku while się objawiał i dał znać o sobie straszliwie... oby nikt nie popełnił tego błędu na przyszłość ;)

    załączam poprawny kod generowania STOP:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    reszta kodu jest OK, więc może ktoś sobie wykorzysta w razie potrzeby... Powodzenia !
REKLAMA