logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Atmega8 - Jak ustawić PWM dla serwa Tower Pro SG-5010?

Demooon 21 Lut 2014 12:29 1944 11
  • #1 13328530
    Demooon
    Poziom 9  
    Witam serdecznie.
    Mam pewien problem ze zrozumieniem sterowania serwonapędów.
    Próbuję zaprogramować ruch serwa ( Tower Pro SG-5010) przez sprzętowe PWM.

    Żyła sygnałowa serwa podpięta do PB1/OC1A , zasilanie 5V, masa wspólna z mikrokontrolerem.

    Częstotliwość taktowania to 8MHz. Oto mój kod:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Ustawiam tryb 14 timera1 i prescaler 256 co daje 8MHz/256 = 31250
    Ustawiając ICR1 na 625 uzyskuję częstotliwość 50Hz czyli właściwy okres sterowania serwem 20ms.

    Moje pytanie brzmi, jak wysterować zmienny stan wysoki przez 1-2ms w tym okresie? Jeśli są błędy w moim rozumowaniu bardzo proszę o poprawkę.
  • #2 13328555
    olelek
    Poziom 24  
    Witam. Przedstawiam kod w którym masz wszystko wyjaśnione:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    I teraz ustawienie serwa.
    Lewo:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Środek:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Prawo:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Wszystko dla taktowania 8MHz.
  • #3 13329507
    el2010tmp
    Poziom 25  
    Gdzie masz pętle np.: while(1);
    Bez niej program zakończy działanie, PWM również.
  • #4 13329546
    olelek
    Poziom 24  
    Słuszna uwaga Kolegi powyżej, należy pamiętać o takiej budowie programu, aby się nigdy nie zakończył, ew. przeszedł w tryb POWER DOWN. Ale program nadal się wykona, ponieważ kompilator na samym końcu dopisze nieskończoną pętlę w sekcji .fini0.
  • #5 13329630
    piotrva
    VIP Zasłużony dla elektroda
    olelek napisał:
    Ale program nadal się wykona, ponieważ kompilator na samym końcu dopisze nieskończoną pętlę w sekcji .fini0.

    Niestety nie - wczoraj przez głupi błąd zakomentowałem tę pętlę na końcu main'a i niestety wysyłanie znaków przez UART oparte na przerwaniach zatrzymywało się ;)
  • #6 13329699
    Demooon
    Poziom 9  
    Faktycznie brakło while.
    A jak wygląda sprawa timera i częstotliwości ? I jak OCR1 ma się do wypełnienia tego impulsu?
    Wybaczcie laickie pytania i proszę o odpowiedź
  • #8 13329801
    Demooon
    Poziom 9  
    Tyle wiem.
    Czy wartość ICR została ustawiona prawidłowo?
    Nie rozumiem w jaki sposób ustala się to wypełnienie.
    Jak wyliczyć jaka wartość OCR to np 1,7ms stanu wysokiego i tak dalej.
  • #9 13329861
    olelek
    Poziom 24  
    Proszę zapoznać się z komentarzami w kodzie oraz Datasheet Atmega8. Przebieg generowany ma częstotliwość f = F_CPU/Prescaler/ICR1. Wypełnienie jest równe stosunkowi OCR1/ICR1. Także można niezależnie zmieniać częstotliwość wyjściową przebiegu i jego wypełnienie. Program, który podałem ma wartości dostosowane do obsługi serw i działa w praktyce.
  • #10 13330166
    Demooon
    Poziom 9  
    Sterowanie poprzez nadawanie stałych wartości działa, dziękuje za pomoc.
    Jednak podczas próby sterowania switchami napotkałem pewien problem, serwo po zaprogramowaniu procka, obraca się raz w lewo raz w prawo aż do zatrzymania, potem można chwilę posterować i znów następuje kilka ruchów w obydwie strony aż do zatrzymania.
    Oto kod:



    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #11 13332187
    polarczn
    Poziom 16  
    Mam pytanie, nie chcę zakładać nowego tematu, gdyż temat jest podobny. Steruje mruganiem diod za pomocą Timer1 w pętli while. Dalej w kodzie mam odczyt ADC. Program robi tylko to co jest w tej pętli, nie mam odczytu z ADC. Jak to naprawić?
REKLAMA