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

📄 mmc_datalogger.c

📁 F320 mmc data logger
💻 C
📖 第 1 页 / 共 5 页
字号:
//-----------------------------------------------------------------------------
// MMC_DataLogger.c
//-----------------------------------------------------------------------------
// Copyright 2004 Silicon Laboratories
//
// AUTH: BW / JS / GV
// DATE: 08 MAR 04
//
// This program shows an example of a data logging application that maintains
// the log on an MMC card.
//
// 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 external memory 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 Silicon Labs
// device and the MMC.
//
// 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 'F32x
//-----------------------------------------------------------------------------

sfr16 DP       = 0x82;                 // data pointer
sfr16 TMR2RL   = 0xca;                 // Timer2 reload value
sfr16 TMR2     = 0xcc;                 // Timer2 counter
sfr16 PCA0CP1  = 0xe9;                 // PCA0 Module 1 Capture/Compare
sfr16 PCA0CP2  = 0xeb;                 // PCA0 Module 2 Capture/Compare
sfr16 PCA0     = 0xf9;                 // PCA0 counter
sfr16 PCA0CP0  = 0xfb;                 // PCA0 Module 0 Capture/Compare
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 FULL_SCALE   65536             // Full scale ADC0 value
#define PREC_FACTOR  1024              // This constant is used to preserve
                                       // precision during temperature calc;
                                       // VREF offset constant used (.01 mV)
#define VREF         243000
                                       // in conversion of ADC sample to temp
                                       // value;
                                       // Temp sensor offset constant used
#define V_OFFSET     77600 
                                       // in conversion of ADC sample to temp
                                       // value (.01 mV);
#define TEMP_SLOPE   2.86              // Temp sensor slope constant used
                                       // in conversion of ADC sample to temp
                                       // value;

// 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     0x00000000

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

#define BUFFER_ENTRIES 32

// Size of XRAM memory buffer that stores table entries
// before they are written to MMC
#define BUFFER_SIZE  LOG_ENTRY_SIZE * BUFFER_ENTRIES

// 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


sbit LED = P2^2;                       // LED='1' means ON
sbit SW2 = P2^0;                       // SW2='0' means switch pressed
sbit TX0 = P0^4;                       // UART0 TX pin
sbit RX0 = P0^5;                       // UART0 RX pin


//-----------------------------------------------------------------------------
// 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 {                        // byte-addressable unsigned int
      unsigned int i;
      unsigned char b[2];
              } UINT;

typedef struct LOG_ENTRY {             // (7 bytes per entry)
   int wTemp;                          // temperature in hundredths of a
                                       // degree
   unsigned int uDay;                  // day of entry
   unsigned char bHour;                // hour of entry
   unsigned char bMin;                 // minute of entry
   unsigned char bSec;                 // second of entry
   unsigned char pad;                  // dummy byte to ensure aligned access;
} LOG_ENTRY;
     
// The states listed below represent various phases of 
// operation;
typedef enum STATE {
   RESET,                              // Device reset has occurred;
   RUNNING,                            // Data is being logged normally;
   FINISHED,                           // Logging stopped, store buffer;
   STOPPED                             // Logging completed, buffer stored;
   } STATE;

// This structure defines entries into the command table;

⌨️ 快捷键说明

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