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

Attiny13 - Fast PWM - AVR C - konfiguracja i inwersja PWM dla LED

yogi009 05 Kwi 2017 23:00 1857 6
  • #1 16394704
    yogi009
    Poziom 43  
    Witam,

    po raz kolejny usiadłem do nauki podstaw programowania małych mikrokontrolerów AVR, na potrzeby sterowania trybami projektowanej latarki LED użyłem sprzętowego trybu Fast PWM. F CPU 1000000, na razie wskaźnikiem jest dioda LED podłączona katodą do PIN1, anodą do +5V. Pin jest ustawiony jako wyjście. Jeśli chodzi o sam Fast PWM, użyłem takich ustawień:

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


    No i to działa, tylko na odwrót (OCR0B = 255 oznacza całkowicie wygaszony LED). W zasadzie jest to poprawne działanie przy takim podłączeniu diody. Teraz pytania:

    1. w nocie katalogowej Attiny13 tryb PWM ustawia się rejestrami COM00 i COM01, tutaj mam tylko COM0B1 - to zapis zapożyczony z jakiegoś anglojęzycznego bloga,

    2. jak ustawić to samo w trybie inwersji, żeby 0 oznaczało wygaszoną diodę LED, a 255 pełne światło.
  • Pomocny post
    #2 16394850
    Konto nie istnieje
    Konto nie istnieje  
  • Pomocny post
    #3 16394924
    dondu
    Moderator na urlopie...
    yogi009 napisał:
    No i to działa, tylko na odwrót (OCR0B = 255 oznacza całkowicie wygaszony LED). W zasadzie jest to poprawne działanie przy takim podłączeniu diody.

    To jest poprawne, czy nie jest - zdecyduj się :)

    Odpowiadam: Nie jest poprawne.


    yogi009 napisał:
    1. w nocie katalogowej Attiny13 tryb PWM ustawia się rejestrami COM00 i COM01, tutaj mam tylko COM0B1 - to zapis zapożyczony z jakiegoś anglojęzycznego bloga, ...

    W dokumentacji w niektórych tabelkach jest błąd w oznaczeniach bitów. Prawidłowe to COM0A1 i COM0A0.

    Znaczenie ich jest opisane w tabelce "Table 11-6. Compare Output Mode, Fast PWM Mode".

    Według dokumentacji masz prawidłowo ustawiony timer pomijając fakt, że nie pokazałeś, czy ustawiasz pin OC0B (PB1) na wyjście. Jeśli tak robisz, to wytłumaczeniem, że dioda nie świeci przy wypełnieniu 255 mogą być jedynie:

    1. fakt iż w programie przez przypadek ustawiasz także bit COM0B0,
    2. lub podłączyłeś diodę anodą do pinu i katodą do GND.

    Oprócz sprawdzenia powyższego i rozwiązaania w ten sposób problemu, możesz pójść na skróty i włączyć "inverting mode":

    Cytat:
    11.7.3 Fast PWM Mode
    ...
    The counter counts from BOTTOM to TOP then restarts from BOTTOM.
    TOP is defined as 0xFF when WGM2:0 = 3, and OCR0A when WGM2:0 = 7. In noninverting
    Compare Output mode, the Output Compare (OC0x) is cleared on the Compare Match
    between TCNT0 and OCR0x, and set at BOTTOM. In inverting Compare Output mode, the output
    is set on Compare Match and cleared at BOTTOM.

    czyli dodatkowo ustawić bit COM0B0, co znajdziesz także w wyżej wymienionej tabelce.

    Sugeruję jednak znalezienie błędu, a nie robienie protezy.

    PS.
    Mam nadzieję, że rezystor diody podłączyłeś, bo nie wynika to z Twojego opisu.
  • #5 16396711
    yogi009
    Poziom 43  
    Piotrus_999 napisał:
    Nawet bez patrzenia w DS wystarczy od 255 odjąć Twoja wartość i masz odwrotnie


    Proste i genialne. Wielkie dzięki.

    dondu napisał:
    To jest poprawne, czy nie jest - zdecyduj się


    Dioda LED została podłączona katodą do PIN1, anoda przez rezystor do plusa zasilania. Na samym pin'ie jest poprawnie, czyli np. wartość 255 oznacza pełne wypełnienie fali prostokątnej. Czyli 255 oznacza stałą "jedynkę" na pin'ie. A ponieważ LED do zaświecenia potrzebuje zera, to nie świeci. Dlatego napisałem, że PWM działa poprawnie (patrząc na wyjście pin'u), ale z tak podłączoną diodą LED potrzebuję inwersji. Wiem, że jest taki tryb, jednak słabo jeszcze czytam te noty kontrolerów. Kolega Piotrus_999 podpowiedział proste i znakomite rozwiązanie.

    Jeszcze jedno, korzystam z PB1, czyli powienien ustawiać OCR0B, a nie OCR0A. O błędach w tabelach noty katalogowej nie słyszałem, to jest niepojęte, że takie błędy są, społeczność o nich wie (i zapewne zgłasza producentowi), a w internecie dalej są te wprowadzające w błąd informacje.

    Obecnie kod pracuje już tak, jak zakładałem, jednak chciałbym w miarę możliwości jak najdokładniej rozwikłać przy okazji te nowe dla mnie zagadki.

    miszczo997 napisał:
    drobna uwaga - oscylator RC w attiny13 pracuje na 9,6MHz, czyli przy zaznaczonym CKDIV masz 1,2MHz.


    Tak, wiem, dlatego ustawiłem go celowo na 1MHz. Chodzi głównie o jak najoszczędniejsze zarządzanie energią (zasilanie z ogniwa Li-Ion). Przede mną jeszcze tryby usypiania/wybudzania i kilka innych detali. Chętnie poznam jakieś ciekawe (optymalnie z polskim komentarzem) i działające przykłady takich rozwiązań. Innym tematem, który jest przede mną to reagowanie na zdecydowanie dłuższe przyciśnięcie przycisku mikroswitch. Czyli włączanie/wyłączanie urządzenia (zapewne raczej po prostu głębsze usypianie).
  • Pomocny post
    #6 16396816
    miszczo997
    Poziom 28  
    Niestety to tak nie działa. Jeżeli nie podłączyłeś zewnętrznego sygnału zegarowego do wejścia CLK o częstotliwości 1MHz i nie ustawiłeś odpowiedni fusebitów na zewnętrzny generator zegarowy to samo zdefiniowanie w programie F_CPU nie spowoduje, że procesor będzie pracował z taką częstotliwością. W Attiny13 masz możliwość ustawienia 3 częstotliwości wewnętrznego taktowania i dodatkowego podziału każdej z nich przez 8. Czyli 9,6MHz->1,2MHz, 4,8MHz->0,6MHz, 128KHz->16KHz. Tyle na poziomie fusebitów. Dodatkowo fajną opcją jest możliwość zmiany taktowania bezpośrednio w kodzie programu, gdzie dostępna jest możliwość ustawienia innego dzielnika sygnału zegarowego. Tutaj szczegóły http://mikrokontrolery.blogspot.com/2011/03/K...-Programowa-zmiana-czestotliwosci-zegara.html
REKLAMA