Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Zegar na atmega8, długookresowa stałość chodu

SzymonHK 01 Jul 2009 20:19 8979 66
Relpol
  • #1
    SzymonHK
    Level 20  
    Witam, w projekcie, który realizuję pojawił się problem zbyt małej dokładności zegara w długim okresie czasu. Dla dostępnych na rynku oscylatorów jest to &plusmn;20 ppm, co oznacza ponad 6 min/rok. Oczekiwana dokładność w projekcie to <3min/rok. Znam rozwiązanie typu DS32kHz, ale jest zbyt drogie. Słyszałem o możliwości synchronizowania zegara częstotliwością sieci energetycznej, której stabilność długo okresowa jest wystarczająca dla takiej dokładności. Czy ktoś z was zetknął się z takim rozwiązaniem?
  • Relpol
  • #3
    SzymonHK
    Level 20  
    To nie jest rozwiazanie,już by było taniej kupić DS32kHz.
  • #4
    emarcus
    Level 38  
    SzymonHK wrote:
    To nie jest rozwiazanie,już by było taniej kupić DS32kHz.


    Wiec zastosuj trimming condensator;
    Daj jeden np. 18 pF, a drugi 3-30pF ceramiczny trimmer, podlaczony do output pin. Droga "prob i bledow" mozesz go 'doregulowac' do wzglednie dobrej dokladnosci. Niemniej jednak nalezy pamietac ze rezonatory kwarcowe zwykle (nie kompensowane) moga miec odchylenia 'f' ze zmiana temperatury pracy, napiecie zasilania ma tez dosc duzy wplyw na efektywna czestotliwosc. Ponadto te tanie sprzedawane przez nieuczciwych dystrybutorow jako klasa 20 ppm moga pochodzic z kategorii 'surplus' i faktycznie nalezec do klasy 50 ppm.

    e marcus
  • #5
    janbernat
    Level 38  
    Zastosuj zewnętrzny RTC.
    PCF8583 można ustawić na kwarc lub zewnętrzny sygnał 50Hz z sieci energetycznej(PO transformatorze)-ale jak odłączysz od sieci-to się rozjedzie.
    Można też tak- chodzi stale RTC na impulsach z sieci, sprawdza ATMega czy są-jak nie ma-to przełącza bity konfiguracji RTC na kwarc zegarkowy.
    Przedtem zapamiętuje czas z RTC.
    A jak są znów- to na te impulsy.
    W zasadzie ten sposób można chyba zrealizować na samej ATMedze- z podtrzymaniem bateryjnym.
    Jak zbyt często sieć nie będzie odłączana-to błąd tylko z zegarka i z czasu rekonfiguracji RTC.
    Trzeci sposób-odbiornik radiowy AM WarszawaI-225 kHz częstotliwość-dzielnik-sygnał na procesor.
    To chyba jest ciągle sygnał wzorcowy.

    Dodano po 12 [minuty]:

    Jest jeszcze DS3234 RTC z własnym oscylatorem +-2ppm.
  • Relpol
  • #6
    SzymonHK
    Level 20  
    W zasadzie najlepszy wariant to drugi, Atmegę chce puscić na 4MHz, a przerwanie odmierzające czas taktowane 100Hz (mostek prostowniczy bez filtracji). Tylko nie wiem jak sobie poradzić ze zmianą źródła zegara przy podtrzymaniu bateryjnym.
  • #7
    janbernat
    Level 38  
    W wersji minimalistycznej- ATMega chodzi na wewnętrznym oscylatorze(jego dokładność jest żadna) a do XTAL1 i XTAL2 podłączasz kwarc 32kHz.
    Fusebity ustawiasz oczywiście na wewnętrzny oscylator.
    Ponieważ jest to ustawione fusebitami to nic nie można przełączyć (ustawienie sprzętowe)
    Jeden z liczników liczy impulsy 100Hz a drugi impulsy z kwarcu.
    Musisz je tylko zapisywać i wybierać programowo które z nich są aktualnie "ważne".
    Teraz mi przyszło do głowy że nie pamiętam jak się konfiguruje licznik aby liczył impulsy z tego kwarcu.
    Ale można.

    Poszedł po rozum do głowy...

    Dodano po 5 [minuty]:

    Już wrócił...

    Tylko Timer2 może w trybie asynchronicznym liczyć te impulsy zegarkowe.
    Co ważne- liczy je także w trybie sleep-co jest istotne przy zasilaniu bateryjnym.
  • #8
    SzymonHK
    Level 20  
    A jak programowo rozwiązać taką kwestję:
    Zasilanie sieciowe -> timer1 zlicza impulsy 100Hz i generuje przerwanie, na jakis port dajemy Vcc do detekcji sieci
    Brak sieci -> przerwanie generuje timer2, z odpowiednio dopasowanym prescalerem i wartością w pisaną do counter2?
  • #9
    janbernat
    Level 38  
    Nie, no nie tak.
    Musisz zrobić dwa liczniki programowe- do których będziesz wpisywał czas- np. co sekundę.
    Z liczników sprzętowych.
    Tzn. z timer2- impulsy z kwarcu.
    a timer1 liczy impulsy z końcówki T1- 100Hz.
    Po co Ci generowanie przerwań?
    Zegar można zrobić wewnątrz procesora.
    A sprawdzanie czy jest napięcie z sieci- w pętli Do-Loop.
    Jak nie ma -to ważny sygnał jest z zegarka.
    Jak jest znowu- to ważny sygnał jest z sieci.
  • #10
    SzymonHK
    Level 20  
    Ale cały projekt to nie zegarek, co określoną ilość czasu przerwanie inkrementuje główną zmienną programu, dokładnie co 3 minuty, potem następuje odczyt eepromu i sprawdzenie warunku, a główna pętla to pomiar temperatury na DS18b20
  • #11
    janbernat
    Level 38  
    No to wersja minimalistyczna+.
    Bierzesz zegarek PCF8583.
    To jest na I2C.
    Taktujesz go sygnałem 50Hz-bity 4 i 5 w rejestrze 00 ustawione 01.
    Sprawdzasz procesorem czy jest sygnał z sieci.
    Jak nie to ustawiasz te bity na 00-wtedy taktowanie ma z
    kwarcu.
    Wady-dodatkowy element.
    Zalety:
    Mało żre prądu- na podtrzymaniu bateria 3V i dwie diody
    będzie chodził lata.
    Na wyjście INT może wystawiać co 1s przerwanie- dajesz w głównej pętli programu odpytywanie stanu jednej z końcówek procesora i masz czas.
    Możesz taktować procesor z normalnego kwarcu zewnętrznego.
  • #12
    SzymonHK
    Level 20  
    Quote:
    Na wyjście INT może wystawiać co 1s przerwanie- dajesz w głównej pętli programu odpytywanie stanu jednej z końcówek procesora i masz czas.

    Czy nie prościej od razy odpytywać zamiast 1Hz, 100Hz z sieci, a jak sieci nie ma to liczyć kwarc z preskalerem?
  • #13
    janbernat
    Level 38  
    Zaraz- nie rozumiem.
    To zegar wystawia co 1s swój stan-
    procesor sprawdza czy stan się zmienił.
    Jak się zmienił-to odczytuje czas.
    Przez pozostały czas robi co ma robić.
  • #14
    SzymonHK
    Level 20  
    Dwa słowa na temat projektu, podstawową rolą procka jest pomiar temperatury i odczyt pamięci EEPROM, w zależności od tych danych, ustawiany jest stan wyjscia, włączającego przekaźnik, temperatura mierzona przez DS18B20, mierzona jest w głównej pętli ciągle, a stan pamięci odczytywany co 180s i do tego potrzebny jest dokładny pomiar czasu, tak, aby w skali roku odchyłka nie przekraczała jednego odczytu czyli 180s.
  • #15
    janbernat
    Level 38  
    Czyli nie jest potrzebny dokładny czas bezwzględny ale stałe odcinki czasu.
    Trzeba było tak od razu.
    Czyli liczymy z sieci 18000 impulsów i dajemy przerwanie.
    Jak ich nie ma-liczymy z kwarcu.
  • #16
    SzymonHK
    Level 20  
    Dokładnie tak, względny, ale stabilny w długim okresie pomiar czasu.
  • #17
    janbernat
    Level 38  
    Czyli problem główny rozwiązany.
    Pozostaje wykonanie zasilacza buforowanego jakimś akumulatorem i szybkie sprawdzanie czy jest zasilanie sieciowe.

    Dodano po 4 [minuty]:

    Każdy taki zanik zasilania sieciowego wprowadzi pewien błąd.
    Suma błędów będzie zależeć od szybkości reakcji i ilości odłączeń od sieci w ciągu roku.
  • #18
    SzymonHK
    Level 20  
    Główny problem dla mnie to rozwiązanie programowe zmiany żródła impulsów dla licznika przerwania. Jedno zródło to pin, na który doprowadzę 100Hz, drugie to oscylator 4MHz i skonfigurowany licznik. Zaniki sieci nie są obecnie duzym utrapieniem, ale ze względu na względny pomiar muszę zapewnić ciągłość. Zasilacz buforowy już mam z akumulatorkiem 3,6V i 170mA i wyjsciem 100Hz po mostku, odseparowane diodą od filtracji i dzielnik na 4V. Procek to Atmega8L, więc dla 4MHz pobór prądu <5mA, przy zaniku prądu reszta układu nie jest zasilana.
  • #19
    janbernat
    Level 38  
    TCCR1B, bity CS10, CS11 i CS12.
    Do wykrywania zaniku sieci przydałby się jakiś TIMER ale nie wiem czy masz wolny.
    Można napięcie wejściowe z zasilacza dać na jakiś pin procesora i sprawdzać jego stan-ale spadek napięcia będzie dopiero jak się kondensator w zasilaczu rozładuje.
    Można też wziąć napięcie przed mostkiem, wyprostować i dać na układ RC i do pinu.
    Wtedy stała RC decyduje jak szybko procesor się przełączy na wewnętrzne taktowanie.
  • #20
    SzymonHK
    Level 20  
    W programowaniu raczej jestem słabym amatorem, lepiej sie czuje w projektowaniu. Zamiast detekcji sieci, można wykorzystać brak 100Hz jako informację o zaniku zasilania, to najszybsza metoda, bez opóźnień RC.
  • #21
    janbernat
    Level 38  
    Jak ustawisz TIMER jako licznik impulsów zewnętrznych z sieci i będzie liczył 18000 (3min) a po 10000 wyłączą sieć to TIMER będzie czekał... i czekał... aż ponownie włączą sieć.
    Wtedy doliczy brakujące 8000 i da przerwanie.
    Ale nie po 3min a np. po godzinie.

    Dodano po 2 [godziny] 50 [minuty]:

    SzymonHK wrote:
    W programowaniu raczej jestem słabym amatorem, lepiej sie czuje w projektowaniu.

    Ale jakoś ten program musisz napisać.
    I to co napisałem o ustawianiu bitów w rejestrze- to nie jest programowanie a raczej ustawianie sprzętowe.
    Napisanie sensownego programu dla mnie jest też trudne.
    Korzysta się z gotowych procedur i kompilatorów które nie wiadomo do końca jak działają.
    Można w asm-ale każde działanie wydłuża ilość linijek w programie niemożebnie.
    Ale ustawienie sprzętu- czyli konfiguracja rejestrów w procesorze- to jest w zasadzie praca projektowa.
    Na podstawie danych katalogowych.
  • #22
    SzymonHK
    Level 20  
    Program już w zasadzie napisałem, pozostaje jeszcze kwestia przerwania inkrementującego tą zmienną co 180s i parę kosmetycznych rzeczy typu zapalanie kontrolek. Jeśli chodzi o brak impulsów, to na jednej nodze może byc timer, zliczający do 18000, a na drugiej cos na kształt watchdoga, dopuki sa impulsy to polegamy na timerze, jak brak, to zmiana na kwarc, i trzeba bysię chyba oprzeć na jakimś pośrednim cyklu, np. 2 s, w razie zaniku sieci, ginie krótszy odcinek czasu. Zaczyna mi brakować wielowątkowości :D
  • #23
    janbernat
    Level 38  
    No to ten "watchdog" to jest ten prostownik dodatkowy z kondensatorem np. 1uF i opornikiem np. 100kOhm.
    Daje Ci to jakieś 100ms na rozładowanie i przełączasz TIMER1 na kwarc.
    Niezależnie od języka jakiego używasz przełączanie źródła taktowania TIMER-a odbywa się przez wstawienie do rejestru TCCR1B odpowiednich wartości bitów CS (oczywiście to jest dla TIMER1-jak używasz innego timera to inny rejestr).
    A w wielowątkowość nie wierzę.
    To i tak jest tylko podział czasu między poszczególne zadania.

    Dodano po 13 [minuty]:

    Przez rok musisz uzyskać 175200 jednakowych impulsów.
    Ciekawe, jaką stabilność ma sieć.
    Testowanie tego będzie dość długo trwać.
    Przydałby się jednak na czas testów jakiś zewnętrzny wzorzec.
    Przez 10 lat powiedzmy.:D
  • #24
    SzymonHK
    Level 20  
    Rozumiem koncepcję, natomiast brakuje mi obsługi pomiaru napięcia jako wskaźnika do zmiany wartości rejestru.
  • #25
    janbernat
    Level 38  
    Nie mierzysz napięcia tylko sprawdzasz stan na jakimś pinie.
    Po 100 ms od zaniku sieci na tym pinie jest 0V

    Np.
    Do
    ...
    coś robi
    ...
    if jakiś pin=1
    licz impulsy z sieci
    (tzn. rejestr licznika ustawiony na imp. zewn.)
    if jakiś pin=0
    licz impulsy z kwarcu
    ...
    loop.
  • #26
    SzymonHK
    Level 20  
    Atmega moze reagować na zbocze, może dodac jakiś warunek do sprawdzania pinu i nim przełączać żródło, nie byłby konieczny dodatkowy prostownik.
  • #27
    janbernat
    Level 38  
    Zegar na atmega8, długookresowa stałość chodu
    No tak, ale co sprawdzać.
    Jak jest sygnał- to jakieś przerwanie.
    Ale jak nie ma?
    Pin dowolny, schemacik rysowany "na chybcika", mogą być błędy.
  • #28
    SzymonHK
    Level 20  
    Wpadł mi do głowy jeszcze jeden pomysł, czy da radę zrobic taką konstrukcję, timer2 synchronizowany timerem1, przy jego braku (brak sieci) pracyje dalej ale bez synchronizacji ze strony timera1?
  • #29
    janbernat
    Level 38  
    Można wykorzystać jakiś nieużywany timer- jeśli jest.
    Inkrementować jakąś zmienną tymczasową, zapisywać do innej i porównywać.
    Jak pierwsza większa-jest sygnał.
    Jak nie- nie ma sygnału.
    Jeśli jest wolny timer.
  • #30
    SzymonHK
    Level 20  
    Myślę o czymś innym: Timer2 dekrementuje do zera stan jakiegoś licznika, aby odmierzać 180s, potem znowu wpisuje pierwotną wartosc i tak w koło. Timer1, taktowany 100Hz sieci, po przepełnieniu zeruje wartość licznika timera2 i wpisuje wartośc pierwotną, skracając lub wydłużając cykl timera2, jak nie ma 100Hz, nie ma synchronizacji, ale timer2 działa.