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

📄 mmc_datalogger.c

📁 C8051F340读写SD卡的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
typedef struct {
      unsigned char command_byte;      // OpCode;
      unsigned char arg_required;      // Indicates argument requirement;
      unsigned char CRC;               // Holds CRC for command if necessary;
      unsigned char trans_type;        // Indicates command transfer type;
      unsigned char response;          // Indicates expected response;
      unsigned char var_length;        // Indicates varialble length transfer;
               } COMMAND;

// Command table for MMC.  This table contains all commands available in SPI
// mode;  Format of command entries is described above in command structure
// definition;
COMMAND code commandlist[25] = {
      { 0,NO ,0x95,CMD,R1 ,NO },    // CMD0;  GO_IDLE_STATE: reset card;
      { 1,NO ,0xFF,CMD,R1 ,NO },    // CMD1;  SEND_OP_COND: initialize card;
      { 9,NO ,0xFF,RD ,R1 ,NO },    // CMD9;  SEND_CSD: get card specific data;
      {10,NO ,0xFF,RD ,R1 ,NO },    // CMD10; SEND_CID: get card identifier;
      {12,NO ,0xFF,CMD,R1 ,NO },    // CMD12; STOP_TRANSMISSION: end read;
      {13,NO ,0xFF,CMD,R2 ,NO },    // CMD13; SEND_STATUS: read card status;
      {16,YES,0xFF,CMD,R1 ,NO },    // CMD16; SET_BLOCKLEN: set block size;
      {17,YES,0xFF,RD ,R1 ,NO },    // CMD17; READ_SINGLE_BLOCK: read 1 block;
      {18,YES,0xFF,RD ,R1 ,YES},    // CMD18; READ_MULTIPLE_BLOCK: read > 1;
      {24,YES,0xFF,WR ,R1 ,NO },    // CMD24; WRITE_BLOCK: write 1 block;
      {25,YES,0xFF,WR ,R1 ,YES},    // CMD25; WRITE_MULTIPLE_BLOCK: write > 1;
      {27,NO ,0xFF,CMD,R1 ,NO },    // CMD27; PROGRAM_CSD: program CSD;
      {28,YES,0xFF,CMD,R1b,NO },    // CMD28; SET_WRITE_PROT: set wp for group;
      {29,YES,0xFF,CMD,R1b,NO },    // CMD29; CLR_WRITE_PROT: clear group wp;
      {30,YES,0xFF,CMD,R1 ,NO },    // CMD30; SEND_WRITE_PROT: check wp status;
      {32,YES,0xFF,CMD,R1 ,NO },    // CMD32; TAG_SECTOR_START: tag 1st erase;
      {33,YES,0xFF,CMD,R1 ,NO },    // CMD33; TAG_SECTOR_END: tag end(single);
      {34,YES,0xFF,CMD,R1 ,NO },    // CMD34; UNTAG_SECTOR: deselect for erase;
      {35,YES,0xFF,CMD,R1 ,NO },    // CMD35; TAG_ERASE_GROUP_START;
      {36,YES,0xFF,CMD,R1 ,NO },    // CMD36; TAG_ERASE_GROUP_END;
      {37,YES,0xFF,CMD,R1 ,NO },    // CMD37; UNTAG_ERASE_GROUP;
      {38,YES,0xFF,CMD,R1b,NO },    // CMD38; ERASE: erase all tagged sectors;
      {42,YES,0xFF,CMD,R1b,NO },    // CMD42; LOCK_UNLOCK;
      {58,NO ,0xFF,CMD,R3 ,NO },    // CMD58; READ_OCR: read OCR register;
      {59,YES,0xFF,CMD,R1 ,NO }    // CMD59; CRC_ON_OFF: toggles CRC checking;
                              };

//-----------------------------------------------------------------------------
// Global VARIABLES
//-----------------------------------------------------------------------------

xdata LONG Result = {0L};              // ADC0 decimated value

xdata LOG_ENTRY LogRecord;             // Memory space for each log entry
xdata unsigned long uLogCount;         // Current number of table entries
LOG_ENTRY xdata *pLogTable;            // Pointer to buffer for table entries
xdata STATE State = RESET;             // System state variable;  Determines
                                       // how log update function will exec;
xdata unsigned long PHYSICAL_SIZE;     // MMC size variable;  Set during
                                       // initialization;
xdata unsigned long LOG_SIZE;          // Available number of bytes for log
                                       // table;

xdata unsigned long PHYSICAL_BLOCKS;   // MMC block number;  Computed during
                                       // initialization;

xdata char LOCAL_BLOCK[BUFFER_SIZE]; 
xdata char SCRATCH_BLOCK[PHYSICAL_BLOCK_SIZE];

xdata char error;
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------

void main (void);

// Support Subroutines
void MENU_ListCommands (void);         // Outputs user menu choices via UART


// Logging Subroutines
void LogUpdate (void);                 // Builds MMC log table
unsigned long LogFindCount();          // Returns current number of log entries
void LogErase (void);                  // Erases entire log table
void LogPrint (void);                  // Prints log through UART
void LogInit (LOG_ENTRY *pEntry);      // Initializes area for building entries

// High Level MMC_FLASH Functions

void MMC_FLASH_Init (void);            // Initializes MMC and configures it to 
                                       // accept SPI commands;

                                       // Reads <length> bytes starting at 
                                       // <address> and stores them at <pchar>;
unsigned char MMC_FLASH_Read (unsigned long address, unsigned char *pchar,
                         unsigned int length);

                                       // Clears <length> bytes starting at 
                                       // <address>; uses memory at <scratch>
                                       // for temporary storage;
unsigned char MMC_FLASH_Clear (unsigned long address, unsigned char *scratch,
                          unsigned int length);

                                       // Writes <length> bytes of data at
                                       // <wdata> to <address> in MMC;
                                       // <scratch> provides temporary storage;
unsigned char MMC_FLASH_Write (unsigned long address, unsigned char *scratch,
                          unsigned char *wdata, unsigned int length);

                                       // Clears <length> bytes of FLASH 
                                       // starting at <address1>; Requires that
                                       // desired erase area be sector aligned;
unsigned char MMC_FLASH_MassErase (unsigned long address1, 
                                   unsigned long length);

// Low Level MMC_FLASH_ Functions

                                       // Decodes and executes MMC commands;  
                                       // <cmd> is an index into the command
                                       // table and <argument> contains a 
                                       // 32-bit argument if necessary;  If a 
                                       // data operation is taking place, the
                                       // data will be stored to or read from
                                       // the location pointed to by <pchar>;
unsigned int MMC_Command_Exec (unsigned char cmd, unsigned long argument,
                           unsigned char *pchar);


// Initialization Subroutines

void SYSCLK_Init (void);
void PORT_Init (void);
void UART0_Init (void);
void ADC0_Init (void);
void Soft_Init (void);
void Timer0_Init (int counts);
void Timer2_Init (int counts);
void SPI_Init (void);

// Interrupt Service Routines

void ADC0_ISR (void);
void Soft_ISR (void);

//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------

void main (void) {
   idata char key_press;               // Input character from UART;
   // Disable Watchdog timer
   PCA0MD &= ~0x40;                    // WDTE = 0 (clear watchdog timer
                                       // enable);

   PORT_Init ();                       // Initialize crossbar and GPIO;
   SYSCLK_Init ();                     // Initialize oscillator;
   UART0_Init ();                      // Initialize UART0;
   SPI_Init ();                        // Initialize SPI0;
   Timer2_Init (SYSCLK/SAMPLE_RATE);   // Init Timer2 for 16-bit autoreload;
   ADC0_Init ();                       // Init ADC0;
   Soft_Init ();                       // Initialize software interrupts;
   MMC_FLASH_Init();                   // Initialize MMC card;
   AD0EN = 1;                          // enable ADC0;

   State = RESET;                      // Set global state machine to reset
                                       // state;

                                       // Initialize log table buffer pointer
   pLogTable = (LOG_ENTRY xdata *)LOCAL_BLOCK;
   uLogCount = LogFindCount();         // Find current number of log table
                                       // entries;

   printf ("\n");                      // Print list of commands;
   MENU_ListCommands ();

   State = STOPPED;                    // Global state is STOPPED; no data
                                       // is being logged;
   EA = 1;                             // Enable global interrupts;

	while (1)                           // Serial port command decoder;
   {
      key_press = getchar();           // Get command character;
      key_press = tolower(key_press);  // Convert to lower case;

      switch (key_press) 
      {
         case 'c':                     // Clear log;
           if(State == STOPPED)        // Only execute if not logging;
           {
            printf ("\n Clear Log\n");
            LogErase();                // erase log entries;
            uLogCount = LogFindCount();// update global log entry count;
           }
           break;
         case 'd':                     // Display log;
           if(State == STOPPED)        // Only execute if not logging;
           {
            printf ("\n Display Log\n");
            LogPrint();                // Print the log entries;
           }
           break;
         case 'i':                     // Init RTC;
           if(State == STOPPED)        // Only execute if not logging;
           {
            printf ("\n Init RTC values\n");
            EA = 0;                    // Disable interrupts;
            LogInit(&LogRecord);       // Clear current time;
            EA = 1;                    // Reenable interrupts;
           }
           break;
         case 'p':                     // Stop logging;
           if(State != STOPPED)        // Only execute if not stopped already;
           {
            State = FINISHED;          // Set state to FINISHED
            printf ("\n Stop Logging\n");
            while(State != STOPPED){}  // Wait for State = STOPPED;
           }
           break;
         case 's':                     // Start logging
           if(State == STOPPED)        // Only execute if not logging;
           {
            printf ("\n Start Logging\n");
            State = RUNNING;           // Start logging data
           }
           break;
         case '?':                     // List commands;
           if(State == STOPPED)        // Only execute if not logging;
           {
            printf ("\n List Commands\n");
            MENU_ListCommands();       // List Commands
           }
           break;
         default:                      // Indicate unknown command;
           if(State == STOPPED)        // Only execute if not logging;
           {
            printf ("\n Unknown command: '%x'\n", key_press);
            MENU_ListCommands();       // Print Menu again;
           }
           break;
      } // switch
   } // while
}

//-----------------------------------------------------------------------------
// Support Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// MENU_ListCommands
//-----------------------------------------------------------------------------
// This routine prints a list of available commands.
//
void MENU_ListCommands (void)
{
   printf ("\nData logging example version %s\n", VERSION);
   printf ("Copyright 2004 Silicon Laboratories.\n\n");
   printf ("Command List\n");
   printf ("===============================================\n");
   printf (" 'c' - Clear Log\n");
   printf (" 'd' - Display Log\n");
   printf (" 'i' - Init RTC\n");
   printf (" 'p' - Stop Logging\n");
   printf (" 's' - Start Logging\n");
   printf (" '?' - List Commands\n");
   printf ("\n");
}

//-----------------------------------------------------------------------------
// Logging Subroutines
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// LogUpdate()
//-----------------------------------------------------------------------------
// This routine is called by the ADC ISR at ~1Hz if State == RUNNING or 
// FINISHED.  Here we read the decimated ADC value, convert it to temperature 
// in hundredths of a degree C, and add the log entry to the log table buffer.  
// If the buffer is full, or the user has stopped the logger, we must commit 
// the buffer to the MMC FLASH.  <State> determines if the system is logging 
// normally (State == RUNNING), or if the user has stopped the logging 

⌨️ 快捷键说明

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