f41x_rtc_suspend.c

来自「芯科原厂所有c8051fxx程序的例子。」· C语言 代码 · 共 468 行 · 第 1/2 页

C
468
字号
//
// This function will implement a delay using T0 and the RTC 32.768 kHz clock.
// A delay time of 32768 counts is equal to one second. This function modifies
// the system clock and exits with a 24.5 MHz clcok.
//-----------------------------------------------------------------------------

void delay (unsigned int time)

{
   TCON    &= ~0x30;                   // stop T0 & clear flag
   TMOD    &= ~0x0F;                   // clear T0 nibble of TMOD
   TMOD    |= 0x01;                    // T0 16 bit counter mode
   CKCON   |= 0x04;                    // T0 uses SYSCLK
   // set T0 using time
   time = -time;
   TL0      = (unsigned char)(time & 0x00FF);
   TH0      = (unsigned char)(time >> 8);
   //switch to low freq oscillator
   CLKSEL   = 0x03;                    // Switch to RTC clock
   TCON    |= 0x10;                    // enable T0
   while (!TF0);                       // wait for TOF
   TCON    &= ~0x30;                   // stop T0 & clear flag
   OSCICN    =  0x87;                  // enable 24.5 MHz int osc
   CLKSEL    = 0x00;                   // use int osc
}

//=============================================================================
// Interrupt Service Routines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// T0ISR ()
//-----------------------------------------------------------------------------

void RTC_ISR (void) interrupt 8        // RTC
{
   RTC_ClearBits (RTC0CN, 0x0C);       // clear RTCAEN and ALARM bits
   RTC_BumpAlarm (RTC_Interval);       // Add RTC interval to ALARMn
   RTC_SetBits (RTC0CN, 0x08);         // enable RTC alarm
}

//=============================================================================
// RTC Primitive Fuctions - used for read, write, and bit twiddling
//-----------------------------------------------------------------------------
// RTC_Read ()
//-----------------------------------------------------------------------------
//
// Return Value : RTC0DAT
// Parameters   : 1) unsigned char reg - address of RTC register to read
//
// This function will read one byte from the specified RTC register.
// Using a register number greater that 0x0F is not permited,
//
//-----------------------------------------------------------------------------

#pragma DISABLE
unsigned char RTC_Read (unsigned char reg)
{
   reg &= 0x0F;                        // mask low nibble
   RTC0ADR  = reg;                     // pick register
   RTC0ADR |= 0x80;                    // set BUSY bit to read
   while ((RTC0ADR & 0x80) == 0x80);   // poll on the BUSY bit
   return RTC0DAT;                     // return value
}

//-----------------------------------------------------------------------------
// RTC_Write ()
//-----------------------------------------------------------------------------
//
// Return Value : none
// Parameters   : 1) unsigned char reg - address of RTC register to write
//                2) unsigned char value - the value to write to <reg>
//
// This function will Write one byte from the specified RTC register.
//
//-----------------------------------------------------------------------------

#pragma DISABLE
void RTC_Write (unsigned char reg, unsigned char value)
{
   reg &= 0x0F;                        // mask low nibble
   RTC0ADR  = reg;                     // pick register
   RTC0DAT = value;                    // write data
   while ((RTC0ADR & 0x80) == 0x80);   // poll on the BUSY bit
}

//-----------------------------------------------------------------------------
// RTC_SetBits ()
//-----------------------------------------------------------------------------
//
// Return Value : none
// Parameters   : 1) unsigned char reg - address of RTC register to set
//                2) unsigned char value - bitmask for the register
//
// This function will set bits in the specified RTC register using the
// supplied bit mask. This function can only be used with an RTC register.
// Using a register number greater that 0x0F is not permited,
//
//-----------------------------------------------------------------------------

#pragma DISABLE
void RTC_SetBits (unsigned char reg, unsigned char value)
{
   reg &= 0x0F;                        // mask low nibble
   RTC0ADR  = reg;                     // pick register
   RTC0ADR |= 0x80;                    // set BUSY bit to read
   while ((RTC0ADR & 0x80) == 0x80);   // poll on the BUSY bit
   value  |= RTC0DAT;                  // read RTC0DAT and OR to set bits
   RTC0ADR  = reg;                     // overwrite autoincrement value
   RTC0DAT = value;                    // write to RTC0DAT
   while ((RTC0ADR & 0x80) == 0x80);   // poll on the BUSY bit
}

//-----------------------------------------------------------------------------
// RTC_ClearBits ()
//-----------------------------------------------------------------------------
//
// Return Value : none
// Parameters   : 1) unsigned char reg - address of RTC register to clear
//                2) unsigned char value - bitmask for the register
//
// This function will clear bits in the specified RTC register using the
// supplied bit mask, ones will be cleared.
//
// Note that writing to the ALARMn or CAPTUREn registers will autoincrement
// RTC0ADDR. So the RTC0ADDR register is set twice.
//
//-----------------------------------------------------------------------------

#pragma DISABLE
void RTC_ClearBits (unsigned char reg, unsigned char value)
{
   reg &= 0x0F;                        // mask low nibble
   value =~value;                      // complement mask
   RTC0ADR  = reg;                     // pick register
   RTC0ADR |= 0x80;                    // set BUSY bit to read
   while ((RTC0ADR & 0x80) == 0x80);   // poll on the BUSY bit
   value  &= RTC0DAT;                  // read RTC0DAT and AND to clear bits
   RTC0ADR  = reg;                     // overwrite autoincrement value
   RTC0DAT = value;                    // write to RTC0DAT
   while ((RTC0ADR & 0x80) == 0x80);   // poll on the BUSY bit
}

//-----------------------------------------------------------------------------
// RTC_ClearCapture ()
//-----------------------------------------------------------------------------
//
// Return Value : none
// Parameters   : none
//
// This function will clear all six CAPTURE registers of the RTC.
//
//-----------------------------------------------------------------------------

#pragma DISABLE
void RTC_ClearCapture (void)
{
   unsigned char n;

   for (n=0;n<6;n++)                   // n = 0-5 for CAPTURE0-5
   {
      RTC0ADR = n;                     // select CAPTUREn register
      RTC0DAT = 0x00;                  // clear data
      while ((RTC0ADR & 0x80) == 0x80);// poll on the BUSY bit
   }
}

//-----------------------------------------------------------------------------
// RTC_ClearAlarm ()
//-----------------------------------------------------------------------------
//
// Return Value : none
// Parameters   : none
//
// This function will clear all six ALARM registers of the RTC.
//
//-----------------------------------------------------------------------------

#pragma DISABLE
void RTC_ClearAlarm (void)
{
   unsigned char n;

   for (n=8;n<14;n++)                  // n = 8-13 for ALARM0-5
   {
      RTC0ADR = n;                     // select ALARMn
      RTC0DAT = 0x00;                  // clear data
      while ((RTC0ADR & 0x80) == 0x80);// poll on the BUSY bit
   }
}

//-----------------------------------------------------------------------------
// RTC_BumpAlarm ()
//-----------------------------------------------------------------------------
//
// Return Value : none
// Parameters   : pointer to 6 byte value stored in code flash memory
//
// This function will add the 48-bit value located by the supplied pointer
// to the 48-bit value in the ALARM registers. The new sum is calculated
// byte-by-byte and store back into the ALARM registers. This is more efficient
// that reading all six bytes, adding, and writing back.
//
// Note Autoread is not used. However the RTC0ADDR register is
// auto-incremented. So the RTC0ADR must be set a second time.
//
//-----------------------------------------------------------------------------

#pragma DISABLE
void RTC_BumpAlarm (unsigned char code *p)
{
   unsigned char n;
   unsigned int sum;

   sum = 0;

   for (n=8;n<14;n++)                  // n = 8-13 for ALARM0-5
   {
      RTC0ADR = n;                     // select ALARMn
      RTC0ADR |= 0x80;                 // set BUSY bit to initiate read
      while ((RTC0ADR & 0x80) == 0x80);// poll on the BUSY bit
      sum += RTC0DAT;                  // add to sum
      sum += *p++;                     // add constant value
      RTC0ADR = n;                     // select ALARMn again
      RTC0DAT = (unsigned char)(sum);  // write sum LSB
      while ((RTC0ADR & 0x80) == 0x80);// poll on the BUSY bit
      sum = sum>>8 ;                   // save remainder
   }
}

//-----------------------------------------------------------------------------
// End of File
//-----------------------------------------------------------------------------

⌨️ 快捷键说明

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