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

📄 data_logger_rtc.c

📁 C8051F系列CPU
💻 C
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------------
// Data_Logger_RTC.c
//-----------------------------------------------------------------------------
// Copyright 2002 Cygnal Integrated Products, Inc.
//
// AUTH: FB
// DATE: 30 SEP 02
//
//
// This application uses a 22.1184 MHz crystal oscillator to implement a 
// software real-time clock (RTC). PCA Module 0, configured to count Timer 0
// overflows in software timer mode, generates an interrupt every second.
// The interrupt handler records the current time and device temperature
// in a non-volatile log in FLASH. 
//
// With SYSCLK at 49.7664 MHZ, Timer 0 in mode 2 overflows exactly 4050 times 
// every second when clocked by SYSCLK/48. PCA0, clocked by Timer 0 overflows,
// is programmed to generate an interrupt every 4050 Timer 0 overflows, 
// or once every second.
//
// The 112,640 byte log cycles through all 4 code banks recording time and 
// temperature. Each data record is 8 bytes long. The log is capable of storing
// 14080 records over a time period of 3.9 hours. Once the log is full, it
// continues logging at the beginning of log, erasing the FLASH page with 
// the oldest data as it progresses.
//
// When this code is built, the linker generates two multiple call to segments
// warnings. These warnings are generated because the FLASH support routines
// are called from the main routine and from interrupts. These warnings have 
// been accounted for in the code by disabling interrupts before calling any
// FLASH support routines.
//
//
// Target: C8051F12x
// Tool chain: KEIL C51 6.03 / KEIL EVAL C51
//

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f120.h>                 // SFR declarations
#include <stdio.h>                     // printf() and getchar()

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F12x
//-----------------------------------------------------------------------------

sfr16 DP       = 0x82;                 // data pointer
sfr16 ADC0     = 0xbe;                 // ADC0 data
sfr16 ADC0GT   = 0xc4;                 // ADC0 greater than window
sfr16 ADC0LT   = 0xc6;                 // ADC0 less than window
sfr16 RCAP2    = 0xca;                 // Timer2 capture/reload
sfr16 RCAP3    = 0xca;                 // Timer3 capture/reload
sfr16 RCAP4    = 0xca;                 // Timer4 capture/reload
sfr16 TMR2     = 0xcc;                 // Timer2
sfr16 TMR3     = 0xcc;                 // Timer3
sfr16 TMR4     = 0xcc;                 // Timer4
sfr16 DAC0     = 0xd2;                 // DAC0 data
sfr16 DAC1     = 0xd2;                 // DAC1 data
sfr16 PCA0CP5  = 0xe1;                 // PCA0 Module 5 capture
sfr16 PCA0CP2  = 0xe9;                 // PCA0 Module 2 capture
sfr16 PCA0CP3  = 0xeb;                 // PCA0 Module 3 capture
sfr16 PCA0CP4  = 0xed;                 // PCA0 Module 4 capture
sfr16 PCA0     = 0xf9;                 // PCA0 counter
sfr16 PCA0CP0  = 0xfb;                 // PCA0 Module 0 capture
sfr16 PCA0CP1  = 0xfd;                 // PCA0 Module 1 capture

//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------

typedef union UInt {                   // Byte addressable unsigned int
   unsigned int Int;
   unsigned char Char[2];
} UInt;

typedef union Long {                   // Byte addressable long
   long Long;
   unsigned int Int[2];
   unsigned char Char[4];
} Long;

typedef union ULong {                  // Byte addressable unsigned long
   unsigned long ULong;
   unsigned int Int[2];
   unsigned char Char[4];
} ULong;

typedef struct Record {                // LOG record structure
   char start;
   unsigned int hours;
   unsigned char minutes;
   unsigned char seconds;
   unsigned int ADC_result;
   char end;
} Record;
   
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define TRUE         1
#define FALSE        0

#define EXTCLK       22118400          // External oscillator frequency in Hz
#define SYSCLK       49766400          // Output of PLL derived from 
                                       // (EXTCLK*9/4)

#define BAUDRATE     115200            // Baud rate of UART in bps
                                       // Note: The minimum standard baud rate
                                       // supported by the UART0_Init routine
                                       // in this file is 19,200 bps when
                                       // SYSCLK = 49.76MHz. 

#define SAMPLERATE   2000              // The ADC sampling rate in Hz

sbit LED = P1^6;                       // LED='1' means ON
sbit SW2 = P3^7;                       // SW2='0' means switch pressed

#define LOG_START 0x04000L             // Starting address of LOG
#define LOG_END   0x1F800L             // Last address in LOG + 1
#define RECORD_LEN 8                   // Record length in bytes
#define START_OF_RECORD ':'            // Start of Record symbol

#define FLASH_PAGESIZE 1024            // Number of bytes in each FLASH page

#define COBANK    0xF0                 // Bit mask for the high nibble of PSBANK

#define COBANK0   0x00                 // These macros define the bit mask values
#define COBANK1   0x10                 // for the PSBANK register used for
#define COBANK2   0x20                 // selecting COBANK. COBANK should always 
#define COBANK3   0x30                 // be cleared then OR-Equaled (|=) with 
                                       // the proper bit mask to avoid changing
                                       // the other bits in the PSBANK register


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

unsigned char SECONDS = 0;             // global RTC seconds counter
unsigned char MINUTES = 0;             // global RTC minutes counter
unsigned int  HOURS = 0;               // global RTC hours counter

unsigned int ADC_RESULT = 0;           // holds the oversampled and averaged
                                       // result from ADC0               


bit LOG_FLAG = 0;                      // this flag is used to enable 
                                       // and disable logging but does
                                       // not affect the real-time clock

bit LOG_ERASED = 0;                    // this flag indicates that the 
                                       // LOG has been erased.  
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------

void main(void);
void RTC_update(void);
void print_menu(void);

// initialization routines
void SYSCLK_Init(void);
void PORT_Init(void);
void UART0_Init (void);
void ADC0_Init (void);
void Timer3_Init(int counts);
void RTC_Init (void);
void PCA0_ISR (void);

// FLASH support routines
void FLASH_PageErase (unsigned long addr);
void FLASH_Write (unsigned long dest, char* src, unsigned int numbytes);
void FLASH_ByteWrite (unsigned long dest, char dat);
void FLASH_Read ( char* dest, unsigned long src, unsigned int numbytes);
unsigned char FLASH_ByteRead (unsigned long addr);

// LOG support routines

void print_time(void);
void LOG_erase(void);
unsigned long find_current_record(void);
void LOG_print(char all_at_once);
void LOG_update(void);


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

void main (void) 
{

   #define input_str_len 4             // buffer to hold characters entered
   char input_str[input_str_len];      // at the command prompt

   WDTCN = 0xde;                       // disable watchdog timer
   WDTCN = 0xad;

   PORT_Init ();                       // initialize crossbar and GPIO
   SYSCLK_Init ();                     // initialize oscillator
   UART0_Init ();                      // initialize UART0
   ADC0_Init();                        // initialize ADC0
   RTC_Init ();                        // initializes Timer0 and the PCA
   Timer3_Init(SYSCLK/SAMPLERATE);     // initialize Timer3 to overflow
                                       // and generate interrupts at 
                                       // <SAMPLERATE> Hz

                                       // to implement a real-time clock

   EA = 1;                             // enable global interrupts
   
   print_menu();                       // print the command menu
 

   while (1){

      SFRPAGE = UART0_PAGE;         
      printf("\nEnter a command > ");
      gets(input_str, input_str_len);
      
      switch ( input_str[0] ){
                      
         case '1': LOG_FLAG = 1;
                   SFRPAGE = UART0_PAGE;
                   printf("\nLogging has now started.\n");
                   break;

         case '2': LOG_FLAG = 0;
                   SFRPAGE = UART0_PAGE;
                   printf("\nLogging has now stopped.\n");
                   break;

         case '3': LOG_FLAG = 0;
                   LOG_erase();
                   SFRPAGE = UART0_PAGE;
                   printf("\nThe log has been erased and logging is stopped.\n");
                   break;
         
         case '4': LOG_print(FALSE);
                   print_menu();
                   break;
         
         case '5': LOG_print(TRUE);
                   print_menu();
                   break;

         case '6': print_time();
                   break;

         case '?': print_menu(); 
                   break;    

         default:  printf("\n*** Unknown Command.\n");
                   break;
      }   

   } // end while

} 


//-----------------------------------------------------------------------------
// RTC_update
//-----------------------------------------------------------------------------
//
//
void RTC_update(void)
{
   SECONDS++;
   if (SECONDS == 60) {
      SECONDS = 0;
      MINUTES++;
      if (MINUTES == 60) {
         MINUTES = 0;
         HOURS++;
      }
   }

}

//-----------------------------------------------------------------------------
// FLASH Support Routines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// FLASH_PageErase
//-----------------------------------------------------------------------------
//
// This function erases the FLASH page containing <addr>.
//
void FLASH_PageErase (unsigned long addr)
{
   char SFRPAGE_SAVE = SFRPAGE;        // Preserve current SFR page
   char PSBANK_SAVE = PSBANK;          // Preserve current code bank
   bit EA_SAVE = EA;                   // Preserve interrupt state
   
   ULong temp_addr;                    // Temporary ULong   
   char xdata * idata pwrite;          // FLASH write/erase pointer
   
   temp_addr.ULong = addr;             // copy <addr> to a byte addressable
                                       // unsigned long

   // Extract address information from <addr>
   pwrite = (char xdata *) temp_addr.Int[1];
   
   // Extract code bank information from <addr>
   PSBANK &= ~COBANK;                  // Clear the COBANK bits
   
   
   if( temp_addr.Char[1] == 0x00){     // If the address is less than
                                       // 0x10000, the Common area and 
      PSBANK |= COBANK1;               // Bank1 provide a 64KB linear 
                                       // address space   
   } else {                            // Else, Bank2 and Bank3 provide
                                       // a 64KB linear address space
      
      if (temp_addr.Char[2] & 0x80){   // If bit 15 of the address is 
                                       // a '1', then the operation should
         PSBANK |= COBANK3;            // target Bank3, else target Bank2
      
      } else { 
         
         PSBANK |= COBANK2;
         temp_addr.Char[2] |= 0x80;    
         pwrite = (char xdata *) temp_addr.Int[1];
      }
    }     
                                        
   SFRPAGE = LEGACY_PAGE;
      
   EA = 0;                             // Disable interrupts                 
   FLSCL |= 0x01;                      // Enable FLASH writes/erases
   PSCTL = 0x03;                       // MOVX erases FLASH page

   *pwrite = 0;                        // Initiate FLASH page erase

   FLSCL &= ~0x01;                     // Disable FLASH writes/erases
   PSCTL = 0x00;                       // MOVX targets XRAM

   EA = EA_SAVE;                       // Restore interrupt state
   PSBANK = PSBANK_SAVE;               // Restore current code bank
   SFRPAGE = SFRPAGE_SAVE;             // Restore SFR page
}

//-----------------------------------------------------------------------------
// FLASH_Write
//-----------------------------------------------------------------------------
//
// This routine copies <numbytes> from <src> to the FLASH addressed by <dest>.
//
void FLASH_Write (unsigned long dest, char* src, unsigned int numbytes)
{
   
   unsigned int i;                     // Software Counter
      
   for (i = 0; i < numbytes; i++) {
      
      FLASH_ByteWrite( dest++, *src++);
   }
}

⌨️ 快捷键说明

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