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

📄 mmc_datalogger_eeprom.c

📁 C8051F340读写SD卡的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
            counter++;                 // Increment byte counter;
            while(!SPIF){}
            SPIF = 0;
         }

         SPI0DAT = 0xFF;               // Write CRC bytes (don't cares);
         while(!SPIF){}
         SPIF = 0;
         SPI0DAT = 0xFF;
         while(!SPIF){}
         SPIF = 0;

         do                            // Read Data Response from card;
         {                             // 
            SPI0DAT = 0xFF;
            while(!SPIF){}
            SPIF = 0;
            data_resp = SPI0DAT;
         }                             // When bit 0 of the MMC response
                                       // is clear, a valid data response
                                       // has been received;
         while((data_resp & DATA_RESP_MASK) != 0x01);

         do                            // Wait for end of busy signal;
         {
            SPI0DAT = 0xFF;            // Start SPI transfer to receive
            while(!SPIF){}             // busy tokens;
            SPIF = 0;
         }
         while(SPI0DAT == 0x00);       // When a non-zero token is returned,
                                       // card is no longer busy;
         SPI0DAT = 0xFF;               // Issue 8 SPI clocks so that all card
         while(!SPIF){}                // operations can complete;
         SPIF = 0;
         break;
      default: break;
   }
   SPI0DAT = 0xFF;
   while(!SPIF){}
   SPIF = 0;


   NSSMD0 = 1;                         // Deselect memory card;
   SPI0DAT = 0xFF;                     // Send 8 more SPI clocks to ensure
   while(!SPIF){}                      // the card has finished all necessary
   SPIF = 0;                           // operations;
                                       // Restore old block length if needed;
   if((current_command.command_byte == 9)||
      (current_command.command_byte == 10))
   {
      current_blklen = old_blklen;
   }
   return card_response.i;
}


//-----------------------------------------------------------------------------
// MMC_FLASH_Init
//-----------------------------------------------------------------------------
//
// This function initializes the flash card, configures it to operate in SPI
// mode, and reads the operating conditions register to ensure that the device
// has initialized correctly.  It also determines the size of the card by 
// reading the Card Specific Data Register (CSD).

void MMC_FLASH_Init (void)
{
   idata UINT card_status;             // Stores card status returned from 
                                       // MMC function calls(MMC_Command_Exec);
   idata unsigned char counter = 0;    // SPI byte counter;
   idata unsigned int size;            // Stores size variable from card;
   unsigned int pchar;                 // Pointer int EEPROM for storing MMC 
                                       // register values;
   unsigned char space[4];             // 4 bytes of memory for use in storing
                                       // temporary register values from MMC;
   unsigned char *lpchar;              // Local storage for data from MMC;
                                       // Transmit at least 64 SPI clocks
                                       // before any bus comm occurs.

   pchar = LOCAL_BLOCK;
   lpchar = &space[0];
   for(counter = 0; counter < 10; counter++)
   {
      SPI0DAT = 0xFF;
      while(!SPIF){}
      SPIF = 0;
   }
                                       // Send the GO_IDLE_STATE command with
                                       // CS driven low;  This causes the MMC
                                       // to enter SPI mode;
   card_status.i = MMC_Command_Exec(GO_IDLE_STATE,EMPTY,EMPTY);
                                       // Send the SEND_OP_COND command
   do                                  // until the MMC indicates that it is
   {                                   // no longer busy (ready for commands);
      SPI0DAT = 0xFF;
      while(!SPIF){}
      SPIF = 0;
      card_status.i = MMC_Command_Exec(SEND_OP_COND,EMPTY,EMPTY);
   }
   while ((card_status.b[0] & 0x01));
   SPI0DAT = 0xFF;                     // Send 8 more SPI clocks to complete
   while(!SPIF){}                      // the initialization sequence;
   SPIF = 0;
   do                                  // Read the Operating Conditions 
   {                                   // Register (OCR);
      card_status.i = MMC_Command_Exec(READ_OCR,EMPTY,pchar);
                                       // Get OCR from EEPROM;
      EEPROM_ReadArray(lpchar,pchar,4);
   }
   while(!(*lpchar&0x80));             // Test for card ready;

   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);
                                       // Get CSD from EEPROM;
   *lpchar = EEPROM_ReadByte(pchar+9);
                                       // Size indicator is in the 9th byte of
                                       // CSD register;
                                       // Extract size indicator bits;
   size = (unsigned int)((((*lpchar) & 0x03) << 1) | 
                         (((*(lpchar+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 MMC data from address <address>, and
// stores them in EEPROM space 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 int 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_Write
//-----------------------------------------------------------------------------
//
// This function operates much like the MMC_FLASH_Read function.  As
// with the MMC_FLASH_Read function, if the desired write space crosses a FLASH 
// block boundary, the operation must be broken into two pieces.  
// MMC_FLASH_Write first reads the addressed block of MMC data into the EEPROM,
// then modifies the contents of that block in EEPROM space;  Finally, the MMC
// block is erased in the MMC and replaced by the updated block from EEPROM 
// space;
//
unsigned char MMC_FLASH_Write (unsigned long address, unsigned int scratch,
                          unsigned int 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;
   idata unsigned int temp_length;
   unsigned int index;                 // Pointer into local copy of data
                                       // block, used during modification;
   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 into EEPROM;
      card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_1,scratch);
      index = (unsigned int)(address % PHYSICAL_BLOCK_SIZE) + scratch;
      counter = 0;                                       
      while(length>0)                  // This loop updates the temporary
      {                                // MMC Page(in EEPROM) with the contents
         if(length<=64)                // of the current temperature buffer;
         {                          
            counter = length;
            length = 0;
         }
         else
         {
            counter = 64;
            length -= 64;
         }
                                       // Read temperature data
         EEPROM_ReadArray(&EEPROM_PageBuffer[0],wdata,counter);
                                       // Store in temp MMC page(in EEPROM);
         EEPROM_WriteArray(index, &EEPROM_PageBuffer[0], counter);
         wdata+=EEPROM_PAGE_SIZE;      // Update temperature buffer pointer;
         index+=EEPROM_PAGE_SIZE;      // Update temp MMC page (in EEPROM)
                                       // pointer;
         counter = 0;
      }
                                       // 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 into EEPROM;
      card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_1,scratch);
      index = (unsigned int)(address % PHYSICAL_BLOCK_SIZE) + scratch;
      temp_length = length;
      length = (unsigned int)(flash_page_2 - address);
      while(length>0)      

⌨️ 快捷键说明

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