Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 19 mar 2026, o 19:02


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 23 ] 
Autor Wiadomość
PostNapisane: 7 sty 2016, o 23:42 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 02 kwi 2015
Posty: 450
Pomógł: 3

Witam!
Zorganizowałem licznik 100ms w przerwaniu timera sprzętowego. Próbuję zmusić licznik aby po doliczeniu do konkretnej wartości (np.600) uległ wyzerowaniu, wykonał ciąg instrukcji switch case (linia 7), a następnie liczył dalej do 600 i tak bez przerwy. Nie bardzo wiem, w którym miejscu kodu umieścić tę procedurę. Bardzo proszę o pomoc.

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

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

Pozdrawiam



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 sty 2016, o 00:25 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 sty 2013
Posty: 1760
Pomógł: 196

Witam
avrfun napisał(a):
wykonał ciąg instrukcji switch case

...ale tak "ciurkiem" czy co 100ms?

Pozdr.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 sty 2016, o 06:38 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 02 kwi 2015
Posty: 450
Pomógł: 3

Cytuj:
...ale tak "ciurkiem" czy co 100ms?

Witam!
Co 100ms



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 sty 2016, o 14:01 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 02 kwi 2015
Posty: 450
Pomógł: 3

Witam.

Przeprowadzając badania nad "rozjeżdżaniem się" timerów programowych napisałem krótki program testowy (poniżej). Umieściłem w nim 2 debuggery jednodiodowe. Spodziewałem się, że obie diody będą mrugać w tym samym rytmie gdyż timer programowy (tu z założenia) powinien zerować się co 10ms, ale tak nie jest (zdjęcie poniżej). Nie potrafię tego wyjaśnić. Proszę o podpowiedź.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Obrazek
Pozdrawiam



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 sty 2016, o 14:49 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

W którymś momencie Timer1 dochodzi Ci do zera i już z nim nic nie robisz.
W pętla główna się cały czas wykonuje, bo tam masz już spełniony warunek
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


--
Pozdrawiam,
Robert



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 sty 2016, o 14:57 
Offline
Użytkownik

Dołączył(a): 24 sty 2012
Posty: 1469
Pomógł: 56

A jak wygląda deklaracja i definicja zmiennej Timer1

------------------------ [ Dodano po: 2 minutach ]

rskup napisał(a):
W którymś momencie Timer1 dochodzi Ci do zera i już z nim nic nie robisz.
W pętla główna się cały czas wykonuje, bo tam masz już spełniony warunek
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


--
Pozdrawiam,
Robert

Nie, nie... w przerwaniu jest cały czas dekrementowana, więc się przekręca i znów działa.

_________________
Jestem początkujący i moje porady mogą być błędne



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 sty 2016, o 15:02 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

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

Więc tylko wykonuje się jak Timer1 (n) jest różny od 0.

--
Pozdrawiam,
Robert



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 sty 2016, o 15:20 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 02 kwi 2015
Posty: 450
Pomógł: 3

rskup napisał(a):
W którymś momencie Timer1 dochodzi Ci do zera i już z nim nic nie robisz.
W pętla główna się cały czas wykonuje, bo tam masz już spełniony warunek
Składnia: [ Pobierz ] [ Ukryj ]
język c
if(!Timer1){
GeSHi



Dzięki. Dodałem linię 20, aby po wyzerowaniu timera ustawiać go na 1 czyli 10ms, a więc po 100ms powinien wykonać się warunek case 10. W terminalu cyfry od 1-4 pojawiają się po kolei i co 150 tyknięć, ale LED PC6 nadal mruga nieregularnie, więc nie wiem jaka jest częstotliwość zmian i ile trwa tyknięcie. Chciałbym aby warunki instrukcji switch wykonały się po kolei co 100ms.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


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

Obrazek
Absolutny brak regularności w wyświetlaniu kolejnych cyfr w terminalu! Dla mnie w chwili obecnej niezrozumiałe.
Wygląda to jak interferencja dwóch lub więcej rytmów (częstotliwości), które wypadkowo dają nieregularne mruganie diody (impulsy mają długość: 10ms, 30ms (najczęściej) oraz rzadko 20ms).



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 sty 2016, o 19:10 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 02 kwi 2015
Posty: 450
Pomógł: 3

W jaki sposób użyć flag przerwania timera sprzętowego (TIMER0 CTC Atmega32) zamiast timera programowego, czyli zamiast: if(!Timer1) {instrukcja; Timer1=100}. Pomyślałem, że po co tworzyć timer programowy gdy można bezpośrednio wykorzystać flagi przerwań - będzie dokładniej ;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 sty 2016, o 19:22 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

Czy przypadkiem funkcja puts() nie jest blokująca?
Daj
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
jako pierwszą instrukcję w warunku (tym pierwszym, bo i tak sprawdzasz to samo dwa razy).
Jakiej prędkości rs232 używasz?

--
Pozdrawiam,
Robert

------------------------ [ Dodano po: 6 minutach ]

Jak chcesz mieć regularność twojego programu, to timer nie powinien być zatrzymywany w przerwaniu tylko ponownie przeładowywany a do głównej części programu iść tylko znacznik (inna zmienna) o przepełnieniu licznika.
Dodatkowo nie ma sensu działania ze zliczaniem 1 impulsu bo dokładność masz jednego impulsu ;( Ustawiając Timer1 = 1 nie wiesz na jakim etapie zliczania jest licznik w TIMER0.

------------------------ [ Dodano po: 11 minutach ]

Cytuj:
W jaki sposób użyć flag przerwania timera sprzętowego (TIMER0 CTC Atmega32) zamiast timera programowego, czyli zamiast: if(!Timer1) {instrukcja; Timer1=100}. Pomyślałem, że po co tworzyć timer programowy gdy można bezpośrednio wykorzystać flagi przerwań - będzie dokładniej

Timer programowy ma sens jak zliczasz np. 100 lub 1000 razy wolniejsze zdarzenia niż przerwanie przepełnienia. Ty próbujesz robić to 1 do 1, więc ciężko to nazwać timerem programowym.
Aby sprawdzić czy nastąpiło przepełnienie to nie włączasz przerwania TIMER0_COMP, tylko sprawdzasz flagę w rejestrze. Masz to wszystko podane w datasheetcie do procesora.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 sty 2016, o 19:35 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 sty 2013
Posty: 1760
Pomógł: 196

Witam
A może tak na żywca; "u mnie" takt to wyliczone 100ms.
Nie wiem czy zadziała; tak bym próbował:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

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



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 sty 2016, o 22:38 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 02 kwi 2015
Posty: 450
Pomógł: 3

Bardzo dziękuję za porady. Program działa jak należy i "równo" w takt 100ms :D
rskup napisał(a):
jako pierwszą instrukcję w warunku (tym pierwszym, bo i tak sprawdzasz to samo dwa razy).
Jakiej prędkości rs232 używasz?

Tak zrobiłem: Timer1=10 jako pierwsza instrukcja
RS232: 115200
rskup napisał(a):
Dodatko
wo nie ma sensu działania ze zliczaniem 1 impulsu bo dokładność masz jednego impulsu ;( Ustawiając Timer1 = 1 nie wiesz na jakim etapie zliczania jest licznik w TIMER0.

Zliczam po 10 impulsów (10x10ms)
rskup napisał(a):
Aby sprawdzić czy nastąpiło przepełnienie to nie włączasz przerwania TIMER0_COMP, tylko sprawdzasz flagę w rejestrze. Masz to wszystko podane w datasheetcie do procesora.

Rozumiem, że należy napisać coś w rodzaju: if(flaga sprzętowa){instrukcja}. Jak jednak zliczać 10 takich flag na tyknięcie (100ms), czyli jak zastąpić warunek Timer1=10?
kicajek napisał(a):
A może tak na żywca; "u mnie" takt to wyliczone 100ms.

Działa dobrze. Rozumiem, że zliczasz 5 impulsów po 20ms na takt?

Pozdrawiam



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sty 2016, o 00:52 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

Cytuj:
Zliczam po 10 impulsów (10x10ms)
Wcześniej podawałeś kod:
Cytuj:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
choć teraz już piszesz:
Cytuj:
Tak zrobiłem: Timer1=10 jako pierwsza instrukcja



Cytuj:
należy napisać coś w rodzaju: if(flaga sprzętowa){instrukcja}.

Tak. Sprawdzasz flagę. Jak jest ustawiona, to ją od razu kasujesz (uwaga, kasuje się przez wpisanie 1) i zmniejszasz Timer1. Jak Timer1 = 0, to go ustawiasz na wartość startową (10) i wykonujesz operacje.
Nie napisałeś jaki masz procesor. Ale dla ATmega32 jest to:
Obrazek


Cytuj:
Jak jednak zliczać 10 takich flag na tyknięcie (100ms), czyli jak zastąpić warunek Timer1=10?
Aby mieć sprawdzanie 10 tyknięć to musisz i tak mieć zmienną typu Timer1, która będzie je zliczać. Proponowana przez Ciebie obsługa flag, to po prostu realizacja timera programowego w całości w pętli głównej. Ale raczej tak nie powinno się robić. Aby mieć dokładny timer programowy, to zliczanie tyknięć TIMER0 powinny być robione na przerwaniach. Gdybyś to robił w pętli głównej, to musiałbyś mieć gwarancję, że najdłuższy czas wykonania pętli głównej jest krótszy od tyknięcie TIMER0, bo inaczej możesz zgubić jakieś tyknięcie. Jak robisz to na przerwaniu, to pętla główna powinna być jedynie krótsza niż wartość timera programowego (u ciebie 10 tyknięć TIMER0).

--
Pozdrawiam,
Robert



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sty 2016, o 10:10 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 02 kwi 2015
Posty: 450
Pomógł: 3

Witam.
rskup napisał(a):
Wcześniej podawałeś kod:
Cytuj:
Składnia: [ Pobierz ] [ Ukryj ]
język c
if(!Timer1) Timer1 = 1;
GeSHi
choć teraz już piszesz:
Cytuj:
Tak zrobiłem: Timer1=10 jako pierwsza instrukcja

Po przemyśleniu i Twoich poradach o dwukrotnym sprawdzaniu tego samego warunku it(!Timer1) i "rozdzielczości", sprawdzam go tylko raz, a Timer ustawiam na 10, zamiast na 1.

rskup napisał(a):
Aby mieć sprawdzanie 10 tyknięć to musisz i tak mieć zmienną typu Timer1, która będzie je zliczać. Proponowana przez Ciebie obsługa flag, to po prostu realizacja timera programowego w całości w pętli głównej. Ale raczej tak nie powinno się robić. Aby mieć dokładny timer programowy, to zliczanie tyknięć TIMER0 powinny być robione na przerwaniach. Gdybyś to robił w pętli głównej, to musiałbyś mieć gwarancję, że najdłuższy czas wykonania pętli głównej jest krótszy od tyknięcie TIMER0, bo inaczej możesz zgubić jakieś tyknięcie. Jak robisz to na przerwaniu, to pętla główna powinna być jedynie krótsza niż wartość timera programowego (u ciebie 10 tyknięć TIMER0).

To rozjaśnia moje spojrzenie na zagadnienie flag przerwań sprzętowych. Sądziłem, że sprzętowo będzie dokładniej, ale teraz rozumiem, że kluczem do tej dokładności jest długość pętli głównej.

Bardzo dziękuję
Pozdrawiam



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sty 2016, o 13:55 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

Cytuj:
To rozjaśnia moje spojrzenie na zagadnienie flag przerwań sprzętowych. Sądziłem, że sprzętowo będzie dokładniej, ale teraz rozumiem, że kluczem do tej dokładności jest długość pętli głównej.

Dokładnie liczy timer sprzętowy. W pętla głównej umieszczasz funkcje wymagające dłuższego czasu ich wykonania, ale timerowi sprzętowemu to nie przeszkadza, bo ma przerwania, które się wykonują wstrzymując działanie pętli głównej. Lecz jeżeli chcesz sam sprawdzać flagę znacznika przepełnienia zamiast generować przerwanie, to nie musisz to robić natychmiast po jej ustawieniu, ale musi to być szybciej niż jedno tyknięcie timera sprzętowego, bo inaczej będziesz gubił "tyknięcia".
Podobna zasada dotyczy timera programowego, tylko tutaj zakładasz jego długość x razy więcej niż sprzętowego. Dlatego aby zgubić jego "tyknięcie" to musisz w tym wypadku działać w pętli głównej x razy wolniej niż jakbyś sprawdzał flagę.
Dodatkowo timer programowy możesz używać w dwóch trybach. Pierwszy to wystawiający flagę a liczący od razu od początku. Więc jak nie zgubisz, jak wcześniej wpisałem jego tyknięcia, to masz dokładne odstępy. W drugiej wersji nie zliczasz kolejnych tyknięć dopóki nie zaczniesz obsługiwać tego timera. Przez co będziesz miał zmienną długość czasu timera (zależnie od długości działania pętli głównej), ale gwarancję że nie będą zgubione żadne tyknięcia.
Sam musisz wybrać jakie są wymagania Twojego rozwiązania i co będzie najlepsze.

Teoretycznie także możesz liczyć i obsługiwać timer programowy na przerwaniu. Tylko funkcje wykonywane na nim muszą to być proste - na przykład miganie diodą.
Choć może miganie diodą lepiej robić na początku w pętli głównej, bo jej nieregularność od razu mówi, że coś nie do końca tak robimy.

--
Pozdrawiam,
Robert



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sty 2016, o 15:52 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 02 kwi 2015
Posty: 450
Pomógł: 3

rskup napisał(a):
Sam musisz wybrać jakie są wymagania Twojego rozwiązania i co będzie najlepsze.
rskup napisał(a):
Choć może miganie diodą lepiej robić na początku w pętli głównej, bo jej nieregularność od razu mówi, że coś nie do końca tak robimy.


Dziękuję za wyjaśnienia.
Powodem dla którego założyłem ten wątek jest rozjeżdżający się timer programowy w dawcy czasu wykorzystywany do odmierzania czasu do synchronizacji wg polecenia:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Na debuggerze jednodiodowym i liczniku na LCD obserwuję jego zacinanie się co przekłada się na dłuższe i krótsze czasy do następnej synchronizacji przy stałym zadanym odstępie np. 10 minut. Postanowiłem więc wykonać "ciało" GetNtpTime_EVENT jako osobny program z użyciem timera programowego i flag. Obie wersje działają bardzo dobrze i synchronizacja jest dokładna. Umieszczenie tego w moim kombajnie skutkuje dławieniem się synchronizacji. Tak wygląda pętla while(!):
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Włączałem i wyłączałem poszczególne instrukcje w różnej kombinacji, ale nieregularność pozostaje. Nie chodzi mi o super dokładność, bo czy synchronizacja nastąpi po 10 czy 15 minutach nie ma znaczenia dla sprawy, ale chodzi o wymknięcie się programu spod mojej kontroli, a to już jest trudne do przyjęcia. Czytając Twoje wyjaśnienia pomyślałem, że można wymusić na sztywno synchronizację po zadanym czasie za pomocą flagi timera sprzętowego licząc się nawet ze stratami. Wyobrażam to sobie tak. Zadany czas do synchronizacji ustawiam np. na 10 minut. Chimeryczny timer programowy generując kolejne tyknięcia co 70, 100, 140, 60ms sprawia, że 10 minut uzbiera się w różnym czasie. Flaga timera sprzętowego zostanie wystawiona dokładnie po 10 minutach i wymusi synchronizację. Powtarzalność 99.99%. Czy takie podejście jest poprawne merytorycznie, a jeżeli tak to jak to zrealizować?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sty 2016, o 16:17 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

A gdzie masz zliczanie timera programowego?
Daj więcej kodu. Szczególnie tego związanego z timerami.

--
Pozdrawiam,
Robert



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sty 2016, o 16:42 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 02 kwi 2015
Posty: 450
Pomógł: 3

Cytuj:
A gdzie masz zliczanie timera programowego?
Daj więcej kodu. Szczególnie tego związanego z timerami.

Organizacja timerów programowych:
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.

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.

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

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



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 sty 2016, o 02:25 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

Masz w procedurze obsługi przerwania timera (TIMER2_COMP) zatrzymywanie liczenia dla zmiennych timera programowego Timer1/3/5/_SuperDebounce. Liczenie ponownie uruchamiane jest dopiero w elementach pętli głównej w momencie obsłużenia danego zdarzenia wykonywanego przy wyzerowaniu zmiennej Timer1/3/5/_SuperDebounce. Jest to poprawne, ale czas liczony między kolejnymi zerowaniami danej zmiennej to nie tylko czas wyznaczony przez przerwania przepełnienia timera ale także czas jaki mija na dojście w pętli głównej do momentu ponownego uruchomienia zliczania danego timera programowego (wpisanie do niego wartości różnej od zera). A ten drugi czas zależy od czasu wykonania pozostałych funkcji / eventów w pętli głównej a także od momentu w którym akurat trafi się wyzerowanie zmiennej timera programowego (jak stanie się to tuż przed daną procedurą, to następuje szybko a jak zaraz po niej, to zajmie to czas potrzebny do obsłużenia wszystkich funkcji).
Zwróć też jeszcze uwagę, że timer dla NTP uruchamiasz ponownie (* tmr_100ms = 16;) na koniec procedury. Czyli musi się wykonać wszystko co masz tam w danym momencie zrobić i dopiero zaczynasz liczyć. Czyli raz dzieje się to szybciej a raz wolniej.

Dlatego nie dziwi mnie że Twoje 10 minut jest raz bliższe a raz dalsze tego spodziewanego okresu.

--
Pozdrawiam,
Robert



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 sty 2016, o 02:25 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

Co zduplikował się poprzedni post :(



Ostatnio edytowano 13 sty 2016, o 18:33 przez rskup, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 sty 2016, o 07:42 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 02 kwi 2015
Posty: 450
Pomógł: 3

rskup napisał(a):
Dlatego nie dziwi mnie że Twoje 10 minut jest raz bliższe a raz dalsze tego spodziewanego okresu.

Witam.
Dziękuję za wyjaśnienia. Rozumiem, że timer programowy jest "zatrzymywany" poprzez ustawienie wartości w pętli głównej na różnym etapie swojego odliczania co zaburza cykl jego pracy i raz ma bliżej, a raz dalej do 0. Czy znasz sposób rozwiązania tego problemu?
Pozdrawiam



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 sty 2016, o 20:01 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

Cytuj:
Rozumiem, że timer programowy jest "zatrzymywany" poprzez ustawienie wartości w pętli głównej

Timer programowy jest zatrzymywany w procedurze obsługi przerwania timera sprzętowego. Bo zmienna jest zmieniana tylko w przypadku wartości różnej od zera a w momencie wyzerowania już nie:
Cytuj:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Załadowanie ponownej wartości różnej od zera następuje w funkcjach / eventach wywoływanych w pętli głównej. I tak dla Timer3 następuje to w evencie GetNtpTime_EVENT() i to samym jego końcu. Więc masz od momentu wyzerowania wartości Timer3 do czasu jego przeładowania nową wartością zatrzymany timer programowy. A czas przeładowania jest zależny jak szybko wejdziesz w GetNtpTime_EVENT() i jakie elementy w nim będą wykonane.

--
Pozdrawiam,
Robert



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 13 sty 2016, o 17:58 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 02 kwi 2015
Posty: 450
Pomógł: 3

rskup napisał(a):
Dlatego nie dziwi mnie że Twoje 10 minut jest raz bliższe a raz dalsze tego spodziewanego okresu.

Witam!
Poradziłem sobie z problemem rozjeżdżania się timera programowego odliczającego czas do następnej synchronizacji poprzez... rezygnację z niego. Wykorzystałem sekundowe zmiany flagi sprzętowej przerwania INT0 - z czasem synchronizacji podawanym jako argument RTC_EVENT(). Teraz synchronizacja jest precyzyjna w dowolnym okresie czasu. Zauważyłem jednak ze zgrozą ;) , że kropka sekundowa mruga bardzo nieregularnie w rytm... timera programowego (cy2 bez kropki / cy2 z kropką). Nie wiem jak włączyć mruganie cy2 w rytm "INT0", a może rozwiązać to zupełnie inaczej. Proszę o rady.
Rozwiązanie w chwili obecnej wygląda tak:
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.

Pozdrawiam



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 23 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 1 gość


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO