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



Teraz jest 30 mar 2026, o 22:38


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 13 ] 
Autor Wiadomość
PostNapisane: 3 maja 2013, o 21:47 
Offline
Nowy

Dołączył(a): 16 mar 2013
Posty: 19
Pomógł: 0

Witam.
Tworzę program który ma za zadanie odczytać pozycję serwa i na wyjściu podać wartość od 0 do 255.

Stan wysoki impulsu pojawia się co 20ms i trwa ok 1ms, więc początkowa idea była następująca:

Wejście sygnału podłączone do INT0 wyzwala przerwanie gdzie na zboczu narastającym timer zaczyna liczyć ile razy przerwanie od timer-a zostało wykonane, a na opadającym zapisuje wynik do zmiennej. Timer0, tryb normal bez preskalera, wyzwala przerwanie co 4us. (1000/256)

1) 1s / 8MHz = 0,125us - co 0,125us timer dostaje impuls do rejestru TCNT0.
2) 4us / 0,125 = 32, więc 256 - 32 = 224 czyli timer ma zliczać od TCNT0 = 224.

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


Kod ten działa ale problemem jest wynik który jest taki sam jak przy TCNT0 = 0. Cokolwiek bym do tego rejestru nie wpisał wynik jest taki jak powinien być przy TCNT0 = 0.

Proszę o pomoc, w rozwiązaniu problemu.

Procek to Atmega8 taktowana wewnętrznym oscylatorem 8MHz, dokładności nie ziemskiej się nie spodziewam.
Wybrałem przerwanie INT0 ponieważ to jeden z niewielu wolnych pinów na płytce. :D

Z góry dziękuje. Pozdrawiam. ;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 maja 2013, o 10:22 
Offline
Nowy
Avatar użytkownika

Dołączył(a): 02 sty 2013
Posty: 11
Pomógł: 1

proszę oto jedna z koncepcji

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


Jest to tylko kod obsługi przerwania INT0.

Preskaler w liczniku ustawiasz na 64. Dzięki temu otrzymamy:

8 000 000 Hz / 64 = 125 000 Hz
125 000 Hz / 256 = 488,281 250 Hz
1 s / 488,281 250 = 0,002 048 s ( około 2 ms )
0,002 048 s / 256 = 0,000 008 s ( 8 us )

Tym sposobem, jeżeli zmienna wynik wyniesie np. 200 to wiadomo że, serwo wychylone będzie np. w prawo.
Ponieważ 8 us * 200 = 1,6 ms . Jak wiadomo jeśli serwo dostaje impuls około 1,5 ms to jest to pozycja neutralna. Wartości odbiegające od tej normy powodują wychylenie w lewo lub w prawo.
Zaznaczam, że mogę wypisywać tu jakieś herezje bo w programowaniu avr-ów jestem średnio początkujący.

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 maja 2013, o 11:03 
Offline
Nowy

Dołączył(a): 16 mar 2013
Posty: 19
Pomógł: 0

Dzięki za odpowiedź.
Co do obliczeń, nie rozumiem dlaczego 2 razy dzielisz przez 256?

8 000 000 Hz / 64 = 125 000 Hz
125 000 Hz / 256 = 488,281 250 Hz
1 s / 488,281 = 0,002 048 s ( około 2 ms )

Przerwanie wykona się co 2ms. Zgadza się?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 maja 2013, o 11:24 
Offline
Nowy
Avatar użytkownika

Dołączył(a): 02 sty 2013
Posty: 11
Pomógł: 1

panowie mamy tu do czynienia z przerwaniem od INT0 a nie timera0.

Adam napisał(a):
....
Co do obliczeń, nie rozumiem dlaczego 2 razy dzielisz przez 256?
...

Jeśli licznik zliczy do 256 to minie około 2ms. A zatem jeśli licznik zliczy tylko do 1 to minie 80us. Obliczam w ten sposób czas 1 impulsu.

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 maja 2013, o 11:59 
Offline
Nowy

Dołączył(a): 16 mar 2013
Posty: 19
Pomógł: 0

no tak... całkowicie o tym zapomniałem. Dzięki.

Teraz kod 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.


I działa o wiele lepiej. :D Jednak nie pojmuje jednej rzeczy. Bo stan wysoki zmienia się od 1ms do 2ms, więc od zmierzonego czasu trzeba odjąć 1ms i mamy przedział od 0 - 1ms. Ale w zależności od tego urządzenia zadającego odpowiedni impuls czas ten może być krótszy lub dłuższy w moim przypadku jest to ok 800us, więc postanowiłem do rejestru TCNT0 przypisywać większą wartość 240 i niestety jest problem. Wynik jest ten sam co przy TCNT0 = 224 i odświeżany ok 2 razy na sekundę.
W czym może tkwić problem?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 maja 2013, o 12:03 
Offline
Nowy
Avatar użytkownika

Dołączył(a): 02 sty 2013
Posty: 11
Pomógł: 1

Chyba się za bardzo nie rozumiemy. Z zastosowaniem mojej koncepcji musi ulec zmianie prawie cała funkcja main (). Nie ma przerwania od timera0. wszystko załatwia INT0. W zmiennej wynik otrzymamy czas trwania impulsu sterującego serwo.
Wyjaśnię może co nieco. Jeśli zmienna wynik wyniesie np. 187 to będziesz wiedział, że serwo jest w pozycji neutralnej. Ponieważ 187 * 8 us da nam 1,5 ms.

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 maja 2013, o 12:25 
Offline
Nowy

Dołączył(a): 16 mar 2013
Posty: 19
Pomógł: 0

Rozumiem, tylko problemem jest wynik. Chodzi o to aby w pozycji neutralnej było ok 128 +/- 10. analogicznie wychylanie w prawo, lewo. Będzie mi to później potrzebne.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 maja 2013, o 12:35 
Offline
Nowy
Avatar użytkownika

Dołączył(a): 02 sty 2013
Posty: 11
Pomógł: 1

Spróbuj tak. Ustaw serwo w pozycji skrajną lewo i odczytaj zmienną wynik. Ustaw w pozycję skrajną prawą odczytaj zmienną wynik. Jeśli dodasz te dwie wartości i podzielisz przez dwa to otrzymasz pozycję neutralną.

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 maja 2013, o 13:03 
Offline
Nowy

Dołączył(a): 16 mar 2013
Posty: 19
Pomógł: 0

Ok, otrzymam w ten sposób pozycję neutralną ale ja w programie potrzebuje mieć wartości od 0 do 255 i nie mogę na to czekać dłużej niż 50ms.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 maja 2013, o 14:10 
Offline
Nowy
Avatar użytkownika

Dołączył(a): 02 sty 2013
Posty: 11
Pomógł: 1

Możesz przybliżyć z jaką częstotliwości pozycja tego serwa się zmienia?

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 maja 2013, o 14:39 
Offline
Nowy

Dołączył(a): 16 mar 2013
Posty: 19
Pomógł: 0

50Hz czyli co 20ms idzie impuls od 1ms do 2ms.

------------------------ [ Dodano po: 36 minutach ]

Czym mogą być spowodowane błędy jeśli przypisuje przypisuje do TCNT0 więcej niż 224? (ostatni kod) Poniżej tej wartości wszystko działa jak należy, przy wyższej wartość, odświeżanie wyniku jest ok 2 razy na sekundę a wyniki nie są poprawne.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 maja 2013, o 15:37 
Offline
Nowy
Avatar użytkownika

Dołączył(a): 02 sty 2013
Posty: 11
Pomógł: 1

Może wyjaśnię jeszcze raz. W zmiennej wynik masz zawsze aktualną pozycję serwa. Ponieważ w przerwaniu przy zboczu narastający uruchamiasz timer0 zwiększasz flagę i zmieniasz przerwanie INT0 na zbocze opadające. Wychodzimy z przerwania a timer dalej zlicza długość impulsu od serwa. Impuls ten trwa np. 1,5 ms po tym czasie zmieni się stan z wysokiego na niski i wyzwoli przerwanie INT0 (zbocze opadające ) . W obsłudze przerwania w drugim warunku instrukcji switch zatrzymujemy timer zerujemy flagę i wartość licznika przypisujemy do zmiennej wynik i zmieniamy zbocze na narastają. I cykl się powtarza. Więc co 20ms masz zawsze nową pozycję serwa w zmiennej wynik. Przy długości impulsu 1,5 ms timer zliczy do około 187. Przy długości impulsu np.1,25ms licznik zliczy do około 156 ( 0,00125 s / 0,000 008 s ).

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 maja 2013, o 19:40 
Offline
Nowy

Dołączył(a): 16 mar 2013
Posty: 19
Pomógł: 0

Rozumiem twój kod i wiem jak on działa. Poprzednie moje pytanie odnosiło się do mojego ostatniego kodu. Twoja idea nie jest zła, też o tym myślałem ale przy taktowaniu 8Mhz i timer0 nie da się tego zrobić żeby na wyjściu była liczba od 0 do 255. Teraz myślę nad twoim pomysłem ale na timerze1 który ma 16 bitów.



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: 13 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

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


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