Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

ATTiny13 - Portowanie odbioru RC5 z Mega8

afterparty 18 Sep 2013 09:39 3675 16
Computer Controls
  • #1
    afterparty
    Level 12  
    Cześć, chciałem przeportować kod do odbioru RC5 autorstwa Dondu za ATMega8 na ATTiny13 - Link. Zauważyłem, że rejestry mają nieco inne nazwy, i dokonałem drobnych modyfikacji:

    main.c:
    Code: c
    Log in, to see the code


    dd_rc5.h:
    Code: c
    Log in, to see the code


    dd_rc5.c:
    Code: c
    Log in, to see the code


    Jak widać nie zmieniłem nic oprócz tych nazw rejestrów, i definicji pinów LED'ów.

    Hardware:
    No tu raczej nie ma się jak pomylić, bo układ jest naprawdę prosty. Odbiornik podczerwieni to TSOP4836. Zasilanie filtrowane, stabilizowane, odbiornik zgodnie z Datasheetem.
    ATTiny13 - Portowanie odbioru RC5 z Mega8
    REzystory diod 470Ω, nie zmieniłem na schemacie.
    Pilot samoróbka, ale 100% pewniak.

    No więc w czym problem? Uruchomiłem przykład na ATMega8, wszystko pięknie śmiga. Program kompiluje się dla Tiny13 bez błędów i ostrzeżeń. Jednak program nie działa - po wciśnięciu przycisku na pilocie widać jak dioda przerwania zaświeca się na moment i gaśnie. Ale diody danych i toggle bita nawet nie migną.

    Co może być nie tak?
    No ja niestety nie mam pojęcia.
    Moja teoria: brakuje pamięci RAM w Tiny13?
  • Computer Controls
  • #2
    BlueDraco
    MCUs specialist
    Sprawdź, co wypisuje konsolidator - jest tam podawana zajętość ROM i RAM.
  • #3
    KrisH
    Level 14  
    Z jakim zegarem pracuje to Tiny? W oryginalnym projekcie ATmega pracuje z wewnętrznym oscylatorem 1MHz.
  • Computer Controls
  • #4
    dondu
    Moderator on vacation ...
    Jak masz ustawiony zegar? Skoro łapie przerwania, a nie dekoduje to tutaj szukałbym przyczyny. Na razie nie analizowałem Twoich zmian.

    Sprawdzałeś co sugerował BlueDraco?

    EDIT:
    KrisH był szybszy :)
    Gdy znajdziesz przyczynę, opisz ją dokładnie, to ewentualnie zamieszczę info w artykule.
  • #5
    afterparty
    Level 12  
    Teraz wiem, że to nie pamięć:
    Device: attiny13
    
    Program:     654 bytes (63.9% Full)
    (.text + .data + .bootloader)
    
    Data:          7 bytes (10.9% Full)
    (.data + .bss + .noinit)
    
    
    Finished building: sizedummy
     
    
    **** Build Finished ****
    


    Z jakim zegarem? 4.8MHz oscylator wewnętrzny.
    Czasy powinny być w porządku, w dd_rc5.h widzimy makra które nam wszystko obliczają:
    Code: c
    Log in, to see the code


    (Chyba, że ja coś źle rozumiem?)
  • #6
    BlueDraco
    MCUs specialist
    Wzory na czasy w kodzie nie działają, jeśli częstotliwość nie jest wielokrotnością 1 MHz - wtedy na dzień dobry masz błąd, w Twoim przypadku ok 20%.

    Zamień na:
    (po poprawce - błąd wypunktowany poniżej przez Dondu)

    (F_CPU * (1778 - DD_RC5_TOLERANCJA_US) / (DD_RC5_TIMER_PRESKALER * 1000000)

    Tylko, że to z kolei nie zadziała z powodu przekroczenia zakresu.

    Trzeba to rozbić tak, żeby opóźnić dzielenie, np:
    (F_CPU / 100 * (1778 - DD_RC5_TOLERANCJA_US) / DD_RC5_TIMER_PRESKALER / 10000)
  • #7
    dondu
    Moderator on vacation ...
    Oj, coś za bardzo się pospieszyłeś :)

    BlueDraco wrote:
    Wzory na czasy w kodzie są bzdurne.

    Nie są bzdurne tylko co najwyżej nie przystosowane do wartości F_CPU nie będących jak słusznie zauważyłeś:

    BlueDraco wrote:
    Jeśli częstotliwość nie jest wielokrotnością 1 MHz, to na dzień dobry masz błąd, ...

    Niestety zaproponowany przez Ciebie wzór:

    BlueDraco wrote:
    Zamień na:
    (F_CPU * (1778 - DD_RC5_TOLERANCJA_US) / (DD_RC5_TIMER_PRESKALER * F_CPU))

    jest tym co piszesz w pierwszym zdaniu ponieważ:

    ATTiny13 - Portowanie odbioru RC5 z Mega8

    ... czyli niezależnie od F_CPU zawsze będzie dawał taki sam wynik :)

    @afterparty
    W tej chwili nie ma czasu na to, by dostosować wzorów i sprawdzić ich działanie.
    Postaram się to zrobić w ciągu 24h.
  • #8
    BlueDraco
    MCUs specialist
    Oczywiście miało być:
    (F_CPU * (1778 - DD_RC5_TOLERANCJA_US) / (DD_RC5_TIMER_PRESKALER * 1000000))

    Ale to i tak źle - poprawiłem powyżej.

    Rozpędziłem się i palnąłem głupotę.
  • #9
    afterparty
    Level 12  
    Zmieniłem na:
    Code: c
    Log in, to see the code

    Niestety dalej nie działa.
  • #11
    afterparty
    Level 12  
    Jakieś pomysły? Kupiłem dziś Tiny2313, i próbowałem kod uruchomić na nim, ale dzieje się dokładnie to samo co z Tiny13. Zegar mam 4MHz.

    EDYCJA:
    Kodzik działa już na ATTiny2313 (fuse bity :roll:)
    Ale jak ktoś rozwiąże zagadkę z ATTiny13, to niech napisze, narazie nie zamykam.
  • #12
    KrisH
    Level 14  
    Atiny2313 ma oscylator 4 lub 8 MHz a Atiny13 4,8 lub 9,6MHz.
    Jest jeszcze dodatkowo "fus" CKDIV8 o którym trzeba pamiętać bo fabrycznie jest zaprogramowany.
    Czy za każdą zmianą procesora dokładnie przeliczasz czasy?
    Czasami warto ujednolicić środowisko pracy tj:
    może spróbujesz podać taki sam zewnętrzny zegar ( najlepiej 1MHz) na oba procesory i wtedy tylko osobno kompilować i ładować program dla każdego procesora ale już z tymi samymi danymi.
  • #13
    dondu
    Moderator on vacation ...
    Sorry, że z opóźnieniem - sprawdziłem w czym był problem z częstotliwościami ułamkowymi w MHz, czyli np. 4,8MHz jak w Twoim przypadku.

    Najbardziej poprawny wzór zaproponowany przez BlueDraco nie liczy prawidłowo, gdy kompilator działa w systemie 32-bitowym z powodu przekroczenia zakresu dla liczb tylu Long. Aby się pozbyć tego problemu można przekształcić wzór tak, by nie dopuścić do przekroczenia zakresu.

    Można to zrobić na kilka sposobów, na przykład modyfikując oryginalny wzór z biblioteki w ten sposób:

    Code: c
    Log in, to see the code

    Taka wersja w stosunku do oryginalnej z biblioteki liczy poprawnie, nie tylko częstotliwości "okrągłe", ale także ułamkowe z którymi miałeś problem. Sprawdziłem to na kwarcach 7.372.800Hz oraz 4.433.619Hz.

    Zaraz dokonam podmiany w oryginałach na blogu.
  • #14
    afterparty
    Level 12  
    Dondu - sprawdziłem przed chwilą kod na dwóch ATTiny13. Niestety dalej dzieje się to samo - brakuje toggle bita, oraz bitów danych :(
  • #15
    dondu
    Moderator on vacation ...
    Nie mam akurat żadnego Tiny by sprawdzić :(
    Na pewno aktualne wzory przeliczają prawidłowo (sprawdzone także CManiakiem) i działają na ATmega8 na kwarcach ułamkowych, które wyżej podałem. Na tych "okrągłych" do 16MHz także oczywiście działają. Przy najbliższych zakupach kupię ATTiny13 i sprawdzę.

    Pokaż proszę aktualną wersję programu + wszystkie pliki bibliotek i opisz dokłądnie efekt. Rozumiem, że komunikaty kompilacji są OK?
  • #16
    afterparty
    Level 12  
    Cześć, ostatnio nie miałem czasu, także przepraszam za brak odpowiedzi.

    Program jest taki sam jak w pierwszym poście, tylko podmieniłem wzory na czas:
    RC5_main.c
    Code: c
    Log in, to see the code


    dd_rc5.c:

    Code: c
    Log in, to see the code


    dd_rc5.h:

    Code: c
    Log in, to see the code


    A objawy są dokładnie takie same jak przy wersji ze starymi wzorami na czas.
    Po naciśnięciu przycisku na pilocie widać jak dioda LED przerwania zaświeca się na krótki czas, po czym gaśnie, a diody danych oraz toggle bit'a w ogóle się nie zaświecają. Nie wiem co mogę jeszcze napisać. Fuse bity w porządku, częstotliwość ustawiona w opcjach projektu, zasilanie filtrowane itp. Kompilacja przechodzi bez błędów, żadych ostrzeżeń też nie ma.

    Da się jakoś sprawdzić maksymalne użycie stosu?
  • #17
    olelek
    Level 24  
    Witam,

    Dzisiaj zmierzyłem się z tym samym problemem, choć kod na ATTINY13 przerabiałem samodzielnie. Taktowanie wewn. 9,6MHz. Oprócz użycia zaktualizowanych wzorów na obliczanie czasów bitów i pół-bitów trzeba było zwiększyć tolerancję:
    #define DD_RC5_TOLERANCJA_US 350


    Po tej zmianie zaczęło działać poprawnie. Jak widać więc attiny13 ma "pecha" do tych częstotliwości. Nie testowałem przy zmianach temperatur. Jeśli będzie taka potrzeba mogę udostępnić cały kod, w którym dodałem:
    -obsługę włącz/wyłącz jednym przyciskiem korzystając z bitu toogle;
    -programową zmianę taktowania procesora (ale tylko na start ;))
    -przechodzenie procesora w tryb POWERDOWN w oczekiwaniu na nowe komendy pilota.

    Edit:
    Przy okazji dodam, że poszedłem za ciosem i przeportowałem program dla Attiny10. Sprawa wygląda jeszcze ciekawiej, ponieważ mamy na pokładzie 16bit timer, a nie 8bit. Dla 8MHz zadowalające rezultaty osiągnąłem dla tolerancji na poziomie 350ms i prescalerze 8 (możemy skorzystać z dobrodziejstwa 16 bitów i liczyć czas z większą rozdzielczością).