Skocz do zawartości

Atmega8 sterowanie serwa na OC2


paralitax

Pomocna odpowiedź

Witam ! Muszę napisać program pozwalający mi na sterowanie serwem podpiętym do wyprowadzenia OC2 Atmegi8.

Bardzo proszę o sprawdzenie kodu, czy w ogóle zadziała. Jestem początkujący dlatego proszę o ograniczone zaufanie. Na razie skleciłem coś takiego:

#define F_CPU 1000000
#include <avr/io.h>

int main()
{


DDRB = 0xff; //konfiguracja portów

TCCR2 = (1<<CS21)I(1<<WGM20) //wyjscie ustawione na 8 bitowy PWM z korektą fazy, preskaler na 1 (nie wiem czy nie powinien być wyższy dla serwa)

ICR1 = 20000; //ustawienie okresu na 20ms(czestotliwosc 50Mz) (nie wiem czy to w ogóle tu ma być



OCR1A = 2000; //określenie czasu impUlsu

While(1)

{
//tutaj isntrukcje do sterowania serwem

}

}

__________

Komentarz dodany przez: Nawyk

Stosuj, proszę, znaczniki "code" przy pisaniu postów z kodem źródłowym

Link do komentarza
Share on other sites

Po pierwsze wstawiaj kod w odpowiednich znacznikach. Będzie się go lepiej przeglądało.

Po drugie coś tutaj bardzo namieszałeś.

Wyjście OC2 to wyprowadzenie Timera 2. Musisz go odpowiednio skonfigurować i wprowadzić odpowiednie wartości do rejestrów ICR2 i OCR2. A Ty je wpisujesz do rejestrów Timera 1. Poza tym Timer 2 jest 8-bitowy więc musisz ustawić większy preskaler.

Link do komentarza
Share on other sites

Jesteś początkujący, więc podam najprostsze rozwiązanie, które będzie ruszało serwem na PB3

ustaw timer: TCCR2 = 0b01101010;

Wartości ICR nie podawaj wogóle, po prostu wywal tę linię.

W pętli while podawaj wartości OCR2 oddzielone pętlą opóźniającą np:

OCR2 = 100;

_delay_ms(500);

OCR2 = 50;

_delay_ms(500);

Te wartości OCR powinny zadziałać, jednak popraw je zgodnie ze swoim serwem

Tak z innej mańki w kodzie masz błąd ortograficzny:p

Nie piszemy: (1<

Tylko: (1<

Link do komentarza
Share on other sites

Dzięki za odpowiedź. Może jeszcze nie bardzo orientuję się w programowaniu w C, więc mogę się mylić, ale... Taką pętlę rozumiem jak działa, problem polega na tym, że w pętli while będę miał jeszcze obsługę przycisków sterujących wypełnieniem PWM'a. Szkoda, że nie napisałem tego wcześniej. Timera1 nie używam do serwa bo steruje on PWMem podwójnego mostka H l298. A potrzebuję jeszcze wysterować jakoś serwo na jednym uC. We wspomnianej pętli while są również inne instrukcje do obliczania wartości zmiennych itd. Podsumowując: W pętli while po kolei wykona się instrukcja podana przez ciebie generująca impuls do serwa, następnie program przejdzie do obsługi pozostałych instrukcji i zostawi ten impuls, a na serwo powinien on być podawany przez cały czas. Dobrze rozumuję?

Jeszcze gdybyś mógł wytłumaczyć mi co oznacza zapis: TCCR2 = 0b01101010, jeszcze się z takim nie spotkałem.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Hmm wszystkie instrukcje podane Ci przez kolegę deuther masz wpisać w funkcji main() przed pętlą while(). One się wykonują tylko raz. Te instrukcje nie generują PWM tylko ustawiają Timer 2 w odpowiedni tryb pracy. Później Timer 2 sam będzie generował impuls PWM. Na tym właśnie polega sprzętowe generowanie PWM, że nie musimy ręcznie tego robić tylko uruchamiamy i dalej już leci.

Tamten zapis o który pytasz na końcu to po prostu ustawienie odpowiednich bitów w rejestrze TCCR2. Tam gdzie jedynki do dany bit ma być ustawiony, a tam gdzie zera to ma być wyzerowany. Możesz to inaczej wpisać.

Na marginesie: w jaki sposób generujesz sygnał PWM licznikiem pierwszym do mostków, skoro nie rozumiesz sprzętowego generowania?? Robisz to programowo??

Link do komentarza
Share on other sites

Jeszcze gdybyś mógł wytłumaczyć mi co oznacza zapis: TCCR2 = 0b01101010, jeszcze się z takim nie spotkałem.

"0b" oznacza, że jest to zapis bitowy, najpierw najbardziej znaczący bit. Mamy tutaj 8 bitów. Jeśli chciałbyś to zapisać heksadecymalnie to masz taki zapis: 0x6A albo w układzie dziesiętnym 106 🙂

Link do komentarza
Share on other sites

Ogólnie jednak proponowałbym stosowanie takiego zapisu:

TCCR2 |= _BV(CS12) | _BV(WGM20)

Jest znacznie czytelniejszy 😉 Takie cuś ustawia bity CS12 i WGM20 w rejestrze TCCR2. CS12 i WGM20 to tak naprawdę zdefiniowane pod ładną nazwą numerki bitów, a _BV(bit) to to samo co (1<

Link do komentarza
Share on other sites

deuther powiedz mi tylko czy to będzie działać jeśli w pętli while dalej zapiszę kolejne instrukcje np do zmiany wartości OCR2 poprzez przycisk i zmiana wartości PWM TIMERA1. Czy sterowanie serwa będzie działać poprawnie? Przecież impuls dla serwa powinien powtarzać się na okrągło (tak skrótowo myśląc). Rozumiem, że te wstrzymania _delay_ms pomiędzy OCR2 zastępują korektę częstotliwości której TIMER2 nie posiada. Bo sprzętowo z tego co mi wiadomo nie da się sterować serwa poprzez TIMER2.

Link do komentarza
Share on other sites

Da się sprzętowo sterować serwo tmierem2, właśnie to robisz. Musisz zrozumieć jedną rzecz. Pętla while działa sobie oddzielnie i timer oddzielnie.To tak jak masz zegarek na ręce, włączasz stoper i on zaczyna zliczać, jednak główny zegar(główny program) pracuje nadal poprawnie, pokazuje Ci czas i date pomimo tego, że gdzieś "obok" napitala sobie stoper. Ważne jest to, że stoper włączyłeś gdzieś z poziomu głównego programu! I teraz tak, Twoja pętla wykonuje się co jakiś bardzo szybki czas (tym dłuższy, im dłuższe delayie powstawiasz). Pamiętając o tym, że stoper mogliśmy włączyć z poziomu programu, należy tutaj podkreślić, że parametrami JUŻ DZIAŁAJĄCEGO NIEZALEŻNIE TIMERA możesz sterować w tej głównej pętli (np zmieniając wypełnienie pwm OCR). W naszym wypadku funkcje delay nie mają nic wspólnego z częstotliwością sygnału (bo tę determinuje niezależny timer), określają one tylko czas w jakim serwo będzie w danym położeniu. Skutkiem ubocznym jest to, że ich obecność spowalnia szybkość pętli, a więc np reakcję guzików. Jeżeli zatem chcesz sterować położeniem serwa poprzez guziki, usuń sobie narazie delayie i do pętli while wstaw instrukcje z guzikami.

Jest to metoda bardzo prymitywna, jeżeli w miarę postępów przestanie Ci wystarczać, zacznij ogarniać temat przerwań😉

Link do komentarza
Share on other sites

Rozumiem jak to działa. Ale żebym dokładnie wytłumaczył o co chodzi musiałbym wstukać cały mój program i opisać projekt. Na razie pozostaję przy drugim uC. Przyda mi się do czegoś jeszcze. Ale do tematu wrócę. Może mi się to nie przyda w moim projekcie ale na pewno rozwinie 🙂 Teraz mam inny problem bardziej teoretyczny. Chciałbym zapytać skąd bierze się dzielenie częstotliwości pracy serwa przez 2. Teoretycznie impulsy jakie trzeba podawac na serwo wahają się w granicach od 0,3 ms do 2,7 ms. Ale w trybie PWM timera1 sterującym serwem trzeba je dzielić przez 2. Impulsy podawane powinny być co 20ms a w każdym projekcie z jakim się spotkałem czas ten wynosi 10ms. Mógłby mi ktoś wyjaśnić tę zaleźność? I drugie pytanie: Czy kąt obrotu serwa w zależności od długości podawanego ipulsu to zależność liniowa?

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.