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

📄 mmc_datalogger.c

📁 C8051F340读写SD卡的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
   while(!(*pchar&0x80));              // Check the card busy bit of the OCR;

   card_status.i = MMC_Command_Exec(SEND_STATUS,EMPTY,EMPTY);
                                       // Get the Card Specific Data (CSD)
                                       // register to determine the size of the
                                       // MMC;
   card_status.i = MMC_Command_Exec(SEND_CSD,EMPTY,pchar);
   pchar += 9;                         // Size indicator is in the 9th byte of
                                       // CSD register;
                                       // Extract size indicator bits;
   size = (unsigned int)((((*pchar) & 0x03) << 1) | 
                         (((*(pchar+1)) & 0x80) >> 7));
   switch(size)                        // Assign PHYSICAL_SIZE variable to 
   {                                   // appropriate size constant;
      case 1: PHYSICAL_SIZE = PS_8MB; break;
      case 2: PHYSICAL_SIZE = PS_16MB; break;
      case 3: PHYSICAL_SIZE = PS_32MB; break;
      case 4: PHYSICAL_SIZE = PS_64MB; break;
      case 5: PHYSICAL_SIZE = PS_128MB; break;
      default: break;
   }
                                       // Determine the number of MMC sectors;
   PHYSICAL_BLOCKS = PHYSICAL_SIZE / PHYSICAL_BLOCK_SIZE;
   LOG_SIZE = PHYSICAL_SIZE - LOG_ADDR;
}
//-----------------------------------------------------------------------------
// MMC_FLASH_Read
//-----------------------------------------------------------------------------
//
// This function reads <length> bytes of FLASH from MMC address <address>, and
// stores them in external RAM at the location pointed to by <pchar>.
// There are two cases that must be considered when performing a read.  If the
// requested data is located entirely in a single FLASH block, the function
// sets the read length appropriately and issues a read command.  If requested
// data crosses a FLASH block boundary, the read operation is broken into two
// parts.  The first part reads data from the starting address to the end of 
// the starting block, and then reads from the start of the next block to the
// end of the requested data.  Before each read, the read length must be set
// to the proper value.
unsigned char MMC_FLASH_Read (unsigned long address, unsigned char *pchar,
                         unsigned int length)
{
   idata unsigned long flash_page_1;   // Stores address of first FLASH page;
   idata unsigned long flash_page_2;   // Stores address of second FLASH page;
   idata unsigned int card_status;     // Stores MMC status after each MMC
                                       // command;

   if(length > 512) return 0;          // Test for valid data length;  Length
                                       // must be less than 512 bytes;
                                       // Find address of first FLASH block;
   flash_page_1 = address & ~(PHYSICAL_BLOCK_SIZE-1);
                                       // Find address of second FLASH block;
   flash_page_2 = (address+length-1) & ~(PHYSICAL_BLOCK_SIZE-1);
   if(flash_page_1 == flash_page_2)    // Execute the following if data is 
   {                                   // located within one FLASH block;
                                       // Set read length to requested data
                                       // length;
      card_status = MMC_Command_Exec(SET_BLOCKLEN,(unsigned long)length,
                                 EMPTY);
                                       // Issue read command;
      card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,address,pchar);
   }
   else                                // Execute the following if data crosses
   {                                   // MMC block boundary;
                                       // Set the read length to the length
                                       // from the starting address to the
                                       // end of the first FLASH page;
      card_status = MMC_Command_Exec(SET_BLOCKLEN,
                                (unsigned long)(flash_page_2 - address),
                                 EMPTY);
                                       // Issue read command;
      card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,address,pchar);
                                       // Set read length to the length from
                                       // the start of the second FLASH page
                                       // to the end of the data;
      card_status = MMC_Command_Exec(SET_BLOCKLEN,
                                (unsigned long)length - 
                                (flash_page_2 - address),
                                 EMPTY);
                                       // Issue second read command;  Notice
                                       // that the incoming data stored in 
                                       // external RAM must be offset from the
                                       // original pointer value by the length
                                       // of data stored during the first read 
                                       // operation;
      card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_2,
                                 pchar + (flash_page_2 - address));
   }
}

//-----------------------------------------------------------------------------
// MMC_FLASH_Clear
//-----------------------------------------------------------------------------
//
// This function erases <length> bytes of flash starting at address <address>.
// The <scratch> pointer points to a 512 byte area of XRAM that can
// be used as temporary storage space.  The flow of this function is similar
// to the FLASH_Read function in that there are two possible cases.  If the
// space to be cleared is contained within one MMC block, the block can be
// stored locally and erased from the MMC.  Then the desired area can be 
// cleared in the local copy and the block can be written back to the MMC.  If 
// the desired clear area crosses a FLASH block boundary, the previous steps 
// must be executed seperately for both blocks.
unsigned char MMC_FLASH_Clear (unsigned long address, unsigned char *scratch,
                          unsigned int length)
{
   idata unsigned long flash_page_1;   // Stores address of first FLASH page;
   idata unsigned long flash_page_2;   // Stores address of second FLASH page;
   idata unsigned int card_status;     // Stores MMC status after each MMC
                                       // command;
   idata unsigned int counter;         // Counter for clearing bytes in local
                                       // block copy;
   unsigned char xdata *index;         // Index into local block used for 
                                       // clearing desired data;
   if(length > 512) return 0;          // Test desired clear length;  If 
                                       // length > 512, break out and return
                                       // zero;
                                       // Calculate first FLASH page address;
   flash_page_1 = address & ~(PHYSICAL_BLOCK_SIZE-1);
                                       // Calculate second FLASH page address;
   flash_page_2 = (address+length-1) & ~(PHYSICAL_BLOCK_SIZE-1);
   if(flash_page_1 == flash_page_2)    // Clear space all in one FLASH block
   {                                   // condition;
                                       // Read first FLASH block;
      card_status = MMC_Command_Exec(SET_BLOCKLEN,
                                 (unsigned long)PHYSICAL_BLOCK_SIZE,
                                 EMPTY);
      card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_1,scratch);
                                       // Set index to address of area to clear
                                       // in local block;
      index = (unsigned int)(address % PHYSICAL_BLOCK_SIZE) + scratch;
      counter = 0;
      while(counter<length)            // Clear desired area in local block;
      {
         *index++ = 0x00;
         counter++;
      }
                                       // Tag first FLASH page for erase;
      card_status = MMC_Command_Exec(TAG_SECTOR_START,flash_page_1,EMPTY);
      card_status = MMC_Command_Exec(TAG_SECTOR_END,flash_page_1,EMPTY);
                                       // Erase first FLASH page;
      card_status = MMC_Command_Exec(ERASE,EMPTY,EMPTY);
                                       // Write local copy of block back out
                                       // to MMC;
      card_status = MMC_Command_Exec(WRITE_BLOCK,flash_page_1,scratch);
   }
   else                                // Clear space crosses FLASH block
   {                                   // boundaries condition;
                                       // Follow same procedure as for single
                                       // block case above;  Read first block
                                       // clear data from start address to end
                                       // of block;  Erase block in FLASH;
                                       // Write local copy back out;
      card_status = MMC_Command_Exec(SET_BLOCKLEN,
                                 (unsigned long)PHYSICAL_BLOCK_SIZE,
                                 EMPTY);
      card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_1,scratch);
      index = (unsigned int)(address % PHYSICAL_BLOCK_SIZE) + scratch;
      counter = (unsigned int)(flash_page_2 - address);
      while(counter > 0)
      {
         *index++ = 0xFF;
         counter--;
      }
      card_status = MMC_Command_Exec(TAG_SECTOR_END,flash_page_1,EMPTY);
      card_status = MMC_Command_Exec(ERASE,EMPTY,EMPTY);
      card_status = MMC_Command_Exec(WRITE_BLOCK,flash_page_1,scratch);
                                       // Same process as above, but using
                                       // second FLASH block;  Area to be
                                       // cleared extends from beginning of
                                       // second FLASH block to end of desired
                                       // clear area;
      card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_2,scratch);
      index = scratch;
      counter = (unsigned int)(length - (flash_page_2 - address));
      while(counter > 0)
      {
         *index++ = 0xFF;
         counter--;
      }
      card_status = MMC_Command_Exec(TAG_SECTOR_END,flash_page_2,EMPTY);
      card_status = MMC_Command_Exec(ERASE,EMPTY,EMPTY);
      card_status = MMC_Command_Exec(WRITE_BLOCK,flash_page_2,scratch);
   }
}

//-----------------------------------------------------------------------------
// MMC_FLASH_Write
//-----------------------------------------------------------------------------
//
// This function operates much like the MMC_FLASH_Clear and MMC_FLASH_Read
// functions.  As with the others, if the desired write space crosses a FLASH 
// block boundary, the operation must be broken into two pieces.  
// MMC_FLASH_Write uses the MMC_FLASH_Clear function to clear the write space 
// before issuing any writes.  The desired write space is cleared using 
// MMC_FLASH_Clear, then the data is read in, the previously cleared write 
// space is modified, and the data is written back out.
//
// While it would be more efficient to avoid the MMC_FLASH_Clear and simply 
// perform a read-modify-write operation, using MMC_FLASH_Clear helps make the 
// process easier to understand.
unsigned char MMC_FLASH_Write (unsigned long address, unsigned char *scratch,
                          unsigned char *wdata, unsigned int length)
{
   idata unsigned long flash_page_1;   // First FLASH page address;
   idata unsigned long flash_page_2;   // Second FLASH page address;
   idata unsigned int card_status;     // Stores status returned from MMC;
   idata unsigned int counter;         // Byte counter used for writes to 
                                       // local copy of data block;
   unsigned char xdata *index;         // Pointer into local copy of data
                                       // block, used during modification;
   MMC_FLASH_Clear(address,scratch,length); // Clear desired write space;
   if(length > 512) return 0;          // Check for valid data length;
                                       // Calculate first FLASH page address;
   flash_page_1 = address & ~(PHYSICAL_BLOCK_SIZE-1);
                                       // Calculate second FLASH page address;
   flash_page_2 = (address+length-1) & ~(PHYSICAL_BLOCK_SIZE-1);
   if(flash_page_1 == flash_page_2)    // Handle single FLASH block condition;
   {
                                       // Set block length to default block
                                       // size (512 bytes);
      card_status = MMC_Command_Exec(SET_BLOCKLEN,
                                 (unsigned long)PHYSICAL_BLOCK_SIZE,
                                 EMPTY);
                                       // Read data block;
      card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_1,scratch);
      index = (unsigned int)(address % PHYSICAL_BLOCK_SIZE) + scratch;
      counter = 0;
      while(counter<length)            // Modify write space in local copy;
      {
         *index++ = *wdata++;
         counter++;
      }
                                       // Write modified block back to MMC;
      card_status = MMC_Command_Exec(WRITE_BLOCK,flash_page_1,scratch);
   }
   else                                // Handle multiple FLASH block 
   {                                   // condition;
                                       // Set block length to default block
                                       // size (512 bytes);
      card_status = MMC_Command_Exec(SET_BLOCKLEN,
                                 (unsigned long)PHYSICAL_BLOCK_SIZE,
                                 EMPTY);
                                       // Read first data block;
      card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_1,scratch);
      index = (unsigned int)(address % PHYSICAL_BLOCK_SIZE) + scratch;
      counter = (unsigned int)(flash_page_2 - address);
      while(counter > 0)               // Modify data in local copy of first
      {                                // block;
         *index++ = *wdata++;
         counter--;
      }
                                       // Write local copy back to MMC;
      card_status = MMC_Command_Exec(WRITE_BLOCK,flash_page_1,scratch);
                                       // Read second data block;
      card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_2,scratch);
      index = scratch;
      counter = (unsigned int)(length - (flash_page_2 - address));
      while(counter > 0)               // Modify data in local copy of second
      {                                // block;
         *index++ = *wdata++;
         counter--;
      }
                                       // Write local copy back to MMC;
      card_status = MMC_Command_Exec(WRITE_BLOCK,flash_page_2,scratch);
   }
}

//-----------------------------------------------------------------------------
// MMC_FLASH_MassErase
//-----------------------------------------------------------------------------
//
// This function erases <length> bytes of flash starting with the block
// indicated by <address1>.  This function only handles sector-si

⌨️ 快捷键说明

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