📄 rtc.c
字号:
//*****************************************************************************
//
// File........: RTC.c
//
// Author(s)...: ATMEL Norway
//
// Target(s)...: ATmega169
//
// Compiler....: IAR EWAAVR 2.27b
//
// Description.: Real Time Clock (RTC)
//
// Revisions...: 1.0
//
// YYYYMMDD - VER. - COMMENT - SIGN.
//
// 20021015 - 1.0 - Created - LHM
//
//*****************************************************************************
// Include files
#include "Main.h"
#include "RTC.h"
// Lookup table used to determine the highest date in a specific month
unsigned char MaxDate[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/******************************************************************************
*
* Function name: Start_Timer2
*
* returns: none
*
* parameters: none
*
* Purpose: Start Timer/Counter2 in asynchronous operation using a
* 32.768kHz crystal.
*
*******************************************************************************/
void RTC_init(void)
{
Delay(1000); // wait for 1 sec to let the Xtal stabilize after a power-on,
__disable_interrupt(); // disabel global interrupt
TIMSK2 = 0; // disable OCIE2A and TOIE2
ASSR = (1<<AS2); // select asynchronous operation of Timer2
TCNT2 = 0; // clear TCNT2A
TCCR2A = (1<<CS22) | (1<<CS20); // select precaler: 32.768 kHz / 128 = 1 sec between each overflow
while((ASSR & 0x01) | (ASSR & 0x04)); // wait for TCN2UB and TCR2UB to be cleared
TIFR2 = 0xFF; // clear interrupt-flags
TIMSK2 = (1<<TOIE2); // enable Timer2 overflow interrupt
__enable_interrupt(); // enable global interrupt
// initial time and date setting
HOUR = 8;
MINUTE = 0;
SECOND = 0;
DAY = 4;
MONTH = 11;
YEAR_LO = 2;
YEAR_HI = 20;
}
/******************************************************************************
*
* Function name: Time_update
*
* returns: None
*
* parameters: None
*
* Purpose: Updates the time and date variables
*
*******************************************************************************/
void Time_update(void)
{
unsigned char LeapYear = FALSE;
//the variable SECOND gets updated in the Timer0 Overflow Interrupt Routine every second
if(SECOND > 59) // if one minute
{
SECOND = 0; // clear SECOND
MINUTE++; // increment MINUTE
if(MINUTE > 59) // if one hour
{
MINUTE = 0; // clear MINUTE
HOUR++; // increment HOUR
if(HOUR > 23) // if one hour
{
HOUR = 0; // clear HOUR
DAY++; // increment DAY
if(MONTH == 2) // if it's February
{
// check for leap year
if(!YEAR_LO) // if YEAR_LO = 0, (a century has passed)
{
if(!(YEAR_HI%4)) // check if YEAR_HI is divisible by 4
LeapYear = TRUE; // then it is a leap year
}
else if(!(YEAR_LO%4) & (YEAR_LO != 0)) // else if YEAR_LO is divisible by 4 and not zero
LeapYear = TRUE; // then it's a leap year
}
if(DAY > (MaxDate[MONTH] + LeapYear)) // if a whole month has passed
{
DAY = 1; // clear DAY
MONTH++; // increment MONTH
if(MONTH > 12) // if one year
{
MONTH = 1; // clear MONTH
YEAR_LO++; // increment YEAR_LO
if(YEAR_LO > 99) // if one century
{
YEAR_LO = 0; // clear YEAR_LO
YEAR_HI++; // increment YEAR_HI
if(YEAR_HI > 99) // if 100 centuries
YEAR_HI = 0; // the AVR is still going strong :)
}
}
}
}
}
}
}
/******************************************************************************
*
* Timer/Counter2 Overflow Interrupt Routine
*
* Purpose: Increment the varible SECOND by one.
*
*******************************************************************************/
#pragma vector = TIMER2_OVF_vect
__interrupt void TIMER2_OVF_interrupt(void)
{
SECOND++; // increment second
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -