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

📄 rtc.c

📁 Analog 公司 ADE7169 SOC 电表方案DEMO程序
💻 C
字号:
/*
-02/24/2006: Petre M.
  -this file contains functions that deal with Real Time Clock
*/

#include "ioADE7169F16.h"
#include "extern_declarations.h"
#include "EEPROM_locations.h"


//this function initializes the RTC
void Setup_RTC(void) {

  //!!!!!!!!!!!!all these settings of the time and date should be
  //introduced using UART. They should be at a certain point eliminated!!!!!!!!!!!!!!!!!!!!!!!
  //disable RTC in order to synchronize the time with the Date
//  TIMECON_bit.RTCEN = 0;
  //set the initial time at 00:00:00
//  SEC = 30;
//  MIN = 59;
//  HOUR= 23;
//////////////////////////////////////////////////////////////////////////////
  /*x=MIDNIGHT is a status bit
     1=24 hour mode
      00=interval timer is based on 1/128 seconds
        0=interval timer is set after 1 time interval
         x=ALARM is a status bit
          1=interval timer is enabled
           1=RTC enabled
  */
  TIMECON = (TIMECON & (NBit5 & NBit4 & NBit3)) | (Bit6 | Bit1 | Bit0);

  //every 0.5sec=64 1/128 sec, the interval timer generates an interrupt
  INTVAL = 64;

  //read RTCCOMP value from EEPROM
  Tx_CTRL_byte(Nr_Bytes_1, RTCCOMP_val,(unsigned char __idata  *)&Temporary[0]);
  RTCCOMP = Temporary[0];

  //RTC interrupt with Low Priority (Bit6=PTI=0)
  //Enable RTC interrupt (Bit2=ETI=1)
  IEIP2_bit.PTI = 0;

  //enable RTC interrupt
  IEIP2_bit.ETI = 1;

  return;
}

//this function is called in PSM1 mode and only enables the RTC interrupt
void Setup_RTC_PSM1(void) {

  /*x=MIDNIGHT is a status bit
     1=24 hour mode
      00=interval timer is based on 1/128 seconds
        0=interval timer is set after 1 time interval
         x=ALARM is a status bit
          0=interval timer disabled
           1=RTC enabled
  */
  TIMECON = (TIMECON & (NBit5 & NBit4 & NBit3 & NBit1)) | (Bit6 | Bit0);

  INTVAL = 64;

  //RTC interrupt with Low Priority
  IEIP2_bit.PTI = 0;

  //enable RTC interrupt
  IEIP2_bit.ETI = 1;



  return;
}

//this function modifies the calendar and stores it into EEPROM
void Update_calendar(void) {
  char __code const *iram_ptr1;
  char Month_length;

  //increment the weekday. It varies between 0 and 6, 0=Sunday, 6=Saturday
  Date.Weekday = Date.Weekday +1;
    if (Date.Weekday>6)
      Date.Weekday = 0;

    Date.Day = Date.Day + 1;

    iram_ptr1 = &Months[0];

    //read the length of the current Month
    Month_length = *(iram_ptr1+Date.Month-1);

    //a leap year is defined as a year divisible by 4. But if the number is
    //divisible by 100, then it must be divisible by 400 to be leap year
    //Because we represent only years between 2000 and 2099, and the next leap year
    //divisible by 400 is 2400, we don't need to verify if the year is divisible by 400.
    //In the leap year case, if Date.Month=2, Month_length=29

    if ((Date.Year & 0x03) == 0x00) {
      if (Date.Month==2) {
        Month_length = 29;
      }
    }

    //if the end of month is reached, then set Day=1 and Month++
    if (Date.Day > Month_length) {
      Date.Day = 1;
      Date.Month = Date.Month + 1;

      //order monthly storing of the energies in the EEPROM because
      //this is the end of the month
      Set_flag(Bit5,&Low_Priority_Command[0]);

      //if end of the year, Month=1 and Year++
      if (Date.Month == 13) {
        Date.Month = 1;

        //the year is incremented. It varies only between 0 and 99
        Date.Year = Date.Year + 1;
        if (Date.Year>99)
          Date.Year=0;

      }
    }

    //start the storage of the bytes representing the
    //energies at Day_Ac_Energy address into EEPROM
    Active_Energy_write();

    //the new updated Calendar is stored into EEPROM
    Calendar_write();

  return;
}

//this function updates the calendar and stores it into EEPROM
void Midnight_Management(void) {

  //update the calendar only if a Midnight event has been ordered
  if (TIMECON_bit.MIDNIGHT) {
    //clear MIDNIGHT flag
    TIMECON_bit.MIDNIGHT = 0;

    //update calendar and store it together with the energy into EEPROM
    Update_calendar();
  }

  return;
}

//this function manages the Midnight event in PSM1 mode.
//The ALARM bit in TIMECON is disabled in PSM1 and PSM2 modes. For this
//reason, the midnight event does not trigger an interrupt and therefore
//the program tests TIMECON_bit.MIDNIGHT instead of Bit2 of Low_Priority_Command[0]
//It waits until the EEPROM storage finishes because in PSM1
//there is no loop to execute other tasks
void Midnight_Management_PSM1(void) {

  //update the calendar only if a Midnight event has been ordered
  if (TIMECON_bit.MIDNIGHT) {
    //clear MIDNIGHT flag
    TIMECON_bit.MIDNIGHT = 0;

    //first, bring energies and current Date from EEPROM and
    //wait until data arrives in IRAM
    Reload_from_EEPROM();

    //update calendar and store it together with the energy into EEPROM
    Update_calendar();

    //we read this byte to ensure the write process ends before the processor enters in sleep mode
    Tx_CTRL_byte(Nr_Bytes_1, EEPROM_Fault_Days,&Fault_Days);

  }

  return;
}

//this function writes the Calendar into EEPROM
void Calendar_write(void) {

  Tx_byte(Nr_Bytes_4, EEPROM_Date,(unsigned char __idata *)&Date.Weekday);
  return;
}

//this function reads the Calendar from EEPROM
void Calendar_read(void) {

  Tx_CTRL_byte(Nr_Bytes_4, EEPROM_Date,(unsigned char __idata *)&Date.Weekday);

  return;
}


//this function stores SEC, MIN and HOUR registers in a buffer indicated by the pointer
//Buffer[0]=HTHSEC
//Buffer[1]=SEC
//Buffer[2]=MIN
//Buffer[3]=HOUR
void Store_time(char __idata *ptr) {
  char a, b, c, d;

  IE_bit.EA = 0;//disable all interrupts

    a=HTHSEC;
    b=SEC;
    c=MIN;
    d=HOUR;
    if (a!=HTHSEC){
      b=SEC;
      c=MIN;
      d=HOUR;
    }

  IE_bit.EA = 1;//enable all interrupts

  *ptr = a;
  *(ptr+1) = b;
  *(ptr+2) = c;
  *(ptr+3) = d;

  return;
}






⌨️ 快捷键说明

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