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

[ATtiny 44a][C/WinAVR][RC5] - Błędne dekodowanie ramki, w około 10-15% odczytów

grabie2 13 Lip 2013 13:09 1920 12
  • #1 12516586
    grabie2
    Poziom 11  
    Witam!

    Procesor ziała z wewnętrznym oscylatorem 8MHz.

    Cały mój problem zawarłem w temacie, więc po prostu zaprezentuję kod, ew. wyjaśnienia pod kodem.

    Struktura danych dla RC5:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


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


    Konfiguracja przerwania INT0(Przerwanie dowolnym zboczem):
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Definicje czasów używanie w przerwaniu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    W oryginalnym kodzie(niestety nie pamiętam skąd go wziąłem)procesor działał z zegarem 1MHz i te wartości nie były dzielone.

    Obsługa przerwania INT0:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Na początku obsługi przerwania ustawiam licznik 0 ze względu na to, że normalnie jest on używany do zliczania impulsów z nogi T0.

    Po przedarciu się przez ten kod zapewne nie pamiętasz problemu - W około 10-15% odczytów ramka dekodowana jest błędnie.

    Mam nadzieję, że niczego nie pominąłem. Problem jest o tyle poważny, że będzie to urządzenie produkcyjne i aż taki błąd jest niedopuszczalny.

    Na oscyloskopie sprawdziłem, że przebieg z odbiornika jest wystarczająco czysty, aby być bez problemów dekodowanym przez procesor, tak więc problem jest czysto programowy.

    pozdrawiam i z góry dziękuję za pomoc,
    Bartek
  • #2 12516614
    pawel-jwe
    Poziom 30  
    grabie2 napisał:
    Procesor ziała z wewnętrznym oscylatorem 8MHz.

    I tu może być problem, wewnętrzny RC jest raczej mało dokładny co przekłada się m.in. na dokładność odmierzanych czasów na timer'ach.
    Spróbuj to samo uruchomić na zewnętrznym kwarcu 8MHz (wystarczy zmienić fusebity no i podłączyć kwarc).
  • #3 12516654
    grabie2
    Poziom 11  
    Niestety nie ma takiej opcji, procesor ma wszystkie piny zajęte.
    Błąd przy programowych PWMach jest mniejszy niż 1%, więc sądzę, że to nie jest problemem.

    Niemniej jednak, dziękuję za szybką odpowiedź.
  • Pomocny post
    #4 12519226
    nsvinc
    Poziom 35  
    Wewnętrzny oscylator jest hiperdokładny nawiązując do zawrotnie szybkiego RC5 ;] dsPIC33FJ obłożony ciężko robotą dekoduje mi perfekcyjnie RC5, chodzac z wewnetrznego zegara...

    Dodatkowo, można spróbować wyjaśnić, czym jest to przestępstwo:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    Mam nadzieję, że kompilator jest inteligentny i zoptymalizował tą radosną twórczość...

    U mnie RC5 dekoduje się z wykorzystaniem przerwania zewnetrznego i timera bez problemu, a kod zamyka się w 30 linijkach ;]

    Po co masz tablice bajtow zeby trzymac stany kolejnych bitow, a potem powyższym wybitnie skomplikowanym algorytmem skladasz wartosci z tablicy w...bajt?
    Nie prosciej by bylo
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Te ciągłe odczyty i zapisy do volatile zmiennych to tez jest a lot of fun. Moze warto zastosować lokalne zmienne i na nich operować w kodzie przerwania, a dopiero pod koniec, po przetworzeniu, zapisać jeden raz do pola struktury wartość z zmiennej lokalnej...
  • #5 12519354
    piotrva
    VIP Zasłużony dla elektroda
    No kod jest zdecydowanie przepakowany.
    To może być problemem - musisz zoptymalizować ten kod, gdzie nie trzeba nie używaj struktur, i to jeszcze tak skomplikowanych...
  • #6 12521390
    grabie2
    Poziom 11  
    Te monstra pochodzą z oryginalnego, działającego, rozwiązania, jedyne co zmieniłem to zmienne globalne do struktur przeniosłem, dla porządku.

    Niemniej jednak macie rację jest to przesadzone.

    Jutro będę miał dostęp do kodu i urządzenia to zoptymalizuję, zapewne przepiszę i podzielę się rezultatami.
  • #7 12528987
    grabie2
    Poziom 11  
    Witam ponownie, przepraszam za opóźnienie, nie miałem dostępu do sieci w domu. Serwery(a szczególnie ich dyski!) bardzo lubią nagłe pady energetyki, szczególnie gdy nie mają UPSów.

    Kod od RC5 przerobiłem na coś takiego:

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


    Nie wielka różnica w wyglądzie, ale 400 bajtów mniej.
    Problem jednak dalej występuje.
    Próbowałem z użyciem jednej 16 bitowej zmiennej i przesuwaniem kolejnych bitów. Jednak wyszło to trochę większe(raptem 7 instrukcji, ale jednak...) i problem nie znikł.

    Jeśli ktoś ma jeszcze jakiś pomysł to proszę o jakąś wskazówkę.
    Na pewno problemem nie są inne procesy w mikrokontrolerze, pierwszą zaimplementowaną rzeczą było RC5 i na samym początku tak też pojawiał się ten problem.[/code]
  • #8 12529250
    Konto nie istnieje
    Poziom 1  
  • #9 12529287
    grabie2
    Poziom 11  
    atom1477 napisał:
    Skoro masz taktowanie 8MHz zamiast 1MHz, to dlaczego dzielisz przez 32 a nie przez 8?


    Bo mam prescaler 256.
    256 / 8 = 32
    Czyli timer tyka co 32 us.
  • Pomocny post
    #10 12529890
    Konto nie istnieje
    Poziom 1  
  • #11 12530417
    grabie2
    Poziom 11  
    Hmmm, tego nie próbowałem.

    Próbowałem natomiast zmieniać górne i dolne granice, licząc na to że to w tym tkwi problem.
    Jednak sądzę, że samą obsługę RC5 poprawię jak już będę miał resztę programu gotową, a w między czasie liczę na to, że ktoś podrzuci rozwiązanie problemu.

    Jutro jak dostanę się do urządzenia to na pewno sprawdzę oryginalną procedurę, a przynajmniej ustawienia, bo program oryginalnie był na ATmega8.
  • #12 12543586
    grabie2
    Poziom 11  
    Witam ponownie, przepraszam za opóźnienie. Niestety nie mogłem zająć się urządzeniem przez ostatnie kilka dni.

    Na oryginalnych ustawieniach(timer1[16 bit], 1MHz, bez prescalera) działa bez większych czknięć z większych odległości. Z bliska problemy z transmisją są częstsze, ale dalej w granicy bezczelności.

    Niestety timer1 jest używany do innych rzeczy i nie mogę go zaprząc do RC5.

    Obecnie moja procedura obsługi przerwania wygląda następująco:

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

    Próbowałem z czasami jednak nie wiele to zmienia.

    Może mógłby ktoś prześledzić logikę działania tego kodu, ja nie dostrzegłem błędu, ale może ktoś inny na coś wpadnie.

    Jeśli ktoś ma pod ręką/zna inną metodę obsługi rc5, wykorzystującą podobne zasoby sprzętowe(licznik 8 bitowy, przerwanie INT) i nieabsorbującą pętli głównej to również proszę o podesłanie.
  • #13 12548065
    grabie2
    Poziom 11  
    Witam!

    Problem rozwiązałem poprzez zmianę procedury obsługi rc5 na inną, używaną w jednym z firmowych projektów. Niestety skończył się czas i mimo iż ta nowa jest znacznie większa to musi być dobra ;)

    Dziękuję wszystkim za pomoc i zaangażowanie.
    Pozdrawiam,
    Bartek
REKLAMA