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

Zmiana wypełnienia i częstotliwości sygnału PWM w Attiny13 - jak?

Chivo 27 Lip 2019 11:19 1356 9
REKLAMA
  • #1 18083000
    Chivo
    Poziom 26  
    Witam,

    Na podstawie poniższego kodu steruję trzema diodami led za pomocą programowego PWM w Attiny13. Jak mogę zmieniać parametry sygnału PWM jak wypełnienie i częstotliwość?

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • Pomocny post
    #2 18083886
    excray
    Poziom 41  
    Wypełnienie - zmieniając wartość zmiennych PWM_kolor, a częstotliwość zmieniając wartość OCR0A.
    BTW> Ta linijka na końcu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    jest zbędna
  • #3 18084278
    Chivo
    Poziom 26  
    Kod poprawiłem. Gdy nie używam rejestru OCR0A diody przełączają się kolejno, natomiast, gdy wpiszę do niego coś efekt psuje się.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • Pomocny post
    #4 18085144
    miszczo997
    Poziom 28  
    Ja bym zrobił to w drugą stronę. Tworzysz 3 zmienne globalne jako liczniki (tak jak masz TCNT dla timera). W przerwaniu od timera jedyne co robisz to inkrementujesz te zmienne. W ten sposób częstotliwość zmieniasz poprzez wartość tych zmiennych (do ilu ma liczyć twój programowy timer). A pwm robisz na 3 ifach w pętli głównej (wypełnienie zmienisz poprzez zmianę wartości w tych ifach). W ten sposób nie blokujesz aż tak programu jak w Twoim kodzie. Btw, domyślnie attiny13 jest taktowane zegarem 1,2MHz, a nie 1MHz.
  • REKLAMA
  • #5 18090331
    Chivo
    Poziom 26  
    Zauważyłem, że w pierwszym programie opóźnienie delay_ms() nie liczy się dobrze. Czy lepsze jest _delay_loop_2()?
  • Pomocny post
    #6 18123103
    excray
    Poziom 41  
    Chivo napisał:
    #define F_CPU 1000000

    Jak uzyskałeś częstotliwość 1MHz? ATTINY13 ma wewnętrzny RC=9.6MHz. Po podziale przez 8 daje 1.2MHz. Bez zewnętrznego sygnału albo grzebania w OSCCAL ciężko jest uzyskać 1MHz. Tak na marginesie to częstotliwość powinno się definiować w ustawieniach projektu. Dodatkowo delay w pętli głównej przerywanej przerwaniami nie będzie wiarygodny. Jak chcesz precyzyjnie i powtarzalnie odmierzać czas użyj timera.
  • #7 18123142
    Chivo
    Poziom 26  
    Ustawiłem już kwarc na 1,2 MHz. Poszukam w necie jak się tworzy delay za pomocą timerów.

    Dodano po 4 [godziny] 32 [minuty]:

    Hej. Czy możesz wyjaśnić jak za pomocą timerów w Attiny13 napisać funkcję delay. W programie używam przerwań i te domyśle delay_ms() żle liczy. Pozdrawiam.

    Dodano po 2 [godziny] 57 [minuty]:

    Attiny13 ma tylko jeden licznik. Mogę użyć funkcji asm("nop")?

    Dodano po 56 [minuty]:

    Czy mogę użyć watchdog jako sterowane opóźnienie http://www.bot-thoughts.com/2013/11/avr-watchdog-as-sleep-delay.html?
  • #8 18125688
    excray
    Poziom 41  
    Jaki jest problem?
  • #9 18125744
    Chivo
    Poziom 26  
    Ustawiłem już kwarc na 1,2 MHz. Attiny13 ma tylko jeden licznik, który już wykorzystałem. Jak za pomocą timerów w Attiny13 napisać funkcję delay. W programie używam przerwań i te domyśle delay_ms() źle liczy. Nie mam już wolnych timerów. Mogę użyć funkcji asm("nop")? Czy mogę użyć watchdog jako sterowane opóźnienie http://www.bot-thoughts.com/2013/11/avr-watchdog-as-sleep-delay.html?
  • REKLAMA
  • Pomocny post
    #10 18125901
    excray
    Poziom 41  
    Nie potrzebujesz kolejnego licznika. Już masz jeden skonfigurowany do pracy cyklicznej i to w zasadzie już Ci mniej więcej wystarczy. Masz w tym momencie przerwanie co 1/18750sekundy czyli co jakieś 53,33(3)us. Jeśli chcesz zrobić opóźnienie w pętli głównej o na przykład 500ms to wystarczy, że poczekasz 500000/53,333=9375 takich przerwań. W tym celu zadeklaruj zmienną globalną typu volatile i w każdym przerwaniu zwiększaj ją o 1. Za to w pętli głównej sprawdzaj o ile się zwiększyła i poczekaj aż osiągnie oczekiwaną wartość (przykładowo 9375 przy opóźnieniu 500ms).
REKLAMA