Eksperymentowałem ostatnio z synchronizacją czasu w układzie z Atmegą i ENC28J60. Użyłem gotowych funkcji zaimplementowanych w stosie tuxgraphics.org, z niewielkimi modyfikacjami (głównie przeliczanie odebranej wartości na Unix epoch. Generalnie rozwiązanie jest bardzo proste. Programowy licznik odlicza w dół liczbę sekund pomiędzy kolejnymi synchronizacjami (w tej chwili
3600). Gdy dojdzie do zera wysyłany jest pakiet z requestem. Jednocześnie w momencie przyjścia pakietu UDP funkcja sprawdza, czy mamy do czynienia z odpowiedzią - jeśli tak, to do zmiennej volatile int32_t rtc ładowany jest odebrany czas. Obliczanie wartości wygląda następująco: *time = ( ( ((uint32_t)buf[0x52]<<24) | ((uint32_t)buf[0x53]<<16) | ((uint32_t)buf[0x54]<<8) | ((uint32_t)buf[0x55]) ) - 2208988800UL )Pomiędzy synchronizacjami zegar jest inkrementowany w przerwaniu timera. Przerwanie jest wywoływane co 1ms - normalnie zwiększana jest zmienna pomocnicza, jednak w przypadku przekroczenia przez nią wartości 1000 uruchamia się obsługa zegara i kilku programowych liczników.
Program zdaje się działać prawidłowo, jednak byłem ciekaw na ile jest dokładny. Napisałem prosty skrypt na Raspberry Pi, który odczytuje czas z omawianego urządzenia i odejmuje go od czasu systemowego w RasPi. Wyniki są dziwne. Nieraz mam kilka sekund różnicy, czasem jednak pojawia się wynik w granicach 60 sekund. Niekiedy większą różnicę obserwuję tuż po synchronizacji.
Nie wydaje mi się, żeby mogło to wynikać z niedokładności timera Atmegi
- niewielki dryf ie objawiłby się tak szybko. No chyba, że jeszcze zegar w RasPi ma tak tragiczną stabilność.
Gdzie mogę szukać przyczyn takiego zachowania?