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.

[Atmega8][AVR-gcc] - Dekoder 2 sygnałów ppm

skyguy 12 Lut 2013 21:35 2727 8
  • #1 12 Lut 2013 21:35
    skyguy
    Poziom 14  

    Koledzy mam małą zagwostkę. Potrzebuje rozkodować 2 sygnały ppm - sygnały pochodzące z odbiornika RC do serwa.
    Sygnał ma taka postać:


    Poniżej zrzuty z oscyloskopu:

    Długość impulsu 1.2ms serwo wychylone na maxa w lewo
    [Atmega8][AVR-gcc] - Dekoder 2 sygnałów ppm

    Długość impulsu 1.9ms serwo wychylone na maxa w prawo
    [Atmega8][AVR-gcc] - Dekoder 2 sygnałów ppm

    Napisałem program który działa, ale dla jednego sygnału, pokrótce:
    -zbocze narastające na INT0 Timer1 ON
    -zbocze opadające na INT0 Timer1 OFF
    -przepisanie z rejestru TCNT1
    -zerowanie licznika

    1) I teraz mam pytanie jak podejść do 2 kanałów, moja teza jest taka:

    -Timer1 ON (cały czas)
    -zbocze narastające na INT0 lub INT1 przepisanie rejestru do zmiennej trzymającej początek sygnału dla danego kanału
    -zbocze opadające na INT0 lub INT1 przepisanie rejestru do zmiennej trzymającej koniec sygnału dla danego kanału
    -1 sygnał S = koniec sygnału1 - początek1
    -2 sygnał S = koniec sygnału2 - początek2

    Mam również przerwanie z przepełnienia licznika, które ustawia zmienną wskazująca na to iż licznik się wyzerował i odpowiednio algorytm na sygnały się zmienia:

    - 1 sygnał S =koniec sygnału1+(65535-początek sygnału1)
    - 2 sygnał S =koniec sygnału2+(65535-początek sygnału2)

    65535 - bo licznik T1 przepełnia się cały 0xFFFF

    2) czy to jest dobre rozumowanie?
    Im bardziej zagłębiam się w datasheet tym więcej mam wątpliwości
    3) czy przerwanie od INT0 i INT1 zdąży przepisać aktualną wartość licznika TCNT1?
    4) jaki w pływ mają na to inne przerwania? Mam przerwanie od USART (jeśli przyjdzie znak...) dla opcji z jednym sygnałem to nie przeszkadzało
    5) czytałem tez o opcji CAPTURE dla Timera1, ale wówczas możemy przechwytywać jeden sygnał wpadający na ICP tak?

    Według Waszego doświadczenia w jaki sposób do tego należy podejść? Do wykorzystania pozostał licznik T1. kodu na razie nie zamieszczam mam skończony w połowie a wolał bym rozwiać wątpliwości niż wypisywać herezję :)

    0 8
  • Pomocny post
    #2 12 Lut 2013 21:55
    BlueDraco
    Specjalista - Mikrokontrolery

    Timer 16-bitowy chodzący w kółko, linie INT0 i INT1 zaprogramowane na przerwania od obu zboczy, obsługa przerwań odczytuje wartość timera i wykonuje stosowne obliczenia. Jeśli procedury obsługi innych przerwań będą poprawnie napisane, nie ma powodu, żeby to nie zadziałało. Powinieneś uzyskać rozdzielczość i dokładność na poziomie kilku mikrosekund.

    0
  • #3 13 Lut 2013 13:39
    skyguy
    Poziom 14  

    Dobra pierwsze podejście do kodu:

    Atmega8 ustawiona fusami na 8Mhz

    Najpierw dobór preskalera. Jak już wcześniej pisałem pomiar jest od 1,2-1,9ms więc zliczanie czasu moim zdaniem powinno być mniejsze od 0,05ms.

    Dobrałem preskaler 64 po czasie 524.288ms następuje przepełnienie T1 dla 0xFFFF, a więc jeden takt zliczania ma 524.288/65535 czyli 0,008ms w przybliżeniu 0,01ms co przy dokładności zupełności wystarczy. Długość impulsu ma min 1.2ms a więc też nie ma możliwości żeby licznik w tym czasie przepełnił się 2 razy.

    Na razie nie wprowadzałem przeliczania na konkretne ms, chcę uzyskać jakieś zmienne wyniki dla różnych stanów.

    Proszę o sugestie do programu i deklaracji zmiennych niestety nie działa tak jak bym chciał:

    Program, nie zawiera USART:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Jakie objawy OK:
    Jak jest niski stan to wartości są następujące:
    i= stała
    i1=stała
    i2=stała

    Jak jest wysoki stan to wartości są następujące:
    i= stała
    i1=stała
    i2=stała

    Objawy złe:
    i= co dziwne zawsze ta sama i oscyluje w okolicach wartości 2870 +/-3
    i1=wartości różne np. 19716
    i2=wartości rózne np. 22586

    0
  • Pomocny post
    #4 13 Lut 2013 13:44
    BlueDraco
    Specjalista - Mikrokontrolery

    Daruj sobie obsługę przepełnień i przerwanie od przepełnienia timer - kompletnie nic one nie wnosi. Po prostu zapisz wartość timera przy zboczu narastającym, a przy zboczu opadającym odejmij od bieżącej wartości tę zapamiętaną - przewinięcie typu uint16_t przez zakres samo załatwi sprawę.
    Skąd wiesz, jakie masz wartości, skoro nic z nimi nie robisz?

    0
  • #5 13 Lut 2013 15:07
    Dawid WAT
    Poziom 14  

    Witam
    czy na pewno tak można ustawić zero w rejestrze??

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    można by tak spróbować:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    sprawdź czy na pewno procesor potrafi rozpoznać czy był zbocze opadające czy narastające.

    Pozdrawiam Dawid

    0
  • #6 13 Lut 2013 15:22
    BlueDraco
    Specjalista - Mikrokontrolery

    Ja bym raczej proponował pozbyć się lęku przed wpisywaniem wartości do rejestrów i napisać po prostu:

    MCUCR = 0b0101;

    lub, jak kto woli
    MCUCR = 1 << ISC10 | 1 << ISC00;

    Przynajmniej wiadomo, o co chodzi.

    0
  • #7 13 Lut 2013 15:55
    skyguy
    Poziom 14  

    Wartości wysyłam po USARCIE na terminal, same operacje wypisywania po USARCIE działają poprawnie, tak jak wspominałem dla jednego kanału działało znakomicie w innym rozwiązaniu.

    Zminimalizowałem kod i ograniczyłem się do jednego kanału, przerwanie od przepełnienia również w całości wywaliłem.

    Pomogło również wpisanie:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    inaczej nie chciało pujść teraz 2 kanał in progress....



    Zmieniony kod:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #8 13 Lut 2013 21:25
    nproton
    Poziom 11  

    Widzę że nie do końca rozumiesz sygnał PPM. Interesuje cię tylko zbocze narastające, czas trwania impulsu jest taki sam, tylko odległość pomiędzy nimi się zmienia, może ten rysunek tobie to wyjaśni:
    [Atmega8][AVR-gcc] - Dekoder 2 sygnałów ppm

    0
  • #9 13 Lut 2013 22:02
    skyguy
    Poziom 14  

    nproton
    Rozumiem dobrze. Ja chcę zdekodować 2 kanały z ppm które dochodzą już do serw a nie cały sygnał ppm. Jak zobaczysz ze swojego wykresu zmienia się ich czas trwania.
    Program już działa bardzo dobrze, jutro go wstawię dla potomnych.

    Mam jeszcze zagwostki:
    1) Czy da się jakoś zmuxowac/powielić przerwania od wejść zewnętrznych? Jak bym chciał nie 2 ale 4 wejścia podłączyć?

    0