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

📄 mmc_datalogger_eeprom.c

📁 C8051F340读写SD卡的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
//-----------------------------------------------------------------------------
// MMC_DataLogger_EEPROM.c
//-----------------------------------------------------------------------------
// Copyright 2003 Silicon Laboratories
//
// AUTH: BW / JS / GV
// DATE: 8 MAR 04
//
// This software shows an example of a data logging application that maintains
// the log on an MMC card.  In addition, this software uses an external EEPROM
// to buffer MMC data.  This removes the need to buffer large amounts of data in
// on-chip external memory.
//
// Control Function:
//
// The system is controlled via the hardware UART, operating at a baud rate
// determined by the constant <BAUDRATE>, using Timer1 overflows as the baud
// rate source.  The commands are as follows (not case sensitive):
//  'c' - Clear Log
//  'd' - Display Log
//  'i' - Init RTC
//  'p' - Stop Logging
//  's' - Start Logging
//  '?' - List Commands
//
// Sampling Function:
//
// The ADC is configured to sample the on-chip temperature sensor at 4.096kHz,
// using Timer0 (in 8-bit auto-reload mode) as the start-of-conversion source.
// The ADC result is accumulated and decimated by a factor of 4096, yielding
// a 16-bit resolution quantitity from the original 10-bit sample at an
// effective output word rate of about 1Hz.  This decimated value is
// stored in the global variable <result>.
//
// A note about oversampling and averaging as it applies to this temp
// sensor example:  The transfer characteristic of the temp sensor on the
// 'F320 family of devices is 2.86mV/C.  The LSB size of the ADC using the
// internal VREF (2.43V) as its voltage reference is 2.3mV/code.
// This means that adjacent ADC codes are about ~1 degrees C apart.
//
// If we desire a higher temperature resolution, we can achieve it by
// oversampling and averaging (See AN118 on the Silicon labs website).  For
// each additional bit of resolution required, we must oversample by a power
// of 4.  For example, increasing the resolution by 4 bits requires
// oversampling by a factor of 4^4, or 256.
//
// By what factor must we oversample to achieve a temperature resolution to
// the nearest hundredth of a degree C?  In other words, "How may bits of
// resolution do we need to add?"  The difference between 1 degrees C and
// 0.01 degrees C is a factor of 100 (100 is between 2^6 and 2^7, so we need
// somewhere between 6 and 7 more bits of resolution).  Choosing '6 bits',
// we calculate our oversampling ratio to be 4^6, or 4096.
//
// A note about accuracy:  oversampling and averaging provides a method to
// increase the 'resolution' of a measurement.  The technique does nothing
// to improve a measurement's 'accuracy'.  Just because we can measure a
// 0.01 degree change in temperature does not mean that the measurements
// are accurate to 0.01 degrees.  Some possible sources of inaccuracies in
// this system are:
//  1. manufacturing tolerances in the temperature sensor itself (transfer
//     characteristic variation)
//  2. VDD or VREF tolerance
//  3. ADC offset, gain, and linearity variations
//  4. Device self-heating
//
// Temperature Clock Function:
//
// The temperature clock maintains a record of days, hours, minutes, and 
// seconds.  The current time record is stored with the temperature value
// in each log entry.  Clock updates are performed in the ADC end-of-conversion
// ISR at approximately once every second.
//
// Storage Function:
//
// MMC FLASH is used for storing the log entries.  Each entry contains
// the temperature in hundredths of a degree C, the day, hour, minute, and
// second that the reading was taken.  The LogUpdate function stores log
// entries in an EEPROM buffer and then writes that buffer out to the
// MMC when it is full.  Communication with the MMC is performed through the 
// MMC access functions.  These functions provide transparent MMC access to 
// the higher level functions (logging functions).  The MMC interface is broken
// into two pieces.  The high level piece consists of the user callable MMC
// access functions (MMC_FLASH_Read, MMC_FLASH_Write, MMC_FLASH_Clear, 
// MMC_FLASH_MassErase).  These functions are called by the user to execute
// data operations on the MMC.  They break down the data operations into MMC
// commands.  The low level piece consists of a single command execution
// function (MMC_Command_Exec) which is called by the MMC data manipulation
// functions.  This function is called every time a command must be sent to the
// MMC.  It handles all of the required SPI traffic between the Cygnal device
// and the MMC.  Communication between the EEPROM and the Cygnal device is
// performed using SMBus.  
//
// Target: C8051F32x
// Tool chain: KEIL C51 6.03 / KEIL EVAL C51
//


//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------


#include <c8051f320.h>                 // SFR declarations
#include <stdio.h>                     // printf() and getchar()
#include <ctype.h>                     // tolower()

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F31x, 'F32x, 'F33x
//-----------------------------------------------------------------------------

sfr16 DP       = 0x82;                 // data pointer
sfr16 TMR2RL   = 0xca;                 // Timer2 reload value
sfr16 TMR2     = 0xcc;                 // Timer2 counter
sfr16 ADC0     = 0xbd;                 // ADC0 Data

//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define VERSION      "1.0"            // version identifier
#define TRUE         1
#define FALSE        0

#define START_SYSCLK 12000000
#define SYSCLK       START_SYSCLK * 2  // SYSCLK frequency in Hz
#define BAUDRATE     115200            // Baud rate of UART in bps
#define SAMPLE_RATE  4096              // Sample frequency in Hz
#define INT_DEC      4096              // integrate and decimate ratio

#define TEMP_OFFSET  50900000L         // Temp sensor offset constant used
                                       // in conversion of ADC sample to temp
                                       // value;
#define TEMP_SLOPE   187433L           // Temp sensor slope constant used
                                       // in conversion of ADC sample to temp
                                       // value;
#define TEMP_VREF    2430              // VREF offset constant used
                                       // in conversion of ADC sample to temp
                                       // value;

#define EEPROM_SIZE 32768
#define EEPROM_PAGE_SIZE 64

// Constants that define available card sizes, 8MB through 128MB                                       
#define PS_8MB       8388608L
#define PS_16MB      16777216L
#define PS_32MB      33554432L
#define PS_64MB      67108864L
#define PS_128MB     134217728L

// Physical size in bytes of one MMC FLASH sector
#define PHYSICAL_BLOCK_SIZE     512    

// Erase group size = 16 MMC FLASH sectors
#define PHYSICAL_GROUP_SIZE     PHYSICAL_BLOCK_SIZE * 16

// Log table start address in MMC FLASH
#define LOG_ADDR     0x0000


// Size in bytes for each log entry
#define LOG_ENTRY_SIZE sizeof(LOG_ENTRY)

// Size of EEPROM buffer that stores table entries
// before they are written to MMC.
#define BUFFER_SIZE  LOG_ENTRY_SIZE * 10

// Command table value definitions
// Used in the MMC_Command_Exec function to 
// decode and execute MMC command requests
#define     EMPTY  0
#define     YES   1
#define     NO    0
#define     CMD   0
#define     RD    1
#define     WR    2
#define     R1    0
#define     R1b   1
#define     R2    2
#define     R3    3

// Start and stop data tokens for single and multiple
// block MMC data operations
#define     START_SBR      0xFE
#define     START_MBR      0xFE
#define     START_SBW      0xFE
#define     START_MBW      0xFC
#define     STOP_MBW       0xFD

// Mask for data response token after an MMC write
#define     DATA_RESP_MASK 0x11

// Mask for busy token in R1b response
#define     BUSY_BIT       0x80

// Command Table Index Constants:
// Definitions for each table entry in the command table.
// These allow the MMC_Command_Exec function to be called with a
// meaningful parameter rather than a number.
#define     GO_IDLE_STATE            0
#define     SEND_OP_COND             1
#define     SEND_CSD                 2
#define     SEND_CID                 3
#define     STOP_TRANSMISSION        4
#define     SEND_STATUS              5
#define     SET_BLOCKLEN             6
#define     READ_SINGLE_BLOCK        7
#define     READ_MULTIPLE_BLOCK      8
#define     WRITE_BLOCK              9
#define     WRITE_MULTIPLE_BLOCK    10
#define     PROGRAM_CSD             11
#define     SET_WRITE_PROT          12
#define     CLR_WRITE_PROT          13
#define     SEND_WRITE_PROT         14
#define     TAG_SECTOR_START        15
#define     TAG_SECTOR_END          16
#define     UNTAG_SECTOR            17
#define     TAG_ERASE_GROUP_START   18
#define     TAG_ERASE_GROUP_END     19
#define     UNTAG_ERASE_GROUP       20
#define     ERASE                   21
#define     LOCK_UNLOCK             22
#define     READ_OCR                23
#define     CRC_ON_OFF              24

// LOCAL_BLOCK is the start of an EEPROM buffer for incoming temperature data; 
// When this buffer is full, the page is written out to the MMC and erased for
// new data;
#define     LOCAL_BLOCK             0x1000
// SCRATCH_BLOCK is used by the high level MMC functions as temporary storage;
#define     SCRATCH_BLOCK           0x0000

// SMBus Definitions

#define  SMB_FREQUENCY  300000         // Target SCL clock rate

#define  WRITE          0x00           // SMBus WRITE command
#define  READ           0x01           // SMBus READ command

// Device addresses (7 bits, lsb is a don't care)
#define  EEPROM_ADDR    0xA0           // Device address for slave target
                                       // Note: This address is specified
                                       // in the Microchip 24LC02B
                                       // datasheet.
// SMBus Buffer Size
#define  SMB_BUFF_SIZE  0x08           // Defines the maximum number of bytes
                                       // that can be sent or received in a
                                       // single transfer

// Status vector - top 4 bits only
#define  SMB_MTSTA      0xE0           // (MT) start transmitted
#define  SMB_MTDB       0xC0           // (MT) data byte transmitted
#define  SMB_MRDB       0x80           // (MR) data byte received
// End status vector definition

//-----------------------------------------------------------------------------
// UNIONs, STRUCTUREs, and ENUMs
//-----------------------------------------------------------------------------
typedef union LONG                     // byte-addressable LONG
{
   long l;
   unsigned char b[4];
} LONG;

typedef union INT                      // byte-addressable INT
{
   int i;
   unsigned char b[2];
} INT;

typedef union                          // byte-addressable unsigned long
{
      unsigned long l;
      unsigned char b[4];
           
} ULONG;

typedef union UINT                     // byte-addressable unsigned int
{
      unsigned int i;
      unsigned char b[2];

⌨️ 快捷键说明

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