📄 rtc.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 + -