Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[C][AtMega32] - Serwo nie działa, gdzie w programie jest błąd ?

Albert91 21 Cze 2013 18:18 1425 4
  • #1 21 Cze 2013 18:18
    Albert91
    Poziom 7  

    Męczę sie już z tym 3 dni i nie mogę wyłapać błędu , jak na AtMedze8 podobnie pisałem to wszystko działało elegancko , a na 32ce serwo nie chce się ruszyć.
    16 MHz

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0 4
  • #2 21 Cze 2013 21:39
    Jeżyk-1
    Poziom 25  

    Fuse bity w mikroprocesorze przestawiłeś na 16MHz w atmega32?

    I zastanawia mnie funkcja:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Która nie jest nigdzie zdefiniowana. Nie wiem czy zapomniałeś jej tu wkleić czy co ale tak kompilowany program zgłasza tu error.

    0
  • #3 21 Cze 2013 22:17
    Albert91
    Poziom 7  

    init(); służyło do obsługi wyświetlacza LCD , wyciąłem tę cześć programu żeby nie zaśmiecać, nie zauważyłem, że zostało.


    Na fuse nie patrzyłem, ale próbowałem też wgrać mu taki program jak dla 1 Mhz i też nie działał.

    Chyba z 32 się poddam , bo na AtMega8 wszystko ładnie śmiga

    0
  • #4 21 Cze 2013 22:43
    Jeżyk-1
    Poziom 25  

    A prawidłowo wszystko podłączyłeś do układu ?


    Nie wiem czy ta konfiguracja portów coś nie miesza. Najlepiej jak byś zostawił tylko konfiguracje portu którą wykorzystujesz:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    A resztę czyli to:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Usunął ze względu że jest to mało czytelny sposób definicji portów.

    0
  • #5 22 Cze 2013 14:36
    Brutus_gsm
    Poziom 25  

    Stałej F_CPU nie definiuje się w kodzie. Robi się to w ustawieniach kompilatora, szczególnie, że korzystasz z opóźnień za pomocą funkcji _delay_ms().
    http://mikrokontrolery.blogspot.com/2011/03/fcpu-gcc-gdzie-definiowac.html

    Dodatkowo, jeśli chcesz, żeby procesor taktowany był zegarem 16MHz, to taki kwarc zewnętrzny musisz podłączyć oraz ustawić odpowiednie fusebity. Od tego zacznij, bo serwa wymagają do sterowania 50Hz, a taktowanie 1MHz (tak są fabrycznie skonfigurowane atmegi) na to nie pozwoli (przy tym kodzie czywiście).

    Nie konfiguruj portów "na pałę". Zastanów się co ma być wejściem, a co wyjściem i skonfiguruj tylko te piny, których używasz. Oszczędzi ci to wielu problemów. Używasz wejść INT0 i INT1 oraz wyjść OC1A i OC1B, dlatego też wystarczy kod:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Oczywiście możesz korzystać z makra _BV, jeśli jest to dla ciebie wygodniejsze lub czytelniejsze.

    Tak samo musisz zrobić ze wszystkimi innymi wykorzystywanymi pinami. Jeśli korzystasz z wyświetlacza, to konfigurujesz tylko te piny, z których korzystasz.

    Jeśli chodzi o konfigurację Fast PWM, to wygląda ona na poprawną, powinna działać.

    Przerwania powinny wykonywać się najszybciej jak to możliwe. Każdorazowe obliczanie liczb zmiennoprzecinkowych szybkie nie jest. Nie wiem, czy kompilator jest na tyle sprytny, że zamieni sobie mnożenie przez 0.125, dzieleniem przez 8, albo przesunięciem bitowym. Obliczenia zmiennoprzecinkowe są dla AVR dość obciążające. Zdecydowanie lepiej byłoby wykorzystać np. dwie zmienne (lub stałe) 16-bitowe, które obliczane byłyby albo raz w programie głównym, albo bezpośrednio przez kompilator. Skoro wykorzystujesz częstotliwość 50Hz i nie będziesz jej zmieniał, a wartość 40000 wpisujesz do ICR1 na sztywno i na stałe, to możesz wykorzystać takie coś:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Dzięki czemu możesz znacząco skrócić czas wykonywania przerwania (co jest bardzo wskazane):
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Korzystasz także ze starej makrodefinicji SIGNAL() oraz starych nazw wektorów przerwań. Nie powinno się ich stosować, gdyż w przyszłości mogą zostać usunięte. Należy korzystać z makrodefinicji ISR().
    http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

    Chociaż tutaj nie jestem pewien, czy kompilator nie zauważy czasem faktu, że wartość ICR1 nigdzie nie jest zmieniana i zamiast obliczeń zmiennoprzecinkowych, zamieni to na stałą. Dzięki wykorzystaniu własnych stałych, masz już taką pewność.

    Edit:
    Kod wykorzystujący obliczenia zmiennoprzecinkowe po kompilacji zajmuje 4774 bajtów. Modyfikacja z wykorzystaniem stały minPWM i maxPWM tyle 728! Czasu wykonywania nie sprawdzałem w symulatorze, ale zapewniam, że będzie znacząco krótszy.

    0
  Szukaj w 5mln produktów