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

Jakość dzwięku uzyskana na PWM

maly_elektronik 19 Sie 2011 09:08 2655 15
REKLAMA
  • #1 9839689
    maly_elektronik
    Poziom 23  
    Witam,
    czy któryś z szanownych kolegów wie może w jaki sposób poprawić jakość muzyki (PCM,RAW) generowanej przy pomocy PWM'a :?:

    Bo oglądają filmik znanego elm-chan'a (m.in z FatFs) stwierdzam iż jakość jest idealna do różnych zastosowań.
  • REKLAMA
  • #2 9839722
    elektryk101
    Warunkowo odblokowany
    Mało informacji podałeś. Program by się przydał.
  • REKLAMA
  • #3 9839774
    maly_elektronik
    Poziom 23  
    Odtwarzam próbki z próbkowaniem 44100Hz (próbowałem także 8KHz ale nie usłyszałem różnicy w jakości), unsigned 8bit, mono :)
    Plik odczytywany z karty SD (WAV wg powyższego opisu).

    PWM w AVR pracuje na max częstotliwości (ok. 8MHz, Kwarc m16 to 16MHz).
    PWM z TIMER2 8bitowy.

    Do PWM'a podpięty wzmacniacz (z głośników do komputera)

    Potrzebne są jeszcze jakieś informacje :?:
  • Pomocny post
    #5 9840118
    tmf
    VIP Zasłużony dla elektroda
    No i sposób "karmienia" timera kolejnymi próbkami. Tu szczególnie istotne są stałe i dokładne odstępy pomiędzy kolejnymi zmianami wypełnienia.
  • REKLAMA
  • #6 9840173
    maly_elektronik
    Poziom 23  
    Schemat...
    Do wyjścia PWM'a (OC2) podpięty jest filtr dolnoprzepustowy(R=470, C=22n) a za filtrem wzmacniacz na układzie TDA2822 (jak wspomniałem wcześniej wzmacniacz głośnikowy do komputera).

    Próbki podawane są jak sądzę w równych odstępach czasu, poprzez _delay_us. A zczytywane są bezpośrednio z karty (dokładniej z bufora w porcjach po 512B).

    Czy podawanie próbek przez Timer będzie dokładniejsze :?:
  • REKLAMA
  • #7 9840187
    dondu
    Moderator na urlopie...
    maly_elektronik napisał:
    Próbki podawane są jak sądzę w równych odstępach czasu, poprzez _delay_us. A zczytywane są bezpośrednio z karty (dokładniej z bufora w porcjach po 512B).
    Czy podawanie próbek przez Timer będzie dokładniejsze :?:

    No nie żartuj - delay() ??? :)
    Przeanalizuj nieco przykładowych projektów:
    http://mikrokontrolery.blogspot.com/2011/04/ciekawe-projekty-dzwiek.html
  • #8 9840335
    maly_elektronik
    Poziom 23  
    Postanowiłem zmienić to faktycznie na TIMER (pracujący w trybie CTC). Jednak napotkałem na problem wysyłanie danych do PWM realizowane jest przez zewnętrzną funkcję, która odpowiedzialna jest za kolejne odczytywanie klastrów/sektorów z karty. Wy mogę te odstępy czasu realizować poprzez sprawdzanie flagi wystąpienia przerwania OCF0 :?: Bo trochę mi to nie wychodzi (tzn nie gra). Czy ta flaga zeruje się sama po wystąpieniu przerwania (w nocie pisze że aby ją wyzerować należy wpisać logiczne , ale ono przecież występuje w momencie wystąpienia przerwania:?:) czy w nocie jest jakaś nieścisłość :?:
    Cytat:

    The OCF0 bit is set (one) when a compare match occurs between the
    Timer/Counter0 and the data in OCR0 – Output Compare Register0. OCF0 is cleared by hardware when executing the corresponding interrupt handling vector. Alternatively, OCF0 is cleared by writing a logic one to the flag. When the I-bit in SREG, OCIE0 (Timer/Counter0 Compare Match Interrupt Enable), and OCF0 are set (one), the Timer/Counter0 Compare Match Interrupt is executed.

  • #9 9840342
    dondu
    Moderator na urlopie...
    Oj nie czytasz dokładnie:
    Cytat:
    The OCF0 bit is set (one) when a compare match occurs between the
    Timer/Counter0 and the data in OCR0 – Output Compare Register0.
    OCF0 is cleared by hardware when executing the corresponding interrupt handling vector.

    Alternatively, OCF0 is cleared by writing a logic one to the flag. When the I-bit in SREG, OCIE0 (Timer/Counter0 Compare Match Interrupt Enable), and OCF0 are set (one), the Timer/Counter0 Compare Match Interrupt is executed.
  • #10 9841000
    maly_elektronik
    Poziom 23  
    Racja, zgubiło mnie słówko "alternatively".
    Ale mimo to czy sposób jest dobry :?: Ze sprawdzaniem tej flagi i na jej podstawie odmierzanie czasu w zewnętrznej funkcji :?:
  • #11 9841027
    dondu
    Moderator na urlopie...
    Sprawdzanie flagi przerwania w pętli głównej grozi jej nie zauważeniem, ponieważ przerwanie realizowane jest natychmiast i od razu flaga jest gaszona.

    Nie realizowałem PWM w połączeniu z odczytem karty SD, ale od takich zawsze można zastosować bufor w pamięci RAM uC.

    Samo PWM polega na ustawieniu jednego Timera w Phase Corrected Mode, a drugiego na interwały czasowe przy których mają być podawane kolejne próbki dźwięku z bufora. Natomiast uzupełnianie bufora realizować powinien inny proces, który odczytuje wtedy gdy trzeba. Można to zrealizować na wiele sposobów co zależy także od wielkości bufora.

    Tak przynajmniej bym to zrobił ja :)
  • #12 9841067
    maly_elektronik
    Poziom 23  
    Tak też to robię tylko coś nie pasuje :( Tzn gra ładnie ale za szybko)
    Próbkowanie mam 44100Hz więc jak oblicze ze wzoru podanego w nocie (dla CTC) przy 16MHz, preskalerze na 1 i ocr=181. Dostaje porządany efekt blisko częstotliwości próbkowania a jednak w rzeczywistości jest znacznie szybciej, dlaczego tak się dzieje :?:
  • #14 9842013
    maly_elektronik
    Poziom 23  
    Plik main.c
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    funkcja ReadFile:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #16 9846209
    maly_elektronik
    Poziom 23  
    Zegar uC :?: Rozumiem że chodzi o taktowanie procesora, tak:?:

    Dodano po 1 [godziny] 11 [minuty]:

    Dziękuje wszystkim za pomoc :)
    Problem rozwiązałem :)

    Zapomniałem że wzór podany w nocie odnosi się do częstotliwości generowanej na wyjściu OCn :)
    Czyli występowanie flagi przerwania jest dwukrotnie częstsze (dwie składowe okresu stan 0 i 1) :)
    Dlatego tak pędziło :)

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