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

📄 mmc_datalogger_eeprom.c

📁 C8051F340读写SD卡的程序
💻 C
📖 第 1 页 / 共 5 页
字号:

   }
}


//-----------------------------------------------------------------------------
// LogInit
//-----------------------------------------------------------------------------
// Initialize the Log Entry space (all zeros);
//
void LogInit (LOG_ENTRY *pEntry)
{
   pEntry->wTemp = 0;
   pEntry->uDay = 0;
   pEntry->bHour = 0;
   pEntry->bMin = 0;
   pEntry->bSec = 0;
}


//-----------------------------------------------------------------------------
// MMC_Command_Exec
//-----------------------------------------------------------------------------
//
// This function generates the necessary SPI traffic for all MMC SPI commands.
// The three parameters are described below:
// 
// cmd:      This parameter is used to index into the command table and read 
//           the desired command.  The Command Table Index Constants allow the
//           caller to use a meaningful constant name in the cmd parameter 
//           instead of a simple index number.  For example, instead of calling 
//           MMC_Command_Exec (0, argument, pchar) to send the MMC into idle 
//           state, the user can call 
//           MMC_Command_Exec (GO_IDLE_STATE, argument, pchar);
//
// argument: This parameter is used for MMC commands that require an argument.
//           MMC arguments are 32-bits long and can be values such as an
//           an address, a block length setting, or register settings for the
//           MMC.
//
// pchar:    This parameter is a pointer to the EEPROM data location for MMC 
//           data operations.  When a read or write occurs, data will be stored
//           or retrieved from the location pointed to by pchar.
//
// The MMC_Command_Exec function indexes the command table using the cmd 
// parameter. It reads the command table entry into memory and uses information
// from that entry to determine how to proceed.  Returns 16-bit card response
// value.
//

unsigned int MMC_Command_Exec (unsigned char cmd, unsigned long argument,
                               unsigned int pchar)
{
   idata command current_command;      // Local space for the command table 
                                       // entry;
   idata ULONG long_arg;               // Union variable for easy byte 
                                       // transfers of the argument;
                                       // Static variable that holds the 
                                       // current data block length;
   static unsigned long current_blklen = 512;
                                       // Temp variable to preserve data block
   idata unsigned long old_blklen = 512;
                                       // length during temporary changes;
   idata unsigned int counter = 0;     // Byte counter for multi-byte fields;
   idata UINT card_response;           // Variable for storing card response;
   idata unsigned char data_resp;      // Variable for storing data response;
   idata unsigned char dummy_CRC;      // Dummy variable for storing CRC field;
                                       // Index variable for keeping track of 
                                       // where you are in the EEPROM page;
   idata unsigned char EEPROM_BufferIndex;

                                       
   current_command = commandlist[cmd]; // Retrieve desired command table entry
                                       // from code space;
   SPI0DAT = 0xFF;                     // Send buffer SPI clocks to ensure no
   while(!SPIF){}                      // MMC operations are pending;
   SPIF = 0;
   NSSMD0 = 0;                         // Select MMC by pulling CS low;
   SPI0DAT = 0xFF;                     // Send another byte of SPI clocks;
   while(!SPIF){}
   SPIF = 0;
                                       // Issue command opcode;
   SPI0DAT = (current_command.command_byte | 0x40);
   long_arg.l = argument;              // Make argument byte addressable;
                                       // If current command changes block
                                       // length, update block length variable
                                       // to keep track;
   if(current_command.command_byte == 16)
   {
      current_blklen = argument;       // Command is a read, set local block
   }                                   // length;
   if((current_command.command_byte == 9)||
      (current_command.command_byte == 10))
   {
      old_blklen = current_blklen;     // Command is a GET_CSD or GET_CID,
      current_blklen = 16;             // set block length to 16-bytes;
   }
   while(!SPIF){}                      // Wait for initial SPI transfer to end;
   SPIF = 0;                           // Clear SPI Interrupt flag;

                                       // If an argument is required, transmit
                                       // one, otherwise transmit 4 bytes of
                                       // 0xFF;
   if(current_command.arg_required == YES)
   {
      counter = 0;
      while(counter <= 3)
      {
         SPI0DAT = long_arg.b[counter];
         counter++;
         while(!SPIF){}
         SPIF = 0;
      }
   }
   else
   {
      counter = 0;
      while(counter <= 3)
      {
         SPI0DAT = 0x00;
         counter++;
         while(!SPIF){}
         SPIF = 0;
      }
   }
   SPI0DAT = current_command.CRC;      // Transmit CRC byte;  In all cases
   while(!SPIF){}                      // except CMD0, this will be a dummy
   SPIF = 0;                           // character;

                                       // The command table entry will indicate
                                       // what type of response to expect for
                                       // a given command;  The following 
                                       // conditional handles the MMC response;
   if(current_command.response == R1)  // Read the R1 response from the card;
   {
      do
      {
         SPI0DAT = 0xFF;               // Write dummy value to SPI so that 
         while(!SPIF){}                // the response byte will be shifted in;
         SPIF = 0;
         card_response.b[0] = SPI0DAT; // Save the response;
      }
      while((card_response.b[0] & BUSY_BIT));
   }
                                       // Read the R1b response;
   else if(current_command.response == R1b)
   {
      do
      {
         SPI0DAT = 0xFF;               // Start SPI transfer;
         while(!SPIF){}
         SPIF = 0;
         card_response.b[0] = SPI0DAT; // Save card response
      }
      while((card_response.b[0] & BUSY_BIT));
      do                               // Wait for busy signal to end;
      {
         SPI0DAT = 0xFF;               
         while(!SPIF){}
         SPIF = 0;
      }
      while(SPI0DAT == 0x00);          // When byte from card is non-zero,
   }                                   // card is no longer busy;
                                       // Read R2 response
   else if(current_command.response == R2)
   {
      do
      {
         SPI0DAT = 0xFF;               // Start SPI transfer;
         while(!SPIF){}
         SPIF = 0;
         card_response.b[0] = SPI0DAT; // Read first byte of response;
      }
      while((card_response.b[0] & BUSY_BIT));
      SPI0DAT = 0xFF;
      while(!SPIF){}
      SPIF = 0;
      card_response.b[1] = SPI0DAT;    // Read second byte of response;
   }
   else                                // Read R3 response;
   {
      do
      {
         SPI0DAT = 0xFF;               // Start SPI transfer;
         while(!SPIF){}
         SPIF = 0;
         card_response.b[0] = SPI0DAT; // Read first byte of response;
      }
      while((card_response.b[0] & BUSY_BIT));
      counter = 0;
      while(counter <= 3)              // Read next three bytes and store them
      {                                // in local memory;  These bytes make up
         counter++;                    // the Operating Conditions Register
         SPI0DAT = 0xFF;               // (OCR);
         while(!SPIF){}
         SPIF = 0;
         data_resp = SPI0DAT;
                                       // Send data read from MMC to EEPROM
                                       // buffer;
         EEPROM_WriteByte(pchar,data_resp);
         pchar++;
      }
   }
   switch(current_command.trans_type)  // This conditional handles all data 
   {                                   // operations;  The command entry
                                       // determines what type, if any, data
                                       // operations need to occur;
      case RD:                         // Read data from the MMC;
         do                            // Wait for a start read token from
         {                             // the MMC;
            SPI0DAT = 0xFF;            // Start a SPI transfer;
            while(!SPIF){}
            SPIF = 0;
         }
         while(SPI0DAT != START_SBR);  // Check for a start read token;
         counter = 0;                  // Reset byte counter;
                                       // Read <current_blklen> bytes;
         EEPROM_BufferIndex = 0;
         while(counter < (unsigned int)current_blklen)
         {
            SPI0DAT = 0x00;            // Start SPI transfer;
            while(!SPIF){}
            SPIF = 0;
                                       // Build a small buffer of data
                                       // in local memory;
            EEPROM_PageBuffer[EEPROM_BufferIndex] = SPI0DAT;
            EEPROM_BufferIndex++;
                                       // If the buffer reaches the size of a
                                       // physical EEPROM page, write buffered
                                       // data out to EEPROM and reset buffer;
            if(EEPROM_BufferIndex >= EEPROM_PAGE_SIZE)
            {
                                       // Send data to EEPROM;
               EEPROM_WriteArray(pchar, &EEPROM_PageBuffer[0], EEPROM_PAGE_SIZE);
                                       // Increment EEPROM page;
               pchar += EEPROM_PAGE_SIZE;  
               EEPROM_BufferIndex = 0; // Reset local buffer index;
            }
            counter++;                 // Increment data byte counter;
         }
                                       // Write any remaining buffered data to 
         if(EEPROM_BufferIndex != 0)   // EEPROM;
            EEPROM_WriteArray(pchar, &EEPROM_PageBuffer[0], EEPROM_BufferIndex);

         SPI0DAT = 0x00;               // After all data is read, read the two
         while(!SPIF){}                // CRC bytes;  These bytes are not used
         SPIF = 0;                     // in this mode, but the placeholders 
         dummy_CRC = SPI0DAT;          // must be read anyway;
         SPI0DAT = 0x00;
         while(!SPIF){}
         SPIF = 0;
         dummy_CRC = SPI0DAT;
         break;
      case WR:                         // Write data to the MMC;
         SPI0DAT = 0xFF;               // Start by sending 8 SPI clocks so
         while(!SPIF){}                // the MMC can prepare for the write;
         SPIF = 0;
         SPI0DAT = START_SBW;          // Send the start write block token;
         counter = 0;                  // Reset byte counter;
         while(!SPIF){}
         SPIF = 0;
                                       // Prime Buffer Index
         EEPROM_BufferIndex = EEPROM_PAGE_SIZE;
                                       // Write <current_blklen> bytes to MMC;
         while(counter < (unsigned int)current_blklen)
         {                             // When EEPROM page is full, reset local
                                       // buffer and move to next EEPROM page;
            if(EEPROM_BufferIndex > EEPROM_PAGE_SIZE-1)
            {
                                       // Send data to EEPROM;
               EEPROM_ReadArray(&EEPROM_PageBuffer[0],pchar,EEPROM_PAGE_SIZE);
                                       // Reset local buffer index;
               EEPROM_BufferIndex = 0;
                                       // Update EEPROM page;
               pchar += EEPROM_PAGE_SIZE;
            }
                                       // Write data byte out through SPI;
            SPI0DAT = EEPROM_PageBuffer[EEPROM_BufferIndex];
            EEPROM_BufferIndex++;

⌨️ 快捷键说明

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