Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Cyfrowy zapis dźwięku do pamięci FLASH

20 Lis 2005 12:54 3008 13
  • Poziom 18  
    Hej!
    Mam do was prośbę. Planuję właśnie zbudować taki układ do zapisu dzwięku: ATMega + pamięć AT45DBxxx (nie pamietam dokladnie ale mam 16Mbit) + przetwornik C/A. Kiedyśjużcośtakiego próbowałem zrobić ale nie wyszło i wracam do tematu. Chodzi o to, że odczytywanie danych z pamięci zajmuje dużo czasu bo trzeba wysłać kilka bajtów rozkazów i chyba jakieś bajty bezpieczeństwa. Zastanawia mnie jaki kwarc musze zastosować by zapisywać dźwięk o paśmie powiedzmy 6-8kHz i teoretycznie jakie pasmo upakuje do środka. I jeszcze jedno. Przeglądam własnie oferte przetworników C/A i zastanawiam się który wybrać na moje potrzeby, oczywiście z zasilaniem niesymetrycznym. Chciałbym siępozbyć wszelkich wątpliwości zanim jeszcze raz podejmęsiętego tematu. Pozdrawiam i czekam na odpowiedzi
  • Poziom 18  
    Projekt robiłem właśnie na podstawie tej aplikacji. Miałem jednak programy z filtrem Czebyszewa. Wogóle w programie do procka znalazłem dwa błedy, które uniemożliwiały wykonanie tego projektu dlatego z pewną ostrożnością używam tej aplikacji. Chcę jązmienić w ten sposób, że na wyjściu daję przytwornik C/A.
  • Poziom 18  
    Interesujący jest ten projekt. Rozumiem, że mikroprocesor mogę wykorzystać dowolny. Powiem szczerze, że wydaje mi sięto zbyt proste by było prawdziwe. Czy ktoś z was już próbował to zbudować. Jaka jest jakość dźwięku. Te szpilki na wyjściu nie wyglądają przekonująco ale mogę się mylić.
  • Poziom 26  
    Prosty przetwornik C/A można zrobić na drabince rezystorów R-2R podłączonej do jednego z portów. W takim przypadku wystarczy tylko wysłać próbkę dźwięku na port...
  • Poziom 18  
    Układ wstępnie zmontowany. Wykorzystalem MEGE8535, do jednego portu podłaczyłem drabinke R2R, do tego pamięć AT45DB161, a na wejscie ADC0 podałem sinusa z offsetem 2,5V. Niestety robie jakis blad z ustawieniem przetwornika AC. Przebieg na wejściu przetwarzam i podaję odrazu na wyjście by widziec zmiany. Wszystko jest wporzadku do 100Hz. Sinus prawie idealny. Później zaczynają się schodki. Próbkuję układ z f 12kHz. Co jeden okres włącza mi się timer, przetwornik chodzi w free runing mode więc co ten czas odczytuje jego stan. Kwarc mam narazie 8MHz ale jutro chyba zmienie na wyższy. Jak powinienem ustawić rejestry sterujące przetwornika by otrzymać najlepszą jakość? Nie wiem jak rozumie, że czas konwersji wynosi od 60us do 250us. Czy to się ustawia programowo? Bo jeśli tak to dla 60us można uzyskać próbkowanie z 16kHz.
  • Poziom 18  
    Prawie wszystko już gra. Opanowałem sprzętowy przetwornik. Mam jeszcze tylko problem z pamięcią. Czy ktoś z już jej używał? Zmontowałem AT45DB161B tak jak w dokumentacji AVR335. Na oscyloskopie widać, że komunikacja jest w dwie strony. Wysyłam najprawdopodobniej dobrze ale odbieram w inny sposób, czyli Continous Array Read. Robię to tak: wysyłam kod operacji czyli 0x68, później 24 bity adresu i 32 bezpieczeństwa. Wg dokumentacji mogęteraz bez przerwy odbierać bajt po bajcie z pamięci. Nie wiem jednak jak generować cloka nie wysyłając danych. Robię tak że wysyłam przykładowo Write_SPI(0xFF) by generować CLK, i jednocześnie odbierać dane. Ale w ten sposób wpisuję dane wysyłane do SPDR i dane odbierane mi w ten sposób "przepadają". Nie wiem czy się mylę, ale mam z tym wielki problem i nie wiem jak się za to zabrać. Jak to zrobićżeby nic nie generować na MOSI a mieć CLK. Może macie swoje własne biblioteki do obsługi tej pamięci? Proszę o podpowiedz i pozdrawiam.
  • Poziom 42  
    Prymulka napisał:
    Robię tak że wysyłam przykładowo Write_SPI(0xFF) by generować CLK, i jednocześnie odbierać dane. Ale w ten sposób wpisuję dane wysyłane do SPDR i dane odbierane mi w ten sposób "przepadają".
    Nie sądze, do tego układu możesz w czasie odczytywania wysłać cokolwiek (zobacz na przebiegu czasowym). Wpisanie czegoś do SPDR oznacza że ta liczba będzie wysłana po SPI i jednocześnie to co przyjdzie po SPI będzie wpisane do SPDR. Taka jest istota działania SPI, będzie to wykonane bit po bicie, tak że np przerwanie operacji po 4 taktach spowoduje że w 4 MSB SPDR będą 4 LSB z orginalnej wartości wpisanej tam, a w 4 LSB SPDR będą 4 MSB z wartości odczytanej z bufora urządzenia.
  • Poziom 18  
    Czyli SPI wysyła jeden bit, przesuwa rejest SPDR i w jego miejsce wpisuje bit odebrany. No dobra, ale jak to zrobić sprzętowo aby generować kloka i nic nie wysyłać tylko czekać na dane przychodzące. Obsługa tej pamięci wygląda tak że wysyłam chyba osiem bajtów sterujących, adresu i bezpieczeństwa a później bajt po bajcie odbieram dane.
  • Poziom 42  
    Prymulka napisał:
    Czyli SPI wysyła jeden bit, przesuwa rejest SPDR i w jego miejsce wpisuje bit odebrany. No dobra, ale jak to zrobić sprzętowo aby generować kloka i nic nie wysyłać tylko czekać na dane przychodzące.
    Nie da się, bo to nie ma sensu, a kto przesunie rejestr? A skoro przesuwasz to ładujesz starą zawartośc do urządzenia. Czy będzie to wartość 0x00 czy 0xFF czy jakaś dowolna inna (nawet ta odebrana poprzednio z urządzenia) to jest to samo, nawet na wykresach przebiegów czasowych jest to oznaczone, że wartość ta nie jest istotna.
  • Poziom 18  
    Spróbuję jeszcze troche pogrzebać w tym sprzętowym SPI, a jak nadal nie będzie efektów to zrobię programowy. Tylko czy programowy nie będzie wolniejszy od sprzętowego z fclk/4.

    Aha jeszcze jedno
    Jak chcę sprawdzić stan bitu PB6 to musze napisac PINB*64?
    Piszę w c
  • Poziom 42  
    Prymulka napisał:
    Spróbuję jeszcze troche pogrzebać w tym sprzętowym SPI, a jak nadal nie będzie efektów to zrobię programowy. Tylko czy programowy nie będzie wolniejszy od sprzętowego z fclk/4
    Ja myśle że w najlepszym wypadku będzie troszke więcej wolny, nadal nie rozumiem Twoich oporów w używaniu sprzętowego SPI.
  • Poziom 18  
    Czy ktośby mógł zerknąć na ten program. Mam już ładny sinus na wyjściu ale jest jeden problem. Ciągle odczytuje mi wartość ostatniej strony. Nie wiem czy wogóle coś odczytuje ze strony do bufora. To wyglada tak jak by w buforze byla ciagle ta sama watosc.

    Coś jest nie tak w tym fragmencie kodu. Wogóle nie ładuje strony do bfora. Naprawde nie mam pojecia co jest nie tak. Ciagle odtwarza to co ostatnio zapisalo sie w buforze.
    void playback(void)
    {
    unsigned int buffer_counter = 528;
    unsigned int page_counter = 1; // zmienne do odczytu
    unsigned char active_buffer = 1; // 1 - bufor 1, 2 - bufor 2

    // page_counter = 0;
    Page_To_Buffer(page_counter,2);
    while (!(PINB & 0x02));
    // for (page_counter = 0; (page_counter <= 4096) & (!(PIND & 2)); page_counter++)
    while(((page_counter)<4096)&(!(PIND & 2)))
    {
    // DF_CS_inactive; //make sure to toggle CS signal in order
    // DF_CS_active; //to reset dataflash command decoder

    // Odczyt z data flash do bufora 1
    if (active_buffer == 2)
    {
    Page_To_Buffer(page_counter,2);
    }
    else
    {
    Page_To_Buffer(page_counter,1);
    }
    buffer_counter = 528;
    page_counter++;
    // while(!(Read_DF_status() & 0x80));
    //to reset dataflash command decoder
    if (active_buffer == 2)
    {
    while(--buffer_counter)
    {

    PORTC = Buffer_Read_Byte(1, buffer_counter);
    PORTB ^= 0x08;
    wait1us(7);
    }
    }
    else
    {
    while (--buffer_counter);
    {
    PORTC = Buffer_Read_Byte(2, buffer_counter);
    PORTB ^= 0x08;
    wait1us(7);
    }
    }

    if (active_buffer == 1)
    active_buffer = 2;
    else
    active_buffer = 1;

    PORTB ^= 0x08;
    }
    }

    Zauważyłem jeszcze jedną rzecz. Przy zapisie ani przy odczycie nie zmienia się bit RDY/BUSY. Powinien wskazywaćBUSY przy wszystkich operacjach wykonywanych na stronach. Niestety tak nie jest. Ma cały czas 1.