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

predkosc zapisu z Atmega48 do pamiec Dataflash

05 Sty 2006 15:44 1422 11
  • Poziom 10  
    W Atmedze uzywam wewnetrznego osculatora ~ 8MHz , zaleznosc pomiedzy czestotliwoscia oscylatora a SCK ustawilem na
    Fsck/2 mimo to przy zapisie do pamieci konkretnie AT45DB321C, otrzymuje okolo 10KB/4s??. Jak zwiekszyc predkosc zapisu do pamieci
    AT45DB321C???

    Pozdrawiam!
  • Poziom 32  
    A czy używasz obydwu buforów do zapisu czy tylko jeden ? A może nie stosujesz zapisu przez bufory ?? J jak kontrolujesz gotowość pamięci ??
  • Poziom 24  
    Zalecana przez Atmela częstotliwość to Fsck/4.
  • Poziom 10  
    Uzywam jednego bufora pewnie w tym jest problem, sprobuje z dwoma moze pomoze Dzieki i Pozdrawiam

    Dodano po 1 [godziny] 17 [minuty]:

    Zapisujac do pamieci 0,5 MB uzywajac jednego buffora uzyskuje czas ~3:35 s gdy wykorzystalem drugi buffor czas sie skrocil sie do 2:09 s ale to i tak za duzo! SPI inicjalizuje nastepujaco:

    SPSR = (1<<SPI2X);
    SPCR = (1<<SPE) | (1<<MSTR) | (1<<CPHA) | (1<<CPOL);

    Jesli chodzi o sprawdzanie gotowosci pamieci to kontroluje rejestr Status Register
    Czy uzyskiwana predkosc zapisu jest minimalna czy mozna ja przyspieszyc???

    Pozdrawiam
  • Poziom 32  
    kknapek napisał:
    Jesli chodzi o sprawdzanie gotowosci pamieci to kontroluje rejestr Status Register
    Pozdrawiam
    Może w tym tkwi problem. Te pamięci w obudowach TSOP28 mają wyjście READY/BUSY które służy do sprzętowej kontroli gotowości a tak to tracisz ileś tam bajtów transmisji na sprawdzenie tej gotowości.
  • Poziom 18  
    Ja używam ATMega8535 na 16MHz i fclk/4. Nagrywam dzięk w czasie rzeczywistym przy próbkowaniu 20kHz co daje 20kB/s tyle że używam dwóch buforów. A oórocz tego jest wykonywanych mnóstwo innych operacji. Kiedyśzrobiłem ten sam błąd i transmisja nie wyrabiała.
    Kiedy używasz jednego bufora powiedzmy że go całego zapełniasz i przesyłasz do pamięci głównej. Trwa to o ile dobrze pamiętam kilkanaście ms. W tym czasie nic nie możesz na tym buforze zrobić bo jest kopiowany.
    Kiedy używasz dwóch buforów operacje są wykonywane równolegle. Kiedy zapełnisz pierwszy bufor jest on wysyłane do pamięci głównej, a w tym samym czasie nowe dane wgrywasz do bufora 2. W ten sposób transmisja trwa bez przerwy.

    A odnośnie RDY/BUSY mój program działa poprawnie bez sprawdzania czy pamięćjest zajęta a więc spokojnie się wyrabia. Kiedy wysyłasz szeregowo Status Register to i tak nie powinno wiele zmieniać bo jest to operacja wykonywana niezależnie do operacji kopiowania do/z głównej pamięci.
  • Poziom 10  
    Czyli zapis d o2 bufforow na raz ok! Zrobilem tak ale dalo to oczekiwanego efektu. Nie wiem do konca jak jednoczesnie zapisywac buffor1 do pamieci i jednoczesnie zapelniac buffor2. Operacje wykonuje sekwencyjnie , zapisuje buffor1 oraz buffor2 a nastepnie zapisuje je do pamieci, czy tak to powinno wygladac??
  • Poziom 24  
    Chyba chodziło o naprzemienną pracę buforów - jeden ładujesz danymi a drugi jest kopiowany do FLASH-a
  • Poziom 18  
    Nie! Ten sposób nie ma sensu.Teraz zapełniasz dwa bufory a później czekasz dwa razy dłużej na zapis do pamięci głównej. Musisz zrobićtak jak napisałem wcześniej. Zapełniacz bufor 1 i kopiujesz do pamięci głównej. W tym czasie gdy ten jest kopiowany możesz zapisywaćdo buforu drugiego ponieważ operacje te można wykonywać równolegle. Zerknij do dokumentacji. Rozkazy masz podzielone na trzy grupy, które można wykonywać równolegle. Mogę ci podesłaćkod mojego programu, ale mam go w pracy więc dopiero jutro. Póki co ściągnij dokumentacje atmela:
    http://www.atmel.com/dyn/resources/prod_documents/doc1456.pdf
    http://www.atmel.com/dyn/resources/prod_documents/avr335.zip
    Poszukaj funkcji zapisu i odczytu. Przykład jest na podstawie nagrywania dźwięku. Najważniejsza dla ciebie jest zmiana active_buffer. Tylko uważaj bo w tym kodzie są błędy i o ile dobrze pamiętam to chyba nawet przy zmianie buforów, więc go nie kopiuj bezpośrednio.
    Pozdrawiam
  • Poziom 18  
    Mówisz masz. Ten kod jest prawidłowy dla AT45DB161 więc musisz pozmieniac niektore parametry jak by co. Nie wrzucęci tutaj całego kodu ale tylko niezbedne fragmenty. Zresztą całego nawet nie mogę umieścić :D. Właściwie to interesuje cie tylko zapis więc:
    unsigned char act_buffer=1; // zmienna globalna

    void write_to_flash(unsigned char flash_data)
    {

    SPCR = 0x5C;

    if (act_buffer == 1)
    Buffer_Write_Byte(1,buffer_count,flash_data);
    else
    Buffer_Write_Byte(2,buffer_count,flash_data);

    buffer_count++;
    if (buffer_count >=528)//if buffer full write buffer into memory page
    {
    buffer_count = 0;
    if (page_num < 4094) //if memory is not full
    {
    licznik_stron++;
    PORTB &= ~DF_CHIP_SELECT; //enable DataFlash

    if (act_buffer == 1)
    Buffer_To_Page(1,page_num);
    else
    Buffer_To_Page(2,page_num);

    page_num++;
    if (act_buffer == 1)
    act_buffer++;
    else
    act_buffer--;
    }
    else
    {
    PORTB |= 0x08;
    }
    }
    SPCR = 0x00; //disable SPI


    }

    SIGNAL (SIG_OVERFLOW0)
    {
    TCNT0 = 0xAB;
    do
    {
    }while(!(ADCSRA&(1<<ADIF)));
    ADCSRA |= 0x40;
    write_to_flash(ADC>>2);
    PORTB ^= 0x08;
    }

    void Buffer_Write_Byte (unsigned char BufferNo, unsigned int IntPageAdr, unsigned char Data)
    {

    DF_CS_inactive; //make sure to toggle CS signal in order
    DF_CS_active; //to reset dataflash command decoder

    if (1 == BufferNo) //write byte to buffer 1
    {
    DF_SPI_RW(Buf1Write); //buffer 1 write op-code
    DF_SPI_RW(0x00); //don't cares
    DF_SPI_RW((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address
    DF_SPI_RW((unsigned char)(IntPageAdr)); //lower part of internal buffer address
    DF_SPI_RW(Data); //write data byte
    }

    //#ifdef USE_BUFFER2
    else
    // if (2 == BufferNo) //write byte to buffer 2
    {
    DF_SPI_RW(Buf2Write); //buffer 2 write op-code
    DF_SPI_RW(0x00); //don't cares
    DF_SPI_RW((unsigned char)(IntPageAdr>>8));//upper part of internal buffer address
    DF_SPI_RW((unsigned char)(IntPageAdr)); //lower part of internal buffer address
    DF_SPI_RW(Data); //write data byte
    }
    //#endif
    }

    void Buffer_To_Page (unsigned char BufferNo, unsigned int PageAdr)
    {
    DF_CS_inactive; //make sure to toggle CS signal in order
    DF_CS_active; //to reset dataflash command decoder

    if (1 == BufferNo) //program flash page from buffer 1
    {
    DF_SPI_RW(Buf1ToFlashWE); //buffer 1 to flash with erase op-code
    DF_SPI_RW((unsigned char)(PageAdr >> (16 - PageBits))); //upper part of page address
    DF_SPI_RW((unsigned char)(PageAdr << (PageBits - 8))); //lower part of page address
    DF_SPI_RW(0x00); //don't cares
    }

    //#ifdef USE_BUFFER2
    else
    // if (2 == BufferNo) //program flash page from buffer 2
    {
    DF_SPI_RW(Buf2ToFlashWE); //buffer 2 to flash with erase op-code
    DF_SPI_RW((unsigned char)(PageAdr >> (16 - PageBits))); //upper part of page address
    DF_SPI_RW((unsigned char)(PageAdr << (PageBits - 8))); //lower part of page address
    DF_SPI_RW(0x00); //don't cares
    }
    //#endif

    DF_CS_inactive; //initiate flash page programming
    DF_CS_active;
    }


    Funkcja write_to_flash jest odpalana przez timer0 który chodzi z f 22kHz. Zwróć uwagęjak pracuje act_buffer. Jeśli masz pytania to pisz.
  • Poziom 10  
    Fajnie! co do calosci kodu to zrozumiala sprawa, zreszta nie jest mi potrzebny. Pomalu dochodze do ladu z ta pamiecia Dzieki Nara
    P.S jak sie pojawia jakies klopoty to sie zglosze:)
  • Poziom 18  
    Nie ma sprawy. I tak napisz jak sobie poradzisz. Tak wogóle to spotkałem bardzo mało osób które korzystają z tej pamięci, a jest ona naprawde super.