MMC Yazma yardım

Başlatan thenorthstar, 26 Nisan 2011, 16:12:14

thenorthstar

S.A Arkadaşlar;
Hocam kusura bakmayın rahatsız ediyorum, yardımınıza ihtiyacım var.
aşağıdaki kodlarla uğraşıyorum, mmc içerisine dosya oluşturuyorum ve dosyanın içerisinede veri yazayorum fakat yazılan veri karakterleri arasında bokluk oluyor, verileri tam yazamıyorum bazende karakterler arasına saçma sapan karakterler giriyor.
Müsait olursanız bir inceleme imkanınız varmı acaba. Burda soft spı kullanılmış bunu HW spı yapabilirmiyiz?
System Start : bunu yazması gerekirken resimdekini yazıyor. :'(




My main Code:
#include <18F4620.h>
#include <string.h> 
#include <MMC_SPI_FAT32.h> 

#fuses HS,NOWDT,NOPROTECT,BROWNOUT,NOLVP,NOCPD 
#use delay(clock=10000000)    
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8) 
#include "2x16_4x20_LCD.c" 
#include "MMC_SPI_FAT32.c" 

void main(){ 
    delay_ms(1000);
   char f,gfilename[12]; 
   char msg[100]; 
  // setup(); 
  lcd_init(); 
  LCD_gotoxy(1,1);
   printf(lcd_putc,"MMC KONTROL");
  if(MMCInit() == MMC_OK)  {
      LCD_gotoxy(1,1);
    
    printf(lcd_putc,"MMC init OK\n");
      delay_ms(1000); 
    
    InitFAT();
   
     LCD_gotoxy(1,2);
      printf(lcd_putc,"FAT init OK\n"); 
      delay_ms(1000); 
      printf(lcd_putc,"\f");  
     
      strcpy(gfilename,"EVENTS.LOG");
      f = fopen(gfilename,'a'); // open EVENTS.LOG for append      

   if (f & MMC_ERROR)                                            
      {                                                
      printf(lcd_putc,"Couldn't open file!");          
      if(f == MMC_NO_CARD_INSERTED)                            
         printf(lcd_putc,"Please, insert MMC!");                          
      else if(f == MMC_MAX_FILES_REACHED)                    
         printf(lcd_putc,"ops.. =)");                                    
   }                                                  
   else                                                          
   {        
      printf(lcd_putc,"\f"); 
      LCD_gotoxy(1,1);
      printf(lcd_putc,"START Writing"); 
   
 
      strcpy(msg,"System Start :)"); 
      fputstring(msg,f);
      LCD_gotoxy(1,2);
      printf(lcd_putc,msg);
      delay_ms(10);
      fclose(f); 
      delay_ms(1000); 
      printf(lcd_putc,"\f"); 
      LCD_gotoxy(1,1);
      printf(lcd_putc,"Writing completed");
                                      
   }           
   }                             
  }
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++


MMC_SPI_FAT32.c
// If you want to use software SPI keep this line uncommented 
// If you want to use hardware SPI comment this line.. 
// Software SPI are slower, but you can use any clock and data 
// pins that you want.. 
#define MMC_SPI_SOFTWARE 
// Change the port to whatever port you are going to use 
#use FAST_IO(C) 
// Change this to set the right tris for your pins 
#define SET_MMC_TRIS() set_tris_C(0x10) // 0b0001000 1=input,0=output 
// Change these pins to whatever pins you are using 
#define ChipSel      pin_C2 // Chip-Select pin 
#define ChipClk      pin_C3 // SPI-Clock pin 
#define ChipDout     pin_C5 // SPI-Data out pin 
#define ChipDin      pin_C4 // SPI-Data in pin 

#ifdef MMC_SPI_SOFTWARE 
   // You can also specify a baud-rate in the line below, if not the fastest possible speed will be used. 
   // For me that was 800kHz on a 18F4550 with 48MHz external clock 
   #USE SPI(MASTER, SAMPLE_RISE, MSB_FIRST, IDLE=1, DI=ChipDin, DO=ChipDout, CLK=ChipClk, BITS=8, STREAM=MMC_SPI) 
   #define MMC_Xfer(a) SPI_Xfer(MMC_SPI,a) 
#else 
   // If MMC_SPI_SOFTWARE isn't defined (se above) these variables are used, you should check if they 
   // matches your target device, but for most pic's they should do 
   #byte SSPBUF   = 0xFC9 
   #byte SSPSTAT   = 0xFC7 
   #byte SSPCON1   = 0xFC6 
   #bit  BF      = SSPSTAT.0 
#endif 

#ifdef ENABLE_FILELISTNG 
   #include <STDLIBM.H> // used for malloc and free functions 
#endif 

int32 FATTable[128]; 
int32 gFirstEmptyCluster; 

FAT32Vars gFAT32Vars; 
diskinforec DiskInfo; 
FILE gFiles[MAXFILES]; 

// Time stores the date and time, this is used when writing and/or creating files 
TimeRecord Time; 

#ifdef ENABLE_FILELISTNG 
   // Set the maximum number of files/dirs to be listed by Listfile() 
   #define MAX_FILE_LIST 10 
   // Variables used by InitList(), ListFiles(), NextPage() and SetPage() 
   ListPos StartList; 
   ListPos CurrentList; 
   BOOLEAN changeList; // Do not use this; it is only used by SetPage() and ListFiles() and Initialized by InitFAT() 
   // The result of ListFiles() function.. 
   LongFileName FileList[MAX_FILE_LIST]; 
#endif 

#byte MMCAddressL = gFAT32Vars 
#byte MMCAddressH = gFAT32Vars+1 
#byte MMCAddressHL = gFAT32Vars+2 
#byte MMCAddressHH = gFAT32Vars+3 
#byte gStartSectorL = gFAT32Vars+8 
#byte gStartSectorH = gFAT32Vars+9 
#byte gStartSectorHL = gFAT32Vars+10 

// You should check that these values matches your pic device 
// but for most devices they should be correct 
#define FSR0L      *0xFE9 
#define POSTINC0   *0xFEE 

// A bunch of error codes 
#define MMC_OK                0 
#define MMC_ERROR             0x80 
#define MMC_INVALID_FILE       0x88 
#define MMC_MAX_FILES_REACHED    0x90 
#define MMC_NO_CARD_INSERTED    0x98 
#define MMC_TIME_OUT         0xA0 
#define MMC_INVALID_RESPONSE   0xA8 
#define MMC_NOT_FOUND         0xB0 
#define MMC_INVALID_CLUSTER      0xB8 
#define MMC_END_OF_DIR         0xC0 
#define MMC_INVALID_POSITION   0xC8 

// I don't like having constants in the code... yeah, I do have some anyway ;) 
#define END_OF_DIR                  17 
#define DIRENTRYS_PER_SECTOR         16 
#define CHARACTERS_IN_LONG_FILENAMES   13 

// If you want to have a cardinserted sens-pin, define CardInserted to a input, like: 
// #define CardInserted !input(PIN_XX) 
// MMC Card have two GND pins, pull one up with a resistor (10K or somwthing like that) to Vcc 
// and connect to desired pin 
#define CardInserted() 1 

// Looks a bit nicer in the code 
#define MMC_Select()    output_low(ChipSel) 
#define MMC_Deselect()   output_high(ChipSel) 


// Below this, there should be no need to change anything 


char IsSelfDir(char *be) 
{ 
   if (be[0] == '.' && be[1] == '.') 
      return 0xFF; 
   else 
      return 0; 
} 

void MMCOut(char indata) 
{ 
  #ifdef MMC_SPI_SOFTWARE 
   MMC_Xfer(indata); 
  #else 
   char i; 
   SSPBUF=indata; 
   while (!BF); 
   i = SSPBUF; 
  #endif 
} 

void MMC8Clock() 
{ 
  #ifdef MMC_SPI_SOFTWARE 
   MMC_Xfer(0xFF); 
  #else 
   char i; 
   SSPBUF=0xFF; 
   while (!BF); 
   i = SSPBUF; 
  #endif 
} 

char MMCIn() 
{ 
  #ifdef MMC_SPI_SOFTWARE 
   return MMC_Xfer(0xFF); 
  #else 
   char i; 
   SSPBUF=0xFF; 
   while (!BF); 
   i = SSPBUF; 
   return i; 
  #endif 
} 

MMCResponse MMCInit() 
{ 
   char response,iii,errcnt; 
    

   if (!CardInserted()) 
      return MMC_NO_CARD_INSERTED; 

   SET_MMC_TRIS();  // Set input/output 
   restart_wdt(); 
   MMC_Deselect(); 

   #ifndef MMC_SPI_SOFTWARE 
      bit_clear(SSPCON1,5); // Disables serial port and configures these pins as I/O port pins 
      SSPCON1 = 0x30; // modify this number to change SPI clock rate 
                     // Enables serial port and configures SCK, SDO, SDI and SS as serial port pins 
                     // Idle state for clock is a high level 
                     // 0000 = SPI Master mode, clock = FOSC/4 

      SSPSTAT = 0;   // Only bit 6,7 are writable 
                     // 0 = Input data sampled at middle of data output time 
                     // 0 = Transmit occurs on transition from Idle to active clock state 
   #endif 

   iii = 10;
   errcnt = 100; 
   do 
   { 
      MMCOut(0xFF); 
   } while (--iii); 
   delay_us(1000); 

   MMC_Select(); // if the /CS line of the MMC is low during CMD0,(below), the card enters SPI-mode 
   MMCOut(0x40); // CMD0 
   MMCOut(0x00); 
   MMCOut(0x00); 
   MMCOut(0x00); 
   MMCOut(0x00); 
   MMCOut(0x95); // CRC 
   MMC8Clock(); 
   response = MMCIn(); 
   MMC_Deselect(); 
   do
   { 
      delay_us(1000); 
      //output_low(ChipClk); 
      MMC_Select(); 
      MMCOut(0x41); // CMD1 
      MMCOut(0x00); 
      MMCOut(0x00); 
      MMCOut(0x00); 
      MMCOut(0x00); 
      MMCOut(0x01); 
      MMC8Clock(); 
      response = MMCIn(); 
      MMC_Deselect(); 
      MMC8Clock(); 
      errcnt--; 
   } while (response && errcnt); 
   if(response == 0) 
      return MMC_OK; 
   else 
      return MMC_TIME_OUT; 
} 


// "Packed" Date: 
// +-------+------------+-------+-----+ 
// | BITS  |    15:9    |  8:5  | 4:0 | 
// | VALUE |Year – 1980 | Month | Day | 
// +-------+------------+-------+-----+ 
int16 GetCurrentDOSDate() 
{ 
   int16 retval; 

   retval = Time.Year - 1980; 
   retval <<= 9; 
   retval |= ((int16)Time.Month << 5); 
   retval |= (int16)Time.Day; 
   return retval; 
} 

// "Packed" Time: 
// +-------+-------+--------+----------+ 
// | BITS  | 15:11 |  10:5  |   4:0    | 
// | VALUE | Hour  | Minute | Second/2 | 
// +-------+-------+--------+----------+ 
int16 GetCurrentDOSTime() 
{ 
   int16 retval; 

   retval = Time.Hour; 
   retval <<= 11; 
   retval |= ((int16)Time.Minute << 5); 
   retval |= (int16)Time.Second >> 1; 
   return retval; 
} 

// Function: Reads a sector from MMC 
MMCResponse ReadSector(int32 sector, char *hova) 
{ 
   char errs,response; 
   char cnt2,cnt3; 

   #byte sectorL = sector 
   #byte sectorH = sector+1 
   #byte sectorHL = sector+2 

   if (!CardInserted()) 
      return MMC_NO_CARD_INSERTED; 
   Disable_interrupts(GLOBAL); 
   Restart_wdt(); 
   MMCAddressL = 0; 
   MMCAddressH = sectorL; 
   MMCAddressHL = sectorH; 
   MMCAddressHH = sectorHL; 
   gFAT32Vars.MMCAddress <<= 1; 

   MMC_Select(); 
   MMCOut(0x51); 
   MMCOut(MMCAddressHH); 
   MMCOut(MMCAddressHL); 
   MMCOut(MMCAddressH & 0xFE); 
   MMCOut(0); 
   MMCOut(0x01); 
   errs = 8; 
   do 
   { 
      response = MMCIn(); 
   } while (--errs && response==0xFF); 
   errs = 50; 
   do 
   { 
      response = MMCIn(); 
      if (response == 0xFE) 
         break; 
      delay_ms(1); 
   } while (--errs); 
   FSR0L = (int16)hova; // *0xFE9 
   cnt3 = 2; 
   cnt2 = 0; 
   do 
   { 
      do 
      { 
         #ifdef MMC_SPI_SOFTWARE 
            POSTINC0 = MMC_Xfer(0xFF); // *0xFEE 
         #else 
            SSPBUF=0xFF; // Writes 0xFF on SPI 
            while(!BF); // Wait until Transmitted/Received 
            POSTINC0 = SSPBUF; // Read the received byte and place it in adress oxFEE 
         #endif 
      } while (--cnt2); 
   } while (--cnt3); 
   response = MMCIn(); 
   response = MMCIn(); 
   MMC_Deselect(); 
   Enable_interrupts(GLOBAL); 
   return MMC_OK; 
} 

// Writes a sector to MMC 
MMCResponse WriteSector(int32 sector, char *honnan) 
{ 
   char errs,response; 
   char cnt2,cnt3; 
   #byte sectorL = sector 
   #byte sectorH = sector+1 
   #byte sectorHL = sector+2 

   if (!CardInserted()) 
      return MMC_NO_CARD_INSERTED; 
   Disable_interrupts(GLOBAL); 
   Restart_wdt(); 
   MMCAddressL = 0; 
   MMCAddressH = sectorL; 
   MMCAddressHL = sectorH; 
   MMCAddressHH = sectorHL; 
   gFAT32Vars.MMCAddress <<= 1; 
   response = 0; 
   //output_low(ChipClk); 
   MMC_Select(); 
   MMCOut(0x58); 
   MMCOut(MMCAddressHH); 
   MMCOut(MMCAddressHL); 
   MMCOut(MMCAddressH & 0xFE); 
   MMCOut(0); 
   MMCOut(0x01); 
   MMC8Clock(); 
   errs = 8; 
   do 
   { 
      response = MMCIn(); 
   } while (--errs && response==0xFF); 
   if (response) 
   { 
      MMC_Deselect(); 
      //output_high(ChipClk); 
      MMC8Clock(); 
      Enable_interrupts(GLOBAL); 
      return MMC_INVALID_RESPONSE; 
   } 
   MMC8Clock(); 
   MMCOut(0xFE); 
   FSR0L = (int16)honnan; // *0xFE9 
   cnt3 = 2; 
   cnt2 = 0; 
   do 
   { 
      do 
      {  

         
         #ifdef MMC_SPI_SOFTWARE 
MMC_Xfer(POSTINC0); // *0xFEE 
#else 
SSPBUF=POSTINC0; // Write the byte on address oxFEE to SPI 
while (!BF); 
dummy= SSPBUFF ; dummy read to clear status bits 
#endif
      } while (--cnt2); 
   } while (--cnt3); 
   MMCOut(0x00); 
   MMCOut(0x01); 
   response = MMCIn(); 
   response ^= 0xE5; // Bitwise exclusive or assignment operator, x^=y, is the same as x=x^y 
   if (response) 
   { 
      goto endwr3; 
   } 
   do 
   { 
      response = MMCIn(); 
   } while (response == 0); 
   response = 0; 
endwr3: 
   MMC_Deselect(); 
   //output_high(ChipClk); 
   MMC8Clock(); 
   Enable_interrupts(GLOBAL); 
   return MMC_OK; 
} 

// Function: Initializes the FAT system 
void InitFAT() 
{ 
   int32 actsector; 
   char i; 

   gFirstEmptyCluster = 0; 
   gFAT32Vars.gStartSector = 0; 
   ReadSector(gFAT32Vars.gStartSector,gFiles[MAXFILES-1].IOpuffer); 
   if (gFiles[MAXFILES-1].IOpuffer[0] != 0xEB) 
   { 
      gStartSectorL = gFiles[MAXFILES-1].IOpuffer[0x1C6]; 
      gStartSectorH = gFiles[MAXFILES-1].IOpuffer[0x1C7]; 
      gStartSectorHL = gFiles[MAXFILES-1].IOpuffer[0x1C8]; 
      ReadSector(gFAT32Vars.gStartSector,gFiles[MAXFILES-1].IOpuffer); 
   } 
   memcpy(&DiskInfo,gFiles[MAXFILES-1].IOpuffer,sizeof(DiskInfo)); 
   actsector = gFAT32Vars.gStartSector+DiskInfo.Reserved1; 
   ReadSector(actsector,FATTable); 
   gFAT32Vars.FATstartidx = 0; 
   gFAT32Vars.gFirstDataSector = gFAT32Vars.gStartSector + DiskInfo.FATCopies*DiskInfo.hSectorsPerFat+DiskInfo.Reserved1 - 2; 

   for (i=0;i<MAXFILES;i++) 
   { 
      gFiles[i].Free = TRUE; 
   } 
   #ifdef ENABLE_FILELISTNG 
      // Code for initializing file-listing 
      for(i=0;i<MAX_FILE_LIST;i++) 
         FileList[i].name = NULL; 
      changeList = TRUE; 
   #endif 
//   MMC_Debug("-FATInit "); 
} 

int32 GetNextCluster(int32 curcluster) 
{ 
   int32 actsector; 
   int32 clpage; 
   char clpos; 

   clpage = curcluster >> 7; 
   clpos = curcluster & 0x7F; 
   if (clpage != gFAT32Vars.FATstartidx) // read in the requested page 
   { 
      actsector = gFAT32Vars.gStartSector+DiskInfo.Reserved1 + clpage; 
      ReadSector(actsector,FATTable); 
      gFAT32Vars.FATstartidx = clpage; 
   } 
   return (FATTable[clpos]); 
} 

void SetClusterEntry(int32 curcluster,int32 value) 
{ 
   int32 actsector; 
   int32 clpage; 
   char clpos; 

   clpage = curcluster >> 7; 
   clpos = curcluster & 0x7F; 
   actsector = gFAT32Vars.gStartSector+DiskInfo.Reserved1 + clpage; 
   if (clpage != gFAT32Vars.FATstartidx) 
   { 
      ReadSector(actsector,FATTable); 
      gFAT32Vars.FATstartidx = clpage; 
   } 
   FATTable[clpos] = value; 
   WriteSector(actsector,FATTable); 
   actsector += DiskInfo.hSectorsPerFat; 
   WriteSector(actsector,FATTable); 
} 

void ClearClusterEntry(int32 curcluster) 
{ 
   int32 actsector; 
   int32 clpage; 
   char clpos; 

   clpage = curcluster >> 7; 
   clpos = curcluster & 0x7F; 
   if (clpage != gFAT32Vars.FATstartidx) 
   { 
      actsector = gFAT32Vars.gStartSector+DiskInfo.Reserved1 + gFAT32Vars.FATstartidx; 
      WriteSector(actsector,FATTable); 
      actsector += DiskInfo.hSectorsPerFat; 
      WriteSector(actsector,FATTable); 
      actsector = gFAT32Vars.gStartSector+DiskInfo.Reserved1 + clpage; 
      ReadSector(actsector,FATTable); 
      gFAT32Vars.FATstartidx = clpage; 
   } 
   FATTable[clpos] = 0; 
} 

int32 FindFirstFreeCluster() 
{ 
   int32 i,st,actsector,retval; 
   char j; 

   st = gFirstEmptyCluster; 
   for (i=st;i<DiskInfo.hSectorsPerFat;i++) 
   { 
      if (i != gFAT32Vars.FATstartidx) 
      { 
         actsector = gFAT32Vars.gStartSector+DiskInfo.Reserved1 + i; 
         ReadSector(actsector,FATTable); 
         gFAT32Vars.FATstartidx = gFirstEmptyCluster = i; 
      } 
      for (j=0;j<128;j++) 
      { 
         if (FATTable[j] == 0) 
         { 
            retval = i; 
            retval <<= 7; 
            retval |= j; 
            return retval; 
         } 
      } 
   } 
   return 0x0FFFFFFF; 
} 

// Function: Converts a dir-entry to a 8.3 filename 
void ConvertFilename(DIR *beDir,char *name) 
{ 
   char i,j,c; 

   j = 0; 
   name[0] = 0; 
   for (i=0;i<8;i++) 
   { 
      c = beDir->sName[i]; 
      if (c == ' ') 
         break; 
      name[j++] = c; 
   } 
   for (i=0;i<3;i++) 
   { 
      c = beDir->spam[i]; 
      if (c == ' ' || c == 0) 
         break; 
      if (!i) 
         name[j++] = '.'; 
      name[j++] = c; 
   } 
   name[j++] = 0; 
} 

// Function: Converts a dir-entry to a (part of a) long filename. 
//           One dir-entry can hold 13 unicode characters 
void ConvertLongFilename(DIR *beDir,char *name) 
{ 
   char i,j,c; 

   j = 0; 
   name[0] = 0; 
   for (i=1;i<11;i+=2) 
   { 
      c = (char)(*(((char*)beDir)+i)); 
      if (c == 0x00 || c == 0xFF) 
         break; 
      name[j++] = c; 
   } 
   if(c!=0x00 && c!= 0xFF) 
   { 
      for (i=14;i<26;i+=2) 
      { 
         c = (char)(*(((char*)beDir)+i));; 
         if (c == 0 || c == 0xFF) 
            break; 
         name[j++] = c; 
      } 
      if(c!=0x00 && c != 0xFF) 
      { 
         for (i=28;i<31;i+=2) 
         { 
            c = (char)(*(((char*)beDir)+i)); 
            if (c == 0 || c == 0xFF) 
               break; 
            name[j++] = c; 
         } 
      } 
   } 
   name[j++] = 0; 
} 

void GetDOSName(DIR *pDir, char *fname) 
{ 
   char i,j,leng,c,toext; 

   toext = FALSE; 
   j = 0; 
   leng = strlen(fname); 
   for (i=0;i<8;i++) 
      pDir->sName[i] = ' '; 
   for (i=0;i<3;i++) 
      pDir->spam[i] = ' '; 
   for (i=0;i<leng;i++) 
   { 
      c = fname[i]; 
      c = toupper(c); 
      if (c == '.') 
      { 
         toext = TRUE; 
         continue; 
      } 
      if (toext) 
         pDir->spam[j++] = c; 
      else 
         pDir->sName[i] = c; 
   } 
} 

// Function: Sets the file f to root dir 
MMCResponse ReadRootDirectory(char fil) 
{ 
   int32 actsector; 

   if (fil > (MAXFILES-1)) 
      return MMC_INVALID_FILE; 
   actsector = gFAT32Vars.gStartSector + DiskInfo.FATCopies*DiskInfo.hSectorsPerFat+DiskInfo.Reserved1; 
   ReadSector(actsector,gFiles[fil].IOpuffer); 
   gFAT32Vars.gDirEntrySector = actsector; 
   gFiles[fil].dirSector = actsector; 
   gFiles[fil].dirIdx = 0; 
   memcpy(&(gFiles[fil].DirEntry),gFiles[fil].IOpuffer,32); 
   gFiles[fil].CurrentCluster = DiskInfo.hRootStartCluster; 
   return MMC_OK; 
} 

// Funciton: Finds a file 
char FindDirEntry(char *fname,char f) 
{ 
   DIR *pDir; 
   int16 i; 
   char filename[16]; 
   int32 nextcluster,actsector; 

   if (f > (MAXFILES-1)) 
   { 
      return FALSE; 
   } 
   gFAT32Vars.gFirstEmptyDirEntry = 0xFF; 
   gFAT32Vars.gFirstDirEntryCluster = 0x0FFFFFFF; 
   do 
   { 
      pDir = (DIR*)(gFiles[f].IOpuffer); 
      for (i=0;i<DIRENTRYS_PER_SECTOR;i++) 
      { 
         if ((pDir->sName[0] == 0xE5 || pDir->sName[0] == 0) && gFAT32Vars.gFirstEmptyDirEntry == 0xFF) // store first free 
         { 
            gFAT32Vars.gFirstEmptyDirEntry = i; 
            gFAT32Vars.gFirstDirEntryCluster = gFiles[f].CurrentCluster; 
         } 
         if (pDir->sName[0] == 0) 
         { 
            return FALSE; 
         } 
         ConvertFilename(pDir,filename); 
         if (!strcmp(filename,fname)) 
         { 
            memcpy(&(gFiles[f].DirEntry),pDir,32); 
            gFiles[f].dirIdx = i; 
            gFAT32Vars.gDirEntryIdx = i; 
            return TRUE; 
         } 
         pDir++; 
      } 
      nextcluster = GetNextCluster(gFiles[f].CurrentCluster); 
      if (nextcluster != 0x0FFFFFFF && nextcluster != 0) 
      { 
         actsector = nextcluster + gFAT32Vars.gFirstDataSector; 
         ReadSector(actsector,gFiles[f].IOpuffer); 
         gFAT32Vars.gDirEntrySector = actsector; 
         gFiles[f].dirSector = actsector; 
         gFiles[f].CurrentCluster = nextcluster; 
      } 
   } while (nextcluster != 0x0FFFFFFF && nextcluster != 0); 
   return FALSE; 
} 

// Function: Assign a filenumber(f) and open the directory 
//           where the file are and return the filename. 
char* TryFile(char *fname, char *f) 
{ 
   char i,leng; 
   char *filename; 

   *f = 0xFF; 
   for (i=0;i<MAXFILES;i++) 
   { 
      if (gFiles[i].Free) 
      { 
         *f = i; 
         break; 
      } 
   } 
   if (*f == 0xFF) 
   { 
      return 0; 
   } 
   ReadRootDirectory(*f); 
   filename = fname; 
   leng = strlen(fname); 
   for (i=0;i<leng;i++) 
   { 
      if (fname[i] == '/') 
      { 
         fname[i] = 0; 
         if (!cwd(filename,*f)) 
         { 
            gFiles[*f].Free = TRUE; 
            return 0; 
         } 
         filename = fname+i+1; 
      } 
   } 
   return filename; 
} 

void strfill(char *dest,char *source,int position) 
{ 
   char *d; 
   for(d=dest+position; *source!=0; d++, source++) 
   { 
      *d = *source; 
   } 
} 

// Parameters: path, the path to the directory you 
//             want to view 
// Function    : Initializes file/dir listing 
// Examples: 
// strcpy(path,""); // the "path" to the root directory 
// f = InitList(path); 
// ... 
// strcpy(path,"DIR3/DIR32/"); 
// f = InitList(path); 
// if(InitList == MMC_OK) 
// { 
//   res = Listfiles(f); 
//   CloseList(f); 
// } 
#ifdef ENABLE_FILELISTNG 
MMCResponse InitList(char *path) 
{ 
   char f; 
   if(TryFile(path,&f) == 0) 
   { 
      return MMC_NOT_FOUND; 
   } 
   gFiles[f].Free = FALSE;    
   StartList.dirSector = gFiles[f].dirSector; 
   StartList.CurrentCluster = gFiles[f].CurrentCluster; 
   StartList.dirIdx = 0; 
   CurrentList.dirSector = gFiles[f].dirSector; 
   CurrentList.CurrentCluster = gFiles[f].CurrentCluster; 
   CurrentList.dirIdx = 0; 
   return f; 
} 

// Function: Lists a part (aka page) of the files in the directory 
//           specified by InitList() 
// Returns : The number of files/dirs that were listed 
int8 ListFiles(char f) 
{ 
   DIR *pDir; 
   char filename[(CHARACTERS_IN_LONG_FILENAMES+1)]; // should be enough with 13+1 
   char i,u,fni,len; 
   BOOLEAN isLongFileName = FALSE; 
   int32 nextcluster,actsector; 

   if (f > (MAXFILES-1)) 
      return 0; 

   if(changeList) 
   { 
      FreeList(); 
   } 

   if((gFiles[f].CurrentCluster != CurrentList.CurrentCluster) || (gFiles[f].dirSector != CurrentList.dirSector)) 
   { 
      gFiles[f].dirSector = CurrentList.dirSector; 
      gFiles[f].CurrentCluster = CurrentList.CurrentCluster;    
      ReadSector(gFiles[f].dirSector,gFiles[f].IOpuffer); 
   } 
   gFiles[f].dirIdx = CurrentList.dirIdx; 


   u=0; 
   do 
   { 
      pDir = (DIR*)(&(gFiles[f].IOpuffer[32*(int16)gFiles[f].dirIdx])); 
      for (i=gFiles[f].dirIdx;i<DIRENTRYS_PER_SECTOR;i++) // loop throu all direntrys in the sector 
      { 
         if ((pDir->sName[0] != 0xE5 && pDir->sName[0] != 0)) // if file/dir isn't deleted and isn't the end of the directory 
         { 
            if(pDir->bAttr != 0x0F) // Normal filename (8.3) 
            { 
               if(isLongFilename) // If this is the short version of the long filename, just save the number 
               { 
                  if(changeList) 
                  { 
                     FileList[u].shortName = malloc(13); // 8.3 = 8chars + '.' + 3chars + 0x00 
                     FileList[u].isLong = TRUE; 
                     ConvertFilename(pDir,filename); 
                     strcpy(FileList[u].shortName,filename); // copy the 8.3 name of the file 
                  } 
                  u++; 
                  isLongFilename = FALSE; 
                  if(u == MAX_FILE_LIST) 
                  { 
                     gFiles[f].dirIdx = i+1; 
                     return u; 
                  } 
               } 
               else // normal 8.3 filename 
               { 
                  if(changeList) 
                  { 
                     ConvertFilename(pDir,filename); 
                     FileList[u].name = malloc(strlen(filename)+1); // +1 for char 0x00 
                     strcpy(FileList[u].name,filename); 
                     FileList[u].shortName = FileList[u].name; // point to same string 
                     FileList[u].isLong = FALSE; 
                     if(pDir->bAttr & 0x10) // is directory 
                        FileList[u].isDir = TRUE; 
                     else 
                        FileList[u].isDir = FALSE; 
                  } 

                  u++; 
                  if(u == MAX_FILE_LIST) 
                  { 
                     gFiles[f].dirIdx = i+1; 
                     return u; 
                  } 
               } 
            } 
            else if((pDir->bAttr & 0x0F) == 0x0F) // If it is a long filename entry 
            { 
               fni = (pDir->sName[0] & 0x3F); // Filename Index 
               if((pDir->sName[0] & 0x40)) // First LongFilename entry, the last characters of a long filename 
               { 
                  if(changeList) 
                  { 
                     ConvertLongFilename(pDir,filename); 
                     len = strlen(filename)+CHARACTERS_IN_LONG_FILENAMES*(fni-1); // Length of the long filename 
                     FileList[u].name = malloc(len+1);// number of chars in this strinng + 13 in each other long filname entry 
                     FileList[u].name[len] = 0x00; // set last char to 0 
                     strfill(FileList[u].name,filename,(fni-1)*CHARACTERS_IN_LONG_FILENAMES); //Fills the name from position (fni-1)*13
                     if(pDir->bAttr & 0x10) // is directory 
                        FileList[u].isDir = TRUE; 
                     else 
                        FileList[u].isDir = FALSE; 
                  } 
                  isLongFilename = TRUE; 
               } 
               else if((pDir->sName[0] & 0x80) == 0) // If it is a long filname, but not deleted 
               { 
                  if(isLongfilename && changeList) 
                  { 
                     ConvertLongFilename(pDir,filename); 
                     strfill(FileList[u].name,filename,(fni-1)*CHARACTERS_IN_LONG_FILENAMES); //Fills the name from position (fni-1)*13
                  } 
                  else 
                     printf(lcd_putc,"NoLongFileName!"); 
               } 
            } 
         } 
         if (pDir->sName[0] == 0) 
         { 
            gFiles[f].dirIdx = END_OF_DIR; 
            return u; 
         } 
         pDir++; 
      } 
      nextcluster = GetNextCluster(gFiles[f].CurrentCluster); 
      if (nextcluster != 0x0FFFFFFF && nextcluster != 0) 
      { 
         actsector = nextcluster + gFAT32Vars.gFirstDataSector; 
         ReadSector(actsector,gFiles[f].IOpuffer); 
         gFiles[f].dirSector = actsector; 
         gFiles[f].CurrentCluster = nextcluster; 
         gFiles[f].dirIdx = 0; 
      } 
   } while (nextcluster != 0x0FFFFFFF && nextcluster != 0); 
   gFiles[f].dirIdx = END_OF_DIR; 
   return u; 
} 

// Function: Go to next page in the file/dir list 
// Returns : MMCResponse 
MMCResponse NextPage(char f) 
{ 
   int32 nextcluster,actsector; 
   if (f > (MAXFILES-1)) 
      return MMC_INVALID_FILE; 

   CurrentList.dirSector = gFiles[f].dirSector; 
   CurrentList.CurrentCluster = gFiles[f].CurrentCluster; 

   if(gFiles[f].dirIdx == DIRENTRYS_PER_SECTOR) 
   { 
      nextcluster = GetNextCluster(gFiles[f].CurrentCluster); 
       if (nextcluster != 0x0FFFFFFF && nextcluster != 0) 
      { 
         actsector = nextcluster + gFAT32Vars.gFirstDataSector; 
         ReadSector(actsector,gFiles[f].IOpuffer); 

         CurrentList.dirSector = actsector; 
         CurrentList.CurrentCluster = nextcluster; 
         CurrentList.dirIdx = 0; 
         return MMC_OK; 
       } 
      return MMC_INVALID_CLUSTER; 
   } 
   else if(gFiles[f].dirIdx == END_OF_DIR) 
   { 
      return MMC_END_OF_DIR; // Last file/dir have already been listed by ListFiles 
   } 
   else 
   { 
      CurrentList.dirIdx = gFiles[f].dirIdx; 
   } 
   return MMC_OK; 
} 

// Note: 0 = first page 
MMCResponse SetPage(char f, int32 page) 
{ 
   int32 i; 
   MMCResponse res; 
   if (f > (MAXFILES-1)) 
      return MMC_INVALID_FILE; 

   CurrentList.dirSector = StartList.dirSector; 
   CurrentList.CurrentCluster = StartList.CurrentCluster; 
   CurrentList.dirIdx = StartList.dirIdx; // should always be 0 

   changeList = FALSE; // this tells the ListFiles function to not change the list, just loop through files 
   for(i=0;i<page;i++) 
   { 
      ListFiles(f); 
      res = NextPage(f); 
      if(res != MMC_OK) 
      { 
         changeList = TRUE; 
         return res; 
      } 
   } 
   changeList = TRUE; 
   return MMC_OK; 
} 

MMCResponse CloseList(char f) 
{ 
   if (f > (MAXFILES-1)) 
      return MMC_INVALID_FILE; 
   gFiles[f].Free = TRUE; 
   return MMC_OK; 
} 

void FreeList() 
{ 
   int i; 
   for(i=0;i<MAX_FILE_LIST;i++) 
   { 
      if(FileList[i].isLong)           // If it is a long filename, name and short name are different string 
         free(FileList[i].shortName); // then free both 
      else 
         FileList[i].shortName = NULL; 
      free(FileList[i].name);          // else free ONLY name(they point to same string..) 
   } 
} 
#endif// ENABLE_FILELISTNG 

// Function: Creates a file 
MMCResponse fcreate(char f,char *fname) 
{ 
   DIR *pDir; 
   int32 actsector,actcl; 
   int16 i; 

   if (f > (MAXFILES-1)) 
   { 
      return MMC_INVALID_FILE; 
   } 
   if (gFAT32Vars.gFirstDirEntryCluster == 0x0FFFFFFF) 
   { 
      // extend the directory file !!! 
      gFAT32Vars.gFirstDirEntryCluster = FindFirstFreeCluster(); 
      gFAT32Vars.gFirstEmptyDirEntry = 0; 
      SetClusterEntry(gFiles[f].CurrentCluster,gFAT32Vars.gFirstDirEntryCluster); 
      SetClusterEntry(gFAT32Vars.gFirstDirEntryCluster,0x0FFFFFFF); 
      actsector = gFAT32Vars.gFirstDirEntryCluster + gFAT32Vars.gFirstDataSector; 
      for (i=0;i<512;i++) 
         gFiles[f].IOpuffer[i] = 0; 
      WriteSector(actsector,gFiles[f].IOpuffer); 
   } 
   actsector = gFAT32Vars.gFirstDirEntryCluster + gFAT32Vars.gFirstDataSector; 
   ReadSector(actsector,gFiles[f].IOpuffer); 
   pDir = (DIR*)(&(gFiles[f].IOpuffer[32*(int16)gFAT32Vars.gFirstEmptyDirEntry])); 
   gFiles[f].dirSector = actsector; 
   gFiles[f].dirIdx = gFAT32Vars.gFirstEmptyDirEntry; 
   GetDOSName(pDir,fname); 
   pDir->bAttr = 0; 
   actcl = FindFirstFreeCluster(); 
   pDir->hCluster = actcl & 0xFFFF; 
   pDir->hClusterH = actcl >> 16; 
   SetClusterEntry(actcl,0x0FFFFFFF); 
   pDir->wSize = 0; 
   gFiles[f].position = 0; 
   pDir->hDate = GetCurrentDOSDate(); 
   pDir->hTime = GetCurrentDOSTime(); 
   WriteSector(actsector,gFiles[f].IOpuffer); 
   memcpy(&(gFiles[f].DirEntry),pDir,32); 
   return MMC_OK; 
} 

int32 ComposeCluster(char f) 
{ 
   int32 retval; 

   retval = gFiles[f].DirEntry.hClusterH; 
   retval <<= 16; 
   retval |= gFiles[f].DirEntry.hCluster; 
   return retval; 
} 

// Function: Opens a file with the specified mode 
// Returns : A file handle or error code 
MMCResponse fopen(char *fname, char mode) 
{ 
   char found; 
   char f; 
   int32 actsector,actcluster,nextcluster; 
   char *filename; 

   if (!CardInserted()) 
      return MMC_NO_CARD_INSERTED; 

   filename = TryFile(fname,&f); 
   if (filename == 0) 
   { 
      return MMC_NOT_FOUND; // probebly invalid directory 
   } 
   found = FALSE; 
   found = FindDirEntry(filename,f); 

   if (!found) 
   { 
      if (mode == 'r') 
      { 
         gFiles[f].Free = TRUE; 
         return MMC_NOT_FOUND; 
      } 
      else 
      { 
         if (fcreate(f,filename) != MMC_OK) 
            return MMC_NOT_FOUND; 
         found = TRUE; 
      } 
   } 
   if (found) 
   { 
      gFiles[f].Free = FALSE; 
      gFiles[f].mode = mode; 
      if  (mode == 'a') 
      { 
         gFiles[f].position = gFiles[f].DirEntry.wSize; 
         actcluster = ComposeCluster(f); 
         while (actcluster != 0x0FFFFFFF && nextcluster != 0) 
         { 
            nextcluster = GetNextCluster(actcluster); 
            if (nextcluster == 0x0FFFFFFF || nextcluster == 0) 
               break; 
            actcluster = nextcluster; 
         } 
         actsector = actcluster + gFAT32Vars.gFirstDataSector; 
         ReadSector(actsector,gFiles[f].IOpuffer); 
         gFiles[f].CurrentCluster = actcluster; 
         gFiles[f].posinsector = gFiles[f].position & 0x01FF; 
         if (gFiles[f].posinsector == 0 && gFiles[f].position != 0) 
            gFiles[f].posinsector = 512; 
      } 
      else 
      { 
         gFiles[f].position = 0; 
         actsector = ComposeCluster(f); 
         actsector += gFAT32Vars.gFirstDataSector; 
         ReadSector(actsector,gFiles[f].IOpuffer); 
         gFiles[f].CurrentCluster = ComposeCluster(f); 
         gFiles[f].posinsector = 0; 
      } 
   } 
   return f; 
} 

// Function: closes a open file and makes it avavible for a new file 
MMCResponse fclose(char f) 
{ 
   if (f > (MAXFILES-1)) 
      return MMC_INVALID_FILE; 
   if ((gFiles[f].mode == 'a') || (gFiles[f].mode == 'w')) 
      fflush(f); 
   gFiles[f].Free = TRUE; 
   return MMC_OK; 
} 

// Function: writes the chach to the MMC 
MMCResponse fflush(char f) 
{ 
   int32 actsector; 
   DIR *pDir; 

   if (f > (MAXFILES-1)) 
      return MMC_INVALID_FILE; 
   actsector = gFiles[f].CurrentCluster + gFAT32Vars.gFirstDataSector; 
   WriteSector(actsector,gFiles[f].IOpuffer); 
   ReadSector(gFiles[f].dirSector,gFiles[f].IOpuffer); 
   pDir = (DIR*)(&(gFiles[f].IOpuffer[32*gFiles[f].dirIdx])); 
   if (gFiles[f].DirEntry.bAttr & 0x10)  // if it is a directory 
      pDir->wSize = 0; 
   else 
      pDir->wSize = gFiles[f].position; 
   pDir->hDate = GetCurrentDOSDate(); 
   pDir->hTime = GetCurrentDOSTime(); 
   WriteSector(gFiles[f].dirSector,gFiles[f].IOpuffer); 
   ReadSector(actsector,gFiles[f].IOpuffer); 
   return MMC_OK; 
} 

// Function: Enter a specified directory 
char cwd(char *fname, char f) 
{ 
   int32 actsector; 
   if (f > (MAXFILES-1)) 
   { 
      return FALSE; // just in case of overaddressing 
   } 
   if (IsSelfDir(fname)) 
   { 
      return TRUE; // already in Root dir 
   } 
   if (!FindDirEntry(fname,f)) 
   { 
      return FALSE; // not found 
   } 

   actsector = ComposeCluster(f); 
   actsector += gFAT32Vars.gFirstDataSector; // read current dir 
   ReadSector(actsector,gFiles[f].IOpuffer); 
   gFAT32Vars.gDirEntrySector = actsector; 
   gFiles[f].dirSector = actsector; 
   gFiles[f].CurrentCluster = ComposeCluster(f); 

   return TRUE; 
} 

// Function: Put a char to the open file 
MMCResponse fputch(char be, char f) 
{ 
   int32 nextcluster,actsector; 

   if (f > (MAXFILES-1)) 
      return MMC_INVALID_FILE; 
   if (gFiles[f].posinsector == 512) 
   { 
      actsector = gFiles[f].CurrentCluster + gFAT32Vars.gFirstDataSector; 
      WriteSector(actsector,gFiles[f].IOpuffer); 
      nextcluster = FindFirstFreeCluster(); 
      if (nextcluster != 0x0FFFFFFF && nextcluster != 0) 
      { 
         SetClusterEntry(gFiles[f].CurrentCluster,nextcluster); 
         SetClusterEntry(nextcluster,0x0FFFFFFF); 
         actsector = nextcluster + gFAT32Vars.gFirstDataSector; 
         ReadSector(actsector,gFiles[f].IOpuffer); 
         gFiles[f].CurrentCluster = nextcluster; 
         gFiles[f].posinsector = 0; 
      } 
   } 
   gFiles[f].IOpuffer[gFiles[f].posinsector] = be; 
   gFiles[f].posinsector++; 
   gFiles[f].position++; 
   return MMC_OK; 
} 

// Function: Puts a string to the open file 
MMCResponse fputstring(char *be, char f) 
{ 
   int16 leng,i; 

   if (f > (MAXFILES-1)) 
      return MMC_INVALID_FILE; 
   leng = strlen(be); 
   for (i=0;i<leng;i++) 
      fputch(be[i],f); 
   return MMC_OK; 
} 

// Function: Read a buffer from the open file 
int16 fread(char *buffer, int16 leng, char f) 
{ 
   int16 i,retv; 
   char c,v; 

   if (f > (MAXFILES-1)) 
      return 0; 
   retv = 0; 
   for (i=0;i<leng;i++) 
   { 
      v = fgetch(&c,f); 
      if (v == MMC_OK) 
      { 
         buffer[i] = c; 
         retv++; 
      } 
      else 
         break; 
   } 
   return retv; 
} 

// Function: Write a buffer to the open file 
MMCResponse fwrite(char *buffer, int16 leng, char f) 
{ 
   int16 i; 

   if (f > (MAXFILES-1)) 
      return MMC_INVALID_FILE; 
   for (i=0;i<leng;i++) 
      fputch(buffer[i],f); 
   return MMC_OK; 
} 

// Function: Read a char from the open file 
MMCResponse fgetch(char *ki,char f) 
{ 
   int32 nextcluster,actsector; 

   if (f > (MAXFILES-1)) 
      return MMC_INVALID_FILE; 
   if (gFiles[f].position >= gFiles[f].DirEntry.wSize) 
      return MMC_INVALID_POSITION; 
   *ki = gFiles[f].IOpuffer[gFiles[f].posinsector]; 
   gFiles[f].posinsector++; 
   gFiles[f].position++; 
   if (gFiles[f].posinsector == 512) 
   { 
      nextcluster = GetNextCluster(gFiles[f].CurrentCluster); 
      if (nextcluster != 0x0FFFFFFF && nextcluster != 0) 
      { 
         actsector = nextcluster + gFAT32Vars.gFirstDataSector; 
         ReadSector(actsector,gFiles[f].IOpuffer); 
         gFiles[f].CurrentCluster = nextcluster; 
         gFiles[f].posinsector = 0; 
      } 
   } 
   return MMC_OK; 
} 

// Function: Removes a file 
MMCResponse remove(char *fname) 
{ 
   char i,found; 
   char f; 
   DIR *pDir; 
   int32 nextcluster,currentcluster; 
   char *filename; 

   filename = TryFile(fname,&f); 
   if (filename == 0) 
      return MMC_NOT_FOUND; 
   found = FindDirEntry(filename,f); 
   if (!found) 
   { 
      gFiles[f].Free = TRUE; 
      return MMC_NOT_FOUND; 
   } 

   pDir = (DIR*)(&(gFiles[f].IOpuffer[32*(int16)gFAT32Vars.gDirEntryIdx])); 
   pDir->sName[0] = 0xE5; 
   for (i=1;i<8;i++) 
      pDir->sName[i] = ' '; 
   for (i=0;i<3;i++) 
      pDir->spam[i] = ' '; 
   WriteSector(gFAT32Vars.gDirEntrySector,gFiles[f].IOpuffer); 
   currentcluster = ComposeCluster(f); 
   while (currentcluster != 0x0FFFFFFF && nextcluster != 0) 
   { 
      nextcluster = GetNextCluster(currentcluster); 
      ClearClusterEntry(currentcluster); 
      currentcluster = nextcluster; 
   } 
   ClearClusterEntry(currentcluster); 
   SetClusterEntry(currentcluster,0); 
   currentcluster = gFAT32Vars.gStartSector+DiskInfo.Reserved1 + gFAT32Vars.FATstartidx; 
   WriteSector(currentcluster,FATTable); 
   currentcluster += DiskInfo.hSectorsPerFat; 
   WriteSector(currentcluster,FATTable); 
   gFiles[f].Free = TRUE; 

   return MMC_OK; 
} 


// Function: Gets the size of a file 
MMCResponse getfsize(char *fname, int32 *fsiz) 
{ 
   char found; 
   char f; 
   DIR *pDir; 
   char *filename; 

   filename = TryFile(fname,&f); 
   if (filename == 0) 
      return MMC_NOT_FOUND; 
   found = FindDirEntry(filename,f); 
   if (!found) 
   { 
      gFiles[f].Free = TRUE; 
      return MMC_NOT_FOUND; 
   } 
   pDir = (DIR*)(&(gFiles[f].IOpuffer[32*(Int16)gFAT32Vars.gDirEntryIdx])); 
   gFiles[f].Free = TRUE; 
   *fsiz = pDir->wSize; 
   return MMC_OK; 
}

MMC_SPI_FAT32.h
[code]
#define MAXFILES 1 // This define specifies the maximum number
               // of simultaneously open files, more files
               // requires more ram. The maximun number of
               // this define is 8, this is because of my
               // error handlig.. but that should be more
               // then enough..

// This enable functions and variables needed for filelisting
// If you aren't going to use it, comment this line out to
// save some RAM
#define ENABLE_FILELISTNG

typedef struct _diskinforec
{
   char   hJumpCode[3];
   char  OEMName[8];
   int16   hBytesPerSector;
   char   bSectorsPerCluster;
   int16 Reserved1;
   char   FATCopies;
   int16 hMaxRootEntries;
   int16 hSectors;
   char   Descriptor;
   int16 holdSectorsPerFat;
   int16 hSectorsPerTrack;
   int16 hNumberofHeads;
   int32   hNumberofHidden;
   int32   hNumberofSectors;

   int32 hSectorsPerFat;
   int16 hFlags;
   int16 hFAT32Version;
   int32 hRootStartCluster;
} diskinforec;

typedef struct _direntry
{
   char   sName[8];
   char   spam[3];
   char   bAttr;
   char   bReserved[8];
      int16 hClusterH;
   int16   hTime;
   int16   hDate;
   int16   hCluster;
   int32   wSize;
} DIR;

typedef struct
{
   char    IOpuffer[512];
   DIR    DirEntry;
   int32 CurrentCluster;
   int16 posinsector;
   int32   position;
   int32 dirSector;
   int8   dirIdx;
   char   mode;
   BOOLEAN   Free;
} FILE;

typedef struct
{
   int32 MMCAddress;
   int32 FATstartidx;
   int32 gStartSector;
   int32 gFirstDataSector;
   int8 gDirEntryIdx;
   int32 gDirEntrySector;
   int8 gFirstEmptyDirEntry;
   int32 gFirstDirEntryCluster;
} FAT32Vars;

typedef struct
{
   unsigned long   Year;
   char         Month;
   char            Day;   
   char            Hour;   
   char            Minute;     
   char            Second;     
} TimeRecord;

typedef struct
{
   int32 dirSector;
   int32 CurrentCluster;
   int dirIdx;
} ListPos;

typedef struct
{
   char *name;
   char *shortName;
   BOOLEAN isDir;
   BOOLEAN isLong;
} LongFileName;

typedef char MMCResponse;

MMCResponse MMCInit();
MMCResponse ReadSector(int32 sector, char *hova);
MMCResponse WriteSector(int32 sector, char *honnan);

void      InitFAT();
char      FindDirEntry(char *fname, char f);

#ifdef ENABLE_FILELISTNG
   MMCResponse InitList(char *path);
   int8      ListFiles(char f);
   MMCResponse NextPage(char f);
   MMCResponse SetPage(char f, int32 page);
   MMCResponse CloseList(char f);
   void      FreeList();
#endif

MMCResponse fopen(char *fname, char mode);
MMCResponse fclose(char f);
MMCResponse fflush(char f);
char      cwd(char *fname, char f);
MMCResponse fputch(char be, char f);
MMCResponse

KONYALI

sanırım CCS C ile yazılmış hazır bir kütüphaneyi kullanıyorsunuz. Bende proje ödevim için aynı kütüphaneyi kullandım ancak dah sonra çok problem oldu farklı marka kart e farklı boyutlarda sorun oluyordu. Bende çözümü swordfish basic derleyicisinin hazır kütüphanesini kullanmakta buldum. Eğer yeterli vaktiniz varsa basicle 1-2 günde çözersiniz tavsiye ederim

Kolay gelsin

Mucit23

Swordfish basic ilk defa duydum. Galiba protona benziyor.Kullanımı kolaymıdır.

KONYALI

@Mucit23
Hocam bende 1 ay kadar önce duydum, kullandım ve çok memnun kaldım. Epeydir CCS C kullanıyordum öncesinde PicBasic de kullandım ama projede SD kart kullanma kısmında Swordfish Basic ilaç gibi geldi. 2 aya yakın SD kart iletişimi için CCS C de denemediğim şey kalmadı ama hiç birisinden verim alamadım.

Boş vakitlerimde manueline göz atıyorum PicBasic le benzer yönleri var ama baya geliştirmişler. Kod optimizasyonu PicBasic e göre çok üstün hatta Sd kart kütüphanesi için konuşursak CCS C'den de üstün.

Şiddetle tavsiye ederim :)


Mucit23

Bazen benimde datalogger benzeri uygulamalar için sd kart çok ihtiyacım oluyor. Kesinlikle araştıracam. Eninde sonunda Cye geçmek zorunda kalıcam ama şimdilik 8 bitlik denetleyiciler için basic ile idare ediyorum. Kullanmak için sadece programı kurmak yeterli geliyormu yoksa başka ayarlarda yapılması gerekiyormu.

KONYALI

forumda ilaçlı download linki var zaten hocam indirin kurun proton, Picbasic vs kullandıysanız zorlanmassınız kullanımı kolay özel bir ayar vs yapmanıza gerek yok

http://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.Plugins

bu adresten plugin leri indirebilir örneklerden faydalanabilirsiniz

Mucit23

Şimdi yükledim hepsini
Yanlız baktımda kendi sample klasörü yok. Acaba örnek uygulamaları nereden indirebilirim.

thenorthstar

ccs yapmam gerekiyor kardeş ya , çünkü ccs de modbus kısmınıda yaptığım için bunuda eklemem egerekiyor. bunu ccs te nasıl çzebilirim.

KONYALI

@Mucit23
Kendi sample klasörü var hocam yanlış yere bakıyor olabilirsiniz. Bi önceki mesajımda belirttiğim siteden örnekleri pluginleri ve modülleri indirebilirsiniz

@thenorthstar
kardeş CCS C forumunda örneklerden yararlanmıştım ben sanırım sende ordan buldun kütüphneyi. Kullandığın kütüphane zaten CCS C hakkında bulabileceğin en en düzgün kod.  msg değişkenine strcpy komutu ile belirlediğin stringi kopyalamışsın msg değişkenine başlangıçta aynı stringi direk atayıp denedin mi bazen böyle hatalar olabiliyor. Birde değişkene başlangıçta sabit ifade atayıp dene

thenorthstar

Denedim olmadı kardeş ya
yine olmadı
char msg[20] ="MMC Yazma Denemesi"; bu şekilde denedim
seri porttan msg yi gönderdim MMC Yazma Denemesi bu yazıyı aldım fakat mmc içerisine MeMiCe  YDasz m a bunu yazdı :(
#include <18F4620.h>
#include <string.h> 
#include <MMC_SPI_FAT32.h> 


#fuses HS,NOWDT,NOPROTECT,BROWNOUT,NOLVP,NOCPD 
#use delay(clock=10000000)    
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8) 
#include "2x16_4x20_LCD.c" 
#include "MMC_SPI_FAT32.c" 

void main(){
    delay_ms(1000);
   char f,gfilename[12]; 
   char msg[100]; 
   lcd_init(); 
   LCD_gotoxy(1,1);
   printf(lcd_putc,"MMC CONTROL");
   printf("\r\nMMC CONTROL\r\n");
   
  if(MMCInit() == MMC_OK)  {
    LCD_gotoxy(1,1);
    printf(lcd_putc,"MMC init OK");
    printf("MMC init OK\r\n");
      delay_ms(2000); 
    
    InitFAT();
   
     LCD_gotoxy(1,2);
      printf(lcd_putc,"FAT init OK");
      printf("FAT init OK\r\n"); 
      printf("Dosya Oluşturuluyor\r\n"); 
      delay_ms(2000); 
      printf(lcd_putc,"\f");  
      strcpy(gfilename,"Deneme.txt");
      f = fopen(gfilename,'a'); // open EVENTS.LOG for append      
      printf("Deneme.txt  Oluşturuldu\r\n");
      delay_ms(2000);
     
     if (f & MMC_ERROR)
      {                                                
      printf(lcd_putc,"Couldn't open file!");          
      if(f == MMC_NO_CARD_INSERTED)                            
         printf(lcd_putc,"Please, insert MMC!");                          
      else if(f == MMC_MAX_FILES_REACHED)                    
         printf(lcd_putc,"ops.. =)");                                    
      }                                                  
   else                                                          
   {        
      printf(lcd_putc,"\f"); 
      LCD_gotoxy(1,1);
      printf(lcd_putc,"Yazma Basladı"); 
      printf("Yazma Basladı\r\n"); 
      delay_ms(1000);
      strcpy(msg,"MMC Yazma Denemesi"); 
      fputstring(msg,f);
      printf("Yazılan Veri=%d",msg);
      delay_ms(100);
      fclose(f);
      delay_ms(100);
      printf(lcd_putc,"\f"); 
      LCD_gotoxy(1,1);
      printf(lcd_putc,"Writing completed");
      delay_ms(100);
      printf("Yazma Tamamlandı\r\n");

      }
   }
                                
  
} 
//+++++++++++++++++++++++++++++++++++++++++++++++++++


thenorthstar

Arkadaşlar bu konuda fikri olan yokmu? :-[

rree

MMC ile  çalıçma Proton da problem yaşamıştım.  Mikrobasic düzgün çalışmıştı. Yazdığın programda bir hata göremedim.Başka c dillerinde mmc desteği varsa Ccs yi döndürülemezmi yakında  benim de ihtiyacım olacak.

thenorthstar

Arkadaşlar yaptığım denemelerde şu sorunla karşılaşıyorum.
printf(lcd_putc,"\f"); 
      LCD_gotoxy(1,1); 
      printf(lcd_putc,"Writing Began"); 
      printf("Writing Began\r\n"); 

      strcpy(msg,"Hello World"); 
      fputstring(msg,f); 

      printf("Written data=%s",msg); 
      fclose(f); 
      delay_ms(100);

yazdırmaya çalıştığım data bu Hello World bu datayı aynı zamanda seri porta da gönderiyorum
printf("Written data=%s",msg);
fakat SD cart içine yazılan veri hatalı çıkıyor bir türlü doğru veri yazdıramadım.
Oluşturulan dosya ve içindeki data aşağıda


Seri port dan aldığım veri aşağıda

SD kartı  winhex ile açtığımda SD kart içi Aşağıdaki  gibi gözüküyor.Üsteki winhex resmi SD kart içini gösteriyor, Alttaki winhex resmide SAMPLE.txt dosyasının içini gösteriyor.



Aşağıdaki resimde SD kartı her ayırma biriminde 512 bayt olacak şekilde formatladım

gkimirti

sanki dosyaya yazarken kütüphane her byte için 2 byte kullanıyor, utf destegi icin boyle bir şey olabilir mi?
belki global bir ayar degiskeni vardır. kütüphane dosyalarının başlık kısmındaki açıklamalara bir göz atmak lazım

thenorthstar

Arkadaşlar ne yaptım ise olmadı, sağlam bir kütüphane bulamadım. ccs de MMC ile ilgilenen ve çalıştıran yokmu?