⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmc_spi_fat32.c

📁 MMC_SPI_FAT32 一个国外网友编写的程序
💻 C
📖 第 1 页 / 共 4 页
字号:
//////////////////////////////////////////////////////////////////////// 
/////////////////// FAT32 DRIVER FOR MMC OVER SPI ////////////////////// 
//////////////////////////////////////////////////////////////////////// 
//// Original code by Tamas Bodorics (Tomi),                        //// 
//// http://www.ccsinfo.com/forum/viewtopic.php?t=23969             //// 
//// Modified by Mattias "miniman" Eriksson, Sweden                 //// 
//// Disclaimer:                                                    //// 
//// This code is provided for you "AS IS", this means I can NOT be //// 
//// held responsible for any damage or harm it may couse.          //// 
//////////////////////////////////////////////////////////////////////// 
//// Hardware:                                                      //// 
////   This is the hardware I use. My pic is running at 5v, the MMC //// 
////   at 3.3V, so I need voltage level conversion. That is what    //// 
////   the resistors and zener diodes are for. First a 820 ohm      //// 
////   resistor from is connected to the pic, then a 3.3V           //// 
////   zenerdiode is connected with its anode to ground and its     //// 
////   cathode to the resistor. This resistor-zenerdiode connection //// 
////   leaves about 3V on the DATA/CS/CLOCK lines which is enough.  //// 
////   A 100K pull-up resistor from Data out(Do) of the MMC is      //// 
////   required. Note: this "picture" do not have the right pin     //// 
////   assignments. Hope you can see what I'm trying to paint..     //// 
////                                                                //// 
////    __ __  3x820 ohm                       ______________       //// 
////   |  U  |--\/\/\----------- o---DATA->---|=2            |      //// 
////   | PIC |--\/\/\-------o----+---CS--->---|=1            |      //// 
////   |     |--\/\/\--o----+----+---CLOCK>---|=5    MMC     |      //// 
////   |     |        _|_, _|_, _|_,       o--|=7            |      //// 
////   |     |       '/_\ '/_\ '/_\        |   \_____________|      //// 
////   |     |     GND_|____|____|_GND     | 100k ohm               //// 
////   |_____|-----------<-DATA-<----------o--\/\/\---<3.3V         //// 
////                                                                //// 
//// Notes:                                                         //// 
//// - The card that is going to be used by this code has to be     //// 
////   pre-formated with FAT32, 512byte/sector. To do this, run cmd //// 
////   and type the following command:                              //// 
////   format X: /A:512 /V:LABEL /FS:FAT32                          //// 
////   where X is the diverletter of your card and LABEL is the     //// 
////   volyme name. This can also be done in the diskmanager        //// 
//// - Use '/' as directory separator, example: "MYDIR/ELEMENT.WND" //// 
////   "MYDIR/SUBDIR/OTHER.TXT" etc.                                //// 
////                                                                //// 
//// Functions:                                                     //// 
////   MMCInit()                                                    //// 
////      Initializes the MMC, this function must be called before  //// 
////      any other MMC functions, and at the top of the program.   //// 
////      Returns a MMCResponse.                                    //// 
////   InitFAT()                                                    //// 
////      Initializes the FAT filesystem, this function must be     //// 
////      called before any other MMC functions and after MMCInit,  //// 
////      only if the later one returned MMC_OK.                    //// 
////      Returns a MMCResponse.                                    //// 
////   InitList(char *path)                                         //// 
////      Initializes file and directory listing in the any         //// 
////      directory that is specified by path. To list files and    //// 
////      directorys in root directory path should be a empty       //// 
////      string(""). Ottherwise path should end with a "/" e.g:    //// 
////      "DIR/SUBDIR/". Returns a filehandle.                      //// 
////   Listfiles(char f)                                            //// 
////      List files and directorys in any directory that have been //// 
////      openes by InitList(). Access the list through FileList    //// 
////      array. See examples. There can only be one file handle    //// 
////      open for file listing at the same time. Returns the       //// 
////      number of files and directorys that where listed.         //// 
////   NextPage(char f)                                             //// 
////      To be able to handle many files in a dir, file listing    //// 
////      is parted up in pages. To list next page, call NextPage   //// 
////      and then ListFiles again. ListFiles must be called        //// 
////      before a NextPage function, otherwise the function will   //// 
////      not have any effect. Returns a MMCResponse.               //// 
////   SetPage(char f)                                              //// 
////      Set the page that you want to list, see above function    //// 
////      to get better understanding. Note: no need to call        //// 
////      ListFiles before this function. Returns a MMCResponse.    //// 
////   CloseList(char f)                                            //// 
////      Closes filelisting, in other words, the there are an      //// 
////      extra free file handle to use. Returns a MMCResponse      //// 
////   FreeList()                                                   //// 
////      Frees all the strings in FileList array. This function    //// 
////      is called before any new files are listed in ListFiles    //// 
////      but not in CloseList. THis means you can access the last  //// 
////      listed files even though you already have closed the      //// 
////      list. But to free the mem that are used by FileList call  //// 
////      this function.                                            //// 
////   fopen(char *fname, char mode)                                //// 
////      Opens a file specified by fname in the desired mode.      //// 
////      Valid modes are: 'r' = read, 'w' = write and 'a' = append //// 
////      No long filenames can be used. To open a file with long   //// 
////      filename, listed by ListFiles(), use the shortName field  //// 
////      in the FileList, FileList[i].shortName. Note: ListFiles   //// 
////      do only filename, not the path..                          //// 
////      Returns a filehandle if succeed, else a errorcode         //// 
////   fclose(char f)                                               //// 
////      Closes a file that previously have been opened by fopen.  //// 
////      Returns a MMCResponse                                     //// 
////   fputch(char be, char f)                                      //// 
////      Puts a char, be, in file f that previously have been      //// 
////      opened by fopen. Returns a MMCResponse                    //// 
////   fgetch(char *ki, char f)                                     //// 
////      get a char from file f that previously have been opened   //// 
////      by fopen, and puts it at the position specified by ki     //// 
////      Returns a MMCSresponse                                    //// 
////   fputstring(char *be, char f)                                 //// 
////      puts a entire string to file f that previously have been  //// 
////      opened by fopen. Returns MMCResponse                      //// 
////   fread(char *buffer, int16 leng, char f)                      //// 
////      Reads a block of data with length leng from file f that   //// 
////      previously have been opened by fopen.                     //// 
////      Returns the number of bytes that were read.               //// 
////   fwrite(char *buffer, int16 leng, char f)                     //// 
////      Writes a block of data with length leng to a file f that  //// 
////      previously have been opened by fopen.                     //// 
////      Returns a MMCResponse                                     //// 
////   getfsize(char *fname, int32 *fsiz)                           //// 
////      Reads the size of a file with a filename specified by     //// 
////      fname. Returns a MMCResponse.                             //// 
////                                                                //// 
//// Examples:                                                      //// 
////   // This example open a file for append, and writes "System   //// 
////   // started". It also shows small error handling              //// 
////   char f,gfilename[12];                                        //// 
////   strcpy(gfilename,"EVENTS.LOG");                              //// 
////   f = fopen(gfilename,'a'); // open EVENTS.LOG for append      //// 
////   if (f & MMC_ERROR)                                           //// 
////   {                                                            //// 
////      printf("Couldn't open file!\r\n");                        //// 
////      if(f == MMC_NO_CARD_INSERTED)                             //// 
////         printf("Please, insert MMC!");                         //// 
////      else if(f == MMC_MAX_FILES_REACHED)                       //// 
////         printf("ops.. =)");                                    //// 
////   }                                                            //// 
////   else                                                         //// 
////   {                                                            //// 
////      strcpy(msg,"System started\r\n");                         //// 
////      fputstring(msg,f);                                        //// 
////      fclose(f);                                                //// 
////   }                                                            //// 
////                                                                //// 
////   // Here is a exampel that covers almost everything...        //// 
////   // It first lists all files and dirs in DIR/ and then open   //// 
////   // The first and prints the file with printf, take a look:   //// 
////   #include <MMC_SPI_FAT32.h> // As usual you also need to      //// 
////   #include <MMC_SPI_FAT32.c> // include your device .h file... //// 
////   void main(void)                                              //// 
////   {                                                            //// 
////      char f,filename[20],res,i,c;                              //// 
////      while(TRUE)                                               //// 
////      {                                                         //// 
////         if(MMCInit() == MMC_OK)                                //// 
////         {                                                      //// 
////            printf("MMC initialized\r\n");                      //// 
////            InitFAT();                                          //// 
////            strcpy(filename,"DIR/");                            //// 
////            f = InitList(filename);                             //// 
////            if(f & MMC_ERROR)                                   //// 
////               printf("Error");                                 //// 
////            else                                                //// 
////            {                                                   //// 
////               do                                               //// 
////               {                                                //// 
////                  res = ListFiles(f);                           //// 
////                  for(i=0;i<res;i++)                            //// 
////                  {                                             //// 
////                     printf(FileList[i].name);                  //// 
////                     if(FileList[i].isDir)                      //// 
////                        printf("\\\r\n");//a "\" with row break //// 
////                     else                                       //// 
////                        printf("\r\n");                         //// 
////                  }                                             //// 
////               } while(NextPage(f) == MMC_OK);                  //// 
////               CloseList(f); // frees the file, but the list is //// 
////            }                // still there...                  //// 
////            strcpy(filename,FileList[0].shortName);             //// 
////            f = open(filename,'r'); // open file for reading    //// 
////            if((f & MMC_ERROR) == 0) // No error, same as       //// 
////            {                        // if(f < MAXFILES)        //// 
////               while(fgetch(&c,f) == MMC_OK)                    //// 
////                  printf(c);                                    //// 
////               fclose(f);                                       //// 
////            }                                                   //// 
////            else if(f == MMC_NOT_FOUND)                         //// 
////               printf("1st file in list was probebly a dir");   //// 
////            else                                                //// 
////               printf("Other error\r\n");                       //// 
////            while(TRUE)                                         //// 
////               ; // Loop forever, program is finished           //// 
////         }                                                      //// 
////         else                                                   //// 
////            printf("MMC init failed!\r\n");                     //// 
////         delay_ms(1000);                                        //// 
////         printf("Trying once more..\r\n");                      //// 
////      }                                                         //// 
////   }                                                            //// 
////                                                                //// 
//////////////////////////////////////////////////////////////////////// 
//// Changelog:                                                     //// 
//// YYYY-MM-DD VER LOG                                             //// 
//// 2007-08-15 0.9 Fixed a hardware SPI error in writesector.      //// 
////                Thanks to wielen who found the bug.             //// 
//// 2007-07-25 0.8 This, and almost all other text is written      //// 
//////////////////////////////////////////////////////////////////////// 
//////////////////////////////////////////////////////////////////////// 

// 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(B) 
// Change this to set the right tris for your pins 
#define SET_MMC_TRIS() set_tris_b(0x10) // 0b0001000 1=input,0=output 
// Change these pins to whatever pins you are using 
#define ChipSel      pin_B7 // Chip-Select pin 
#define ChipClk      pin_B5 // SPI-Clock pin 
#define ChipDout   pin_B6 // SPI-Data out pin 
#define ChipDin      pin_B4 // 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); 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -