mikroc fat32 library

Başlatan Karamel, 18 Ağustos 2015, 02:24:16

Karamel

merhaba. suradaki https://www.picproje.org/index.php?topic=60670.new#new topic icersinde 16 bit 44100 hz wav file calmayi basardik ::) orada ufak bir belirsizligi gidermek ve wav playerimin bir sonraki adimina gecmek icin. wav file lari microsd card in icersinden okuyup. calmak gerekli. microsd card icersinden wav file i sanki hex editorden aciyormus gibi acacagimizdan. direk data lari digital analog converter unit imize tasiyip. sorunu bulacagiz.

simdi fatih6761 den duzgun volume de calinabilen bir file gelince. cok heyecanlandim ve hemen aklima bu durumu microsdcard ile dogruma fikri geldi. hemen deneylere basladim. anlamadigim bazi seyler olustu.

libraryimiz libstock tan alinan mikroelektronika nin dagittigi library. http://www.libstock.com/projects/view/108/fat32-library

bu kisimda fat32 library i. spi i init ediyoruz.

    initSPI();

    err = FAT32_Init();
    // err = FAT32_format("dev0");
    if (err < 0)        //
    {
        while(err < 0)  //  ...retry each second
        {
            err = FAT32_Init();
            Delay_ms(1000);
        }
    }


eger hersey okay ise. spi i fast mode a aliyoruz.

    initFastSPI();   
    
    err = FAT32_Dir();
    
    fileHandle[0] = FAT32_Open("a.TXT", FILE_READ);
    err = FAT32_Read (fileHandle[0], rdbuf, sizeof(rdbuf));





ben example dan yuruyerek hemen deneyde  fileHandle[0] = FAT32_Open("a.TXT", FILE_READ); sekilde "a" isimli txt file i open edebildim. daha sonra bunu read edebildim. yalniz bu code larin nasil calistigini anlayamadim.

burada tam olarak ne yaptik?
    fileHandle[0] = FAT32_Open("a.TXT", FILE_READ);


burada a.txt file in ne kadarini okuduk? ben deneyi 512 byte gore yaptim. bir cumle yazip. bunu surekli copy paste yaptim. 512 byte a kadar okuyabildi.
  err = FAT32_Read (fileHandle[0], rdbuf, sizeof(rdbuf));



fatih6761

Not: tam olarak ne yaptık? sorusu üzerine uzun uzadıya yazdım.

FAT32_Open ile dosyayı açtın. Evet, çok açıklayıcı oldu :)
Kütüphane dosya adını diskteki root directory entry'lerinde aradı.
Dosyayı bulunca entryden dosyanın verilerinin bulunduğu ilk logical cluster adresini ve dosyanın byte cinsinden boyutunu buldu.
Tekrar diske gitti ve elindeki logical cluster adresini FAT(file allocation table)'da buldu ve bu bilgileri bir struct'a kaydetti.
Fonksiyon o struct'a ait bir işaretçi döndürdü ve sen bunu fileHandle[0]'a yazdın.
Sonra okumak istediğinde dosya sistemi sürücü bu structa baktı ve daha dosyayı hiç okumadığını gördü.
Daha önce kaydettiği ilk logical cluster adresini physical sector address'e dönüştürdü ve diskte o adrese gidip ilk cluster'ı okudu ardından tahsis ettiğin bellek alanına istediğin kadarını kopyaladı.
Bir sonraki okumanda eğer bir cluster'daki veriyi daha bitirmediysen o cluster'dan kopyalamaya devam edecek.
Eğer o cluster'ın sonuna gelirsen bir sonraki cluster'a geçmek için struct'ta daha önce kaydedilen FAT konumuna gidip dosyaya ait bir sonraki chunk'ın nerede olduğunu bulacak.
O chunk'ın logical adresini physical address'e çevirip bir chunk kadar veriyi okuyacak.
İstediğin kadarını belleğe kopyalayacak.

Kütüphaneye geri dönersek FAT32_Read fonksiyonu da bahsettiğim şekilde gereken okuma işlemini yapıp okuduğu byte sayısını döndürmesi gerekir.
Yani eğer mikroC standartlara uyduysa read fonksiyonu okunan byte sayısını döndürür. En son işlemde err içinde;
-1 varsa okumada hata olmuş. Mesela dosya açılmamış ya da yok.
0 varsa dosya var ama sonuna gelinmiş dolayısıyla okuyacak bir şey kalmamış.
n varsa n byte kadar veri okunmuş anlamına gelir.

E o zaman biz fonksiyonun 3. parametresini ne işe yaradı?
Burada da dosya ve okuma block boyutu devreye giriyor. Mesela dosya boyutu 950 byte olsun. rdbuf ise 100 byte lık bir dizi olsun.
100 okuduk 850 kaldı, 750 kaldı... 50 kaldı.
Son okumada da 100 byte isteyeceğiz ama o kadar veri yok, ne olacak bu durumda?
read fonksiyonu bize 50 değerini döndürerek bunu bildirecek. Bir sonraki okumada da 0 dönecek ve dosya sonuna geldiğimizi böylece anlayacağız.

Terimler:
  Sektör : Fiziksel olarak disk üzerinde bulunan en küçük veri birimleri.
  Chunk : (Katı hal disk için) Bir veya birkaç sektörden oluşan veri birimi (diski biçimlendirirken ayarlanabilir)

Karamel

anladigim kadari ile Fat32_Read ile ilk 512 byte i okuyoruz. bir daha read yapinca. bir sonraki 512 byte i okuyoruz. vs vs . taki. dosya icersindeki bilgileri bitirene kadar.

asagidaki code ile bunu basarabiliyorum.

    err = FAT32_Size("dingdong.WAV", &size);
    for (k = 0; k < size;)
    {
        err = FAT32_Read(fileHandle[0], rdbuf, sizeof(rdbuf));
        for (cnt = 0; cnt < sizeof(rdbuf); cnt++, k++)
        {
            if (k < size)
            {
                  Ses_Cal = rdbuf[cnt];

                  Line1 = Ses_Cal*16;

                  DAC1_Advanced_Ch1_Output(Line1, conf1);
                  DAC1_Advanced_Ch2_Output(Line2, conf2);
                  
                  Delay_us(15);
            }
            else
            {
                  break;
            }
        }
    }


stereo da simdilik byte kaciriyorum. meseleyi suan icin tam olarak anlayamadigimdan. bende hemen 44100hz mono 8 bit e geri dondurdum(simdilik)

yukaridaki codelari yazdim. dingdong caliyor ama calarken farkettim ki. her 512 byte ta bir okuma yapildigindan. ses bozuluyor. sanki wav file in uzerine bir effect bindirmis gibi oluyor.

sonra hemen karar verdim. wav file i digital analog converterlara zamani sasmadan aktarmak gerekli. bunun icin yeni bir interrupt sekli gerekli. aklima timer interrupt geldi? bu is icin ne derece dogru bilemiyorum ama aklimdaki fikir su.


oncelikle ses_buffer[513]; seklinde bir buffer daha yaparim. timer interrupt icersinde ses_buffer array in global lerini sonuna kadar gonderirken. diger yandan fat32 file in bir sonraki 512 byte inin okunmasini saglarim. 512 * 18 usn. 18usn den buyuk bir deger oluyor. sanirim sdcard read function bu zaman dilimi icersinde isini halledebilir?

eger halledebilirse. ses_buffer 512 ye gelince. rdbuf[] icersindeki yeni 512 byte i bir for dongusu ile ses_buffer a hizlica aktaririm?

boyle bekleme hissedilmeyecek kadar az olabilir?

bu isi cozen baska ne tur algoritm lar var?

Gökhan BEKEN

SD karttan okuma işini dma ile yaptırırsan, ölü bekleme olmaz.
SD kartı SPI değil SDIO arayüzüyle kullanırsan 4 katı daha hızlı okuma yapabilirsin.
SD kartın teknoloji eski değil de yeni Class 10 modellerden kullanırsan okuma yazma hızın sınıra takılmaz.
SD kart için ayırdığın SPI veya SDIO'nun frekans ayarı düşük değil de yüksek ise(elm-chan fatfs kütüphanesinde bu ayar mevcut), hızlı olur.
512byte okumak zorunda olman da kötü bişey, elm-chan fatfs kütüphanesini kullansaydın okunacak byte sayısını sen seçebilirdin.
Özel mesaj okumuyorum, lütfen göndermeyin.

Karamel

#4
hocam bundada secebiliyoruz. yani 2kbyte falanda yapabiliriz.
hocam sdio portd de bir pin ile cakisiyor. ben portd yi ssd1963 icin kullanmak istiyorum. o yuzden spi ile yapma girisiminde bulunduydum.

az once olcumleri yaptim. simdi isin rengi cok degisti.

ilk once programi yukarida anlattigim gibi yaptim. tim2 yu 20usn ye calistirdim. daha sonra 512 byte lik bir buffer hazirlayip. ana bufferimiz okunurken. ben bu copy buffer i timer ile digital analog converter a gondermeye calistim.

dusunceme gore coppy bufferimiz bitince. for ile yeni okunmus 512 byte lik ana bufferimizi copy ye aktarip. daha sonra o daha da yeni bir 512 byte okurken. ben tazelenmis copy bufferimi tim2 yardimiyla gonderecektim ki. basarili olmadim.

hemen code lara led blink code u ekledim ve logic analyzerim ile olcumleri yaptim. read function inda duruma gore 1-3 msn arasinda vakit kaybettigi oluyor. ortalama 2.5 msn vakit kaybediyor.


simdi 512 byte ile bu isi becerebilmesi gerekli? 512 * 20 = 10.24 msn vaktimiz var. interrupt yuzunden bunun yarisi gitse. yaklasik 5 msn miz var. theory im neden tutmadi. anlayamadim. sanirim algorithm bir yerde yetersiz kaldi.  :-\

mesaj birleştirme:: 19 Ağustos 2015, 02:08:38

suan ses aliyorum ama bozuk. tahminimce benim theory bir yerleri cozemedi. yeni bastan. kagit uzerinde bir gozden gecireyim en iyisi.

mesaj birleştirme:: 19 Ağustos 2015, 02:24:34

tamam. isi becerdim. buffer i 2 katina cikarttim. 1024 byte in bu is icin yeterli olamasi gerekliydi. oylede oldu. deneyi yaptim. 8 bit 44100 hz mono file i calabildim. simdi 16 bit stereo su uzerinde deneyler yapacagim. ::)

Gökhan BEKEN

Bu arada, sdkart ile okuma yaparken ne kadar çok okursan o kadar hızlı byte okursun.
atıyorum mesela 512 byte'ı 100 birimde okuyorsan, 5120 byte'ı orantılayınca 1000 birim yapar amma velakin öyle değildir, 5120 byte'ı 500 birimde bile okuyabilirsin.
Yani toptan alırsan indirim yapıyor :)
Özel mesaj okumuyorum, lütfen göndermeyin.

Karamel

#6
anladigim kadariyla hocam. okuma yapabilmek icin. en basta initialize code lari cok vakit aliyor. sonra pat pat pat diye okuyor?

bu arada 16 bit wav file dan hic sonuc alamadim. bende deneyleri bir sure daha 8 bit 44100 hz de yapayim dedim. burada daha ilginc bir problem beliriverdi.

en basta tim2 de sunlari yapiyoruz.

void Timer2_interrupt() iv IVT_INT_TIM2 {

  unsigned int Line1;
  unsigned int Line2;

  TIM2_SR.UIF = 0;
  GPIOB_ODR.F8 = ~GPIOB_ODR.F8;
  
  Ses_Cal = Ses_Buffer[value];

  Line1 = Ses_Cal*16;

  DAC1_Advanced_Ch1_Output(Line1, conf1);
  DAC1_Advanced_Ch2_Output(Line1, conf2);
  
  value++;

  if(value > sizeof(rdbuf))
  {
     value = 0;
     Calma_izin = 1;
  }
}



daha sonra calmak istedigimiz wav file i asagidaki code lar ile calabiliyoruz.
    err = FAT32_Dir();
    fileHandle[0] = FAT32_Open("dingdong.WAV", FILE_READ);
    err = FAT32_Size("dingdong.WAV", &size);
    for (k = 0; k < size;)
    {
        err = FAT32_Read(fileHandle[0], rdbuf, sizeof(rdbuf));
        for (cnt = 0; cnt < sizeof(rdbuf); cnt++, k++)
        {
            if (k < size){}
            else{break;}
        }
        TIM2_CR1.CEN = 1;
        while(Calma_izin == 0);
        for(f = 0; f<sizeof(rdbuf); f++) Ses_Buffer[f] = rdbuf[f];
        Calma_izin = 0;
    }
    err = FAT32_Close(fileHandle[0]);
    Delay_ms(200);

    fileHandle[0] = FAT32_Open("CS.WAV", FILE_READ);
    err = FAT32_Size("CS.WAV", &size);
    for (k = 0; k < size;)
    {
        err = FAT32_Read(fileHandle[0], rdbuf, sizeof(rdbuf));
        for (cnt = 0; cnt < sizeof(rdbuf); cnt++, k++)
        {
            if (k < size){}
            else{break;}
        }
        TIM2_CR1.CEN = 1;
        while(Calma_izin == 0);
        for(f = 0; f<sizeof(rdbuf); f++) Ses_Buffer[f] = rdbuf[f];
        Calma_izin = 0;
    }
    err = FAT32_Close(fileHandle[0]);
    Delay_ms(100);

    fileHandle[0] = FAT32_Open("r.WAV", FILE_READ);
    err = FAT32_Size("r.WAV", &size);
    for (k = 0; k < size;)
    {
        err = FAT32_Read(fileHandle[0], rdbuf, sizeof(rdbuf));
        for (cnt = 0; cnt < sizeof(rdbuf); cnt++, k++)
        {
            if (k < size){}
            else{break;}
        }
        TIM2_CR1.CEN = 1;
        while(Calma_izin == 0);
        for(f = 0; f<sizeof(rdbuf); f++) Ses_Buffer[f] = rdbuf[f];
        Calma_izin = 0;
    }
    err = FAT32_Close(fileHandle[0]);
    Delay_ms(100);

    fileHandle[0] = FAT32_Open("F.WAV", FILE_READ);
    err = FAT32_Size("F.WAV", &size);
    for (k = 0; k < size;)
    {
        err = FAT32_Read(fileHandle[0], rdbuf, sizeof(rdbuf));
        for (cnt = 0; cnt < sizeof(rdbuf); cnt++, k++)
        {
            if (k < size){}
            else{break;}
        }
        TIM2_CR1.CEN = 1;
        while(Calma_izin == 0);
        for(f = 0; f<sizeof(rdbuf); f++) Ses_Buffer[f] = rdbuf[f];
        Calma_izin = 0;
    }

    err = FAT32_Close(fileHandle[0]);
                Heard_Led = 1; TIM2_CR1.CEN = 0;
                while(1);


mesaj birleştirme:: 19 Ağustos 2015, 04:17:05

bu r.wav daha sonra F.wav. dingdong.wav. bunlar ayri ayri wav file larimiz. sarki bunlar. ard arda calayim dedim bakalim neler olacak.

olan sey cok esrarengiz. simdi en basta su code lari yaziyorum. digerlerini commend yapiyorum.


    err = FAT32_Dir();
    fileHandle[0] = FAT32_Open("dingdong.WAV", FILE_READ);
    err = FAT32_Size("dingdong.WAV", &size);
    for (k = 0; k < size;)
    {
        err = FAT32_Read(fileHandle[0], rdbuf, sizeof(rdbuf));
        for (cnt = 0; cnt < sizeof(rdbuf); cnt++, k++)
        {
            if (k < size){}
            else{break;}
        }
        TIM2_CR1.CEN = 1;
        while(Calma_izin == 0);
        for(f = 0; f<sizeof(rdbuf); f++) Ses_Buffer[f] = rdbuf[f];
        Calma_izin = 0;
    }
    err = FAT32_Close(fileHandle[0]);
    Delay_ms(200);


dingdong temizce caliyor. daha sonra ardina CS.wav li olan code larin commendini kaldiriyorum. digerleri commend seklinde duruyor. once iste dingdong yapiyor. daha sonra sarki calmaya basliyor.

iste simdi esrarengizlik basladi.

r.wav li kisiminda commendini ladiriyorum. kalanlar yine duruyor. calismaya baslar baslamaz daha dingdong calarken bile bir zirilti basliyor. r.wav file da sorun olsa. r yi calarken sorun olmasi gerekir? sorun en bastan basliyor. r.wav li kismi commend haline yeniden getirirsek. yine sorun yok. dingdong ve cs sarkisi caliyor.

sonra en sona F.wav i ekleyince yine system tam takir calisiyor. en bastan o zirilti olmadan. r.wav sarkisida duzgunce caliniyor.

simdi ben bu ne bicim istir anlamadim. anlayabilen hocalarim varsa birisi bana bunu anlatsin. sonraya ekledigim code lar. daha hic islenmeden en bastaki duzeni alt ust ediveriyorlar?

LukeSkywalker

#7
Şimdi sen exampledan yola çıkarak bişeyler yapmışsın ama çok fazla gereksiz kod parçası var. Şöyle yap daha sade olur;
#include "__Lib_FAT32.h"
uint32 size;
short filehandle;
char readbuff[512];
char kactane=0;
int8 error;

sbit Mmc_Chip_Select at GPIOC_ODR.B0; // hangi pini kullanıyorsan artık

void main()
{
SPI3_Init_Advanced(_SPI_FPCLK_DIV64, _SPI_MASTER | _SPI_8_BIT |
                       _SPI_CLK_IDLE_LOW | _SPI_FIRST_CLK_EDGE_TRANSITION |
                       _SPI_MSB_FIRST | _SPI_SS_DISABLE | _SPI_SSM_ENABLE | _SPI_SSI_1,
                       &_GPIO_MODULE_SPI3_PC10_11_12);

error = FAT32_Init();

while(error < 0) 
        {
            error = FAT32_Init();
            Delay_ms(1000);
        }

 SPI3_CR1 = 0;

 SPI3_Init_Advanced(_SPI_FPCLK_DIV8, _SPI_MASTER | _SPI_8_BIT |
                       _SPI_CLK_IDLE_LOW | _SPI_FIRST_CLK_EDGE_TRANSITION |
                       _SPI_MSB_FIRST | _SPI_SS_DISABLE | _SPI_SSM_ENABLE | _SPI_SSI_1,
                       &_GPIO_MODULE_SPI3_PC10_11_12);

filehandle = FAT32_Open("dingdong.WAV", FILE_READ);
FAT32_Size("dingdong.WAV", &size);
FAT32_Read(fileHandle, readbuff, 512);
}


Yukarıdaki kod dingdong.wav dosyasından 512 byte veri okumanın en sade hali.

Şimdi gelelim dosya boyutunun önemine. Her seferinde 512 byte veriyi okudun diyelim, senin dosya boyutunda atıyorum 1985 byte olsun. Her okuduğunda bunu kontrol edeceksin. Şöyle;
FAT32_Size("dingdong.WAV", &size);
while()
{
 FAT32_Read(fileHandle, readbuff, boy);
 olcum+=512;
 if(olcum>size)boy=size-olcum;
 else boy=512;
}
olcum=0;
boy=512;


Yukarıdaki şekilde yaparsan her seferinde 512 byte okursun ve dosya sonuna geldiğinde de geriye ne kadar kaldıysa o kadar okursun.

Tabi şöyle de bir şey yapmak lazım; Okuduğumuz bufferı sürekli kontrol altında tutacağız. İki adet buffer tutmak lazım. Birinci bufferdaki veriler dac'a gmönderilip bitince, ikinci bufferdaki verileri daca göndermek, bu arada birinci bufferı dosya işaretçisinin kaldığı yerden sd kartı okuyarak tekrar doldurmak gerek.

LukeSkywalker

Oturdum biraz deney yapıp teoriden pratiğe geçtim. Uzun zamandır kod yazma isteği kalmamıştı, bu iyi oldu @Karamel.
Şimdi yukarıda belirttiğim teorik bilgileri pratiğe dönüştürerek kabaca şöyle birşeyler yaptım;

//***********************************************************
void tamponal()
{
 int j=0;
 for(j=0;j<1024;j++)tampon[j]=rdbuf[j];
}
//*******************************************************************************
 void tamponal2()
{
 int j=0;
 for(j=0;j<1024;j++)tampon2[j]=rdbuf[j];
}

//*******************************************************************************
void karttanoku()
{
 FAT32_Read(fHandle, rdbuf, boy);
 olcum+=1024;
 if(olcum>size)boy=size-olcum;
 else boy=1024;
}
//*******************************************************************************


Bunlar tanımladığım fonksiyonlardı. Şimdi diğer kısma bakalım;

fhandle=Fat32_Open("2.wav",FILE_READ);
 karttanoku();
 tamponal();
 karttanoku();
 TIM7_CR1.CEN=1;
 while(1)
 {
  if(k==1){tamponal2();karttanoku();}
  if(k==1024){tamponal();karttanoku();}
 }
}

//***********************************************************
//***********************************************************
void Timer7_interrupt() iv IVT_INT_TIM7 {
  TIM7_SR.UIF = 0;
  if(k<1024)veri=tampon[i];
  else veri=tampon2[i];
  DAC_DHR12R1=(veri<<4);
  i++;k++;leng++;
  if(i==boy)i=0;
  if(k==2048)k=0;
  if(leng>size){TIM7_CR1.CEN=0;devam=0;};
  }
//***********************************************************
//***********************************************************



Sabahki mesajlarımda yazdığım şeyleri pratiğe dönüştürdüm. İki adet tampon tanımladım. İki kovam var, birisi boşalınca diğerinden devam ediyorum, bu boşalırken, öbürü doluyor. Amaç verileri sadece RAM'den alıp DAC'a göndermek.

Kod düzenlenebilir, daha sağlam yazılabilir,  işlemci daha az yorulabilir. Fazla yormadım kafayı üzerinde. Sadece bu şekilde devam edersen sesi daha cızırtısız ve net alacağını göstermek istedim.

Gökhan BEKEN

Hocam
tamponal(); ve tamponal2(); fonksiyonları ekstradan zaman kaybettiriyor.
unsigned char tampon[1024]; 
FAT32_Read(fHandle, &tampon2[0], boy); //ilk yarıyı doldur
FAT32_Read(fHandle, &tampon2[512], boy);  //ikinci yarıyı doldur

gibi şekillerde direkt adres vermek daha kestirme yol. Ben hep böyle kullanıyorum, buffer boyutu küçükken sorun olmaz ama büyük buffer'larda ve kritik zamanlamalarda önem arzediyor.

Kova olayı çok mantıklı ama dma olmayınca avantajı olmuyor, çünkü kovanın birini dma doldururken, diğer kovayı dac boşaltmalı.
E zaten sd kart ölü bekleme yapıyor, o halde 2 kovanın bir anlamı kalmıyor.
Özel mesaj okumuyorum, lütfen göndermeyin.

LukeSkywalker

#10
Dedimya kodlar daha kısa yazılabilir. Fazla düşünmeden uğraşmadan yazdım.
Aslında burada bu şekilde yapılması gayet mantıklı. Veriler DAC birimine kesme vasıtasıyla iletilirken, kesme haricindeki zamanlarda okuma yapıldığından seste sıkıntı oluşmuyor. Karamel'in yaptığı gibi tek tamponla yapılması seste bozulmalara sebep olur. DMA ile yapılsa tek dizi ile halledilir zaten.  Fakat iki tampon yöntemi de konunun anlaşılması açısından  önemli.

Karamel

#11
hocalarima bir iyi. Gokhan hocama bir kotu haberim var.

sabahleyin 16 bit 44100 hz mono wav file i calabildim. quality is excellent! :) sarki caldirmistim. bir music player yapmis kadar cok sevdim. Gokhan hocam size kotu haber. sizin wav to hex converter programiniz yuksek volume lerde sorun cikartiyor. onu yeniden gozden gecirmelisiniz. gerci suan icin bakiyorumda. biz wav to hex deneyini wav file i tanimak icin yapmistik. microsd card gibi bir system varken. wav to hex yapip. microcontroller in rom memory sini 16 bit 44100 hz gibi cok yer tutan bir file ile doldurmak cokta mantikli değil?

neyse neler yaptigima geri donelim :)
void Timer2_interrupt() iv IVT_INT_TIM2 {

  unsigned int Line1;
  unsigned int Line2;

  Ses_Cal = 0;
  Ses_Cal = Ses_Buffer[value + 1];
  Ses_Cal = Ses_Cal << 8;
  Ses_Cal = (Ses_Cal | Ses_Buffer[value]);
  Ses_Cal = (Ses_Cal + 32768);
  Ses_Cal = (Ses_Cal >> 4) & 0x0FFF;

  Line1 = Ses_Cal;

  //Ses_Cal = Ses_Buffer[value + 3];
  //Ses_Cal = Ses_Cal << 8;
  //Ses_Cal = (Ses_Cal | Ses_Buffer[value + 2]);
  //Ses_Cal = (Ses_Cal + 32768);
  //Ses_Cal = (Ses_Cal >> 4) & 0x0FFF;

  //Line2 = Ses_Cal;

  DAC1_Advanced_Ch1_Output(Line1, conf1);
  DAC1_Advanced_Ch2_Output(Line1, conf1);
 

  value++; value++; //value++; value++;



  TIM2_SR.UIF = 0;
  GPIOB_ODR.F8 = ~GPIOB_ODR.F8;

  if(value >= sizeof(rdbuf))
  {
     value = 0;
     Calma_izin = 1;
  }
}


simdi oncelikle bufferlarimi 2048 byte a cikarttim. timer 2 de Ses_Buffer imi yaklasik 21usn de. adim adim digital analog converterima send ediyorum. bunu yaparken. main icersinde bir sonraki 2048 byte okunuyor. tim2 da ne zaman ki Ses_Buffer icerigi bitmisse. Calma_izin i veriliyor. izin verilince main de bir for ile yeni buffer value lari Ses_Buffer a geciriliyor. yeni value lar dac unit e giderken. main de yine bir sonraki 2048 byte okunmaya baslaniyor. stereo ile daha ilgilenmedim. tim2 icersindeki // comment li satirlari kaldirinca ve dac ch2 ya line2 value su verilince stereo olacak.

daha sonra adagidaki kismi Wav_Cal() seklinde bir function haline getirdim.
void Wav_Cal()
{
    fileHandle[0] = FAT32_Open(FileName, FILE_READ);
    err = FAT32_Size(FileName, &size);
    for (k = 0; k < size;)
    {
        err = FAT32_Read(fileHandle[0], rdbuf, sizeof(rdbuf));
        for (cnt = 0; cnt < sizeof(rdbuf); cnt++, k++)
        {
            if (k < size){}
            else{break;}
        }
        TIM2_CR1.CEN = 1;
        while(Calma_izin == 0);
        for(f = 0; f<sizeof(rdbuf); f++) Ses_Buffer[f] = rdbuf[f];
        Calma_izin = 0;
    }  TIM2_CR1.CEN = 0;
    err = FAT32_Close(fileHandle[0]);
}


Wav cali cagirmadan once FileName isimli array e wav in file name ini yazinca. microsd card icersindeki istedigimiz wav file i calabiliyoruz ::)

LukeSkywalker

for(f = 0; f<sizeof(rdbuf); f++) Ses_Buffer[f] = rdbuf[f];

Şu noktada vakit kaybettiğin için ses kalitesinin mükemmel olması imkansız.

Bu sebeple ya bufferı ikiye bölerek çalışacaksın ya da iki buffer kullanacaksın.

Karamel

#13
hocam oradaki hesabi yapmistim. 22 us den kisa biz zamanda 2048 byte i digerine copy edebilmesi lazim. tabiki ben bunu c code line larina gore hesapladim. daha fazla vakit kaybediyorsa onu bilemeyecegim

simdi sizin modele dondurtmeye calisiyorum programimi. ::)

hocam birde Wav_Cal funcfion ima filename array i ni call ederken gondermek istiyorum.

mesela Wav_Cal("A.WAV);

Wav_Cal icersinden A.WAV i nasil alabilirim?

mesaj birleştirme:: 19 Ağustos 2015, 20:24:07

Alıntı yapılan: LukeSkywalker - 19 Ağustos 2015, 19:21:36
for(f = 0; f<sizeof(rdbuf); f++) Ses_Buffer[f] = rdbuf[f];

Şu noktada vakit kaybettiğin için ses kalitesinin mükemmel olması imkansız.

Bu sebeple ya bufferı ikiye bölerek çalışacaksın ya da iki buffer kullanacaksın.

hocam simdi dusundumde. burayi 22 usn de beceremese bile sound ta bozulma olmamasi gerekir. nedeni su.

mesela 22usn de atiyorum 500 byte i aktarabildik. tim2 icersinde copy edilenden ilk yani 0. byte gideceginden. donuste. for icersinde kalan 1548 copy edilmeye calisilacak. tim2 bir kacbyte i gonderdikten sonra microcontrollerin buradaki isi bitecek ve yeni 2048 byte ini okumaya calisacak? tezim kagit uzerinde olur gibi dozukuyor?  :-\

LukeSkywalker

Ses calmiyor ki o arada. Calmaizin=1 o bolgede henuz. Zaten pit pit sesletini duyman lazim. Filtreden dolayi duymuyor olabilirsin.