📄 mmc_datalogger.c
字号:
// process (State == FINISHED).
//
//
void LogUpdate (void)
{
idata ULONG voltage; // Long voltage value;
idata int temp_int, temp_frac; // Integer and fractional portions of
// Temperature;
// Count variable for number of
// Log entries in local buffer;
static idata unsigned int lLogCount = 0;
EA = 0; // Disable interrupts (precautionary);
voltage.l = Result.l; // Retrieve 32-bit ADC value;
EA = 1; // Re-enable interrupts;
// Calculate voltage in .01 millivolt;
// units;
voltage.l = voltage.l * ((VREF*PREC_FACTOR) / FULL_SCALE / TEMP_SLOPE);
// Handle temp sensor voltage offset;
voltage.l = voltage.l - ((V_OFFSET*PREC_FACTOR / TEMP_SLOPE));
voltage.b[4] = voltage.b[3]; // Scale down by PREC_FACTOR with a
voltage.b[3] = voltage.b[2]; // 10-bit shift; <voltage> now contains
voltage.b[2] = voltage.b[1]; // temperature value;
voltage.b[1] = voltage.b[0];
voltage.b[0] = 0;
voltage.l = voltage.l >> 2;
LogRecord.wTemp = (int)voltage.l; // Store temp value in temporary log
// entry;
if(uLogCount == 0) // If the FLASH table has been cleared,
{ // The local buffer is reset;
lLogCount = 0; // Reset number of local table entries;
// Reset local buffer pointer;
pLogTable = (LOG_ENTRY xdata *)LOCAL_BLOCK;
}
if(State == RUNNING) // Execute the following if the logger
{ // is logging normally;
// Check to see if the log table is
// full;
if ((uLogCount*LOG_ENTRY_SIZE) < LOG_SIZE)
{
*pLogTable = LogRecord; // Copy temporary log entry to buffer;
pLogTable++; // Increment buffer pointer;
lLogCount++; // Increment local log entry count;
uLogCount++; // Increment global log entry count;
// If the buffer is full, it must be
// written to FLASH;
if(lLogCount == (unsigned int)(BUFFER_SIZE / LOG_ENTRY_SIZE))
{
// Call FLASH Write function; Write to
// address pointed at by the global
// entry count less the local buffer
// count;
MMC_FLASH_Write((uLogCount -
(unsigned long)lLogCount)*LOG_ENTRY_SIZE,
(unsigned char xdata * )SCRATCH_BLOCK,
(unsigned char xdata *)LOCAL_BLOCK, BUFFER_SIZE);
lLogCount = 0; // Reset the local buffer size
// and pointer;
pLogTable = (LOG_ENTRY xdata *)LOCAL_BLOCK;
}
// Update display;
temp_int = LogRecord.wTemp / 100;
temp_frac = LogRecord.wTemp - ((long) temp_int * 100L);
printf (" %08lu\t", uLogCount);
printf ("%02u: ",(unsigned)LogRecord.uDay);
printf ("%02u:",(unsigned) LogRecord.bHour);
printf ("%02u:",(unsigned) LogRecord.bMin);
printf ("%02u ",(unsigned) LogRecord.bSec);
printf ("%+02d.%02d\n", temp_int, temp_frac);
}
else // If the FLASH table is full, stop
{ // logging data and print the full
State = STOPPED; // message;
printf ("Log is full\n");
}
}
else if(State == FINISHED) // If the data logger has been stopped
{ // by the user, write the local buffer
// to FLASH;
MMC_FLASH_Write((uLogCount - (unsigned long)lLogCount)*LOG_ENTRY_SIZE,
(unsigned char xdata * )SCRATCH_BLOCK,
(unsigned char xdata *)LOCAL_BLOCK,
lLogCount*LOG_ENTRY_SIZE);
lLogCount = 0; // Reset the local buffer size;
// and pointer;
pLogTable = (LOG_ENTRY xdata *)LOCAL_BLOCK;
State = STOPPED; // Set the state to STOPPED;
}
}
//-----------------------------------------------------------------------------
// LogFindCount()
//-----------------------------------------------------------------------------
// This function finds the number of entries already stored in the MMC log;
//
unsigned long LogFindCount()
{
unsigned long Count = 0; // Count variable, incremented as table
// entries are read;
unsigned long i = 0; // Address variable, used to read table
// table entries from FLASH;
LOG_ENTRY xdata *TempEntry; // Temporary log entry space;
// Initialize temp space in
// SCRATCH_BLOCK of external memory;
TempEntry = (LOG_ENTRY xdata *)SCRATCH_BLOCK;
// Loop through the table looking for a
// blank entry;
for (i=LOG_ADDR;i<LOG_SIZE;i += LOG_ENTRY_SIZE)
{
// Read one entry from address i of
// FLASH;
MMC_FLASH_Read((unsigned long)(i),(unsigned char xdata *) SCRATCH_BLOCK,
(unsigned int)LOG_ENTRY_SIZE);
// Check if entry is blank;
if ((TempEntry->bSec == 0x00)&&(TempEntry->bMin == 0x00)
&& (TempEntry->bHour == 0x00))
{
// If entry is blank, set Count;
Count = (i/LOG_ENTRY_SIZE) - LOG_ADDR;
break; // Break out of loop;
}
}
return Count; // Return entry count;
}
//-----------------------------------------------------------------------------
// LogErase
//-----------------------------------------------------------------------------
// This function clears the log table using the FLASH Mass Erase capability.
//
void LogErase (void)
{
// Call Mass Erase function with start
// of table as address and log size as
// length;
MMC_FLASH_MassErase(LOG_ADDR, LOG_SIZE);
uLogCount = 0; // Reset global count;
}
//-----------------------------------------------------------------------------
// LogPrint
//-----------------------------------------------------------------------------
// This function prints the log table. Entries are read one at a time, temp
// is broken into the integer and fractional portions, and the log entry is
// displayed on the PC through UART.
//
void LogPrint (void)
{
idata long temp_int, temp_frac; // Integer and fractional portions of
// temperature;
idata unsigned long i; // Log index;
unsigned char xdata *pchar; // Pointer to external mem space for
// FLASH Read function;
LOG_ENTRY xdata *TempEntry;
printf ("Entry#\tTime\t\tResult\n");// Print display column headers;
// Assign pointers to local block;
// FLASHRead function stores incoming
// data at pchar, and then that data can
// be accessed as log entries through
// TempEntry;
pchar = (unsigned char xdata *)LOCAL_BLOCK;
TempEntry = (LOG_ENTRY xdata *)LOCAL_BLOCK;
for (i = 0; i < uLogCount; i++) // For each entry in the table,
{ // do the following;
// Read the entry from FLASH;
MMC_FLASH_Read((unsigned long)(LOG_ADDR + i*LOG_ENTRY_SIZE), pchar,
(unsigned int)LOG_ENTRY_SIZE);
// break temperature into integer and fractional components
temp_int = (long) (TempEntry->wTemp) / 100L;
temp_frac = (long) (TempEntry->wTemp) - ((long) temp_int * 100L);
// display log entry
printf (" %lu\t%03u: %02u:%02u:%02u ", (i + 1),
TempEntry->uDay, (unsigned) TempEntry->bHour,
(unsigned) TempEntry->bMin,
(unsigned) TempEntry->bSec);
printf ("%+02ld.%02ld\n", temp_int, temp_frac);
}
}
//-----------------------------------------------------------------------------
// 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 local 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 the 16-bit card
// response value;
//
unsigned int MMC_Command_Exec (unsigned char cmd, unsigned long argument,
unsigned char *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;
unsigned long old_blklen = 512; // Temp variable to preserve data block
// 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;
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;
// Command byte = 16 means that a set
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -