143 lines
4.4 KiB
C
143 lines
4.4 KiB
C
#ifndef __TIME_C
|
|
#define __TIME_C
|
|
|
|
#include "cmos.h"
|
|
|
|
static const char* clock_months[] = {0,
|
|
"January", "February", "March", "April", "May", "June",
|
|
"July", "August", "September", "October", "November", "December"};
|
|
static const char* clock_weekdays[] = {0,
|
|
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
|
|
|
|
byte clock_months_len[] = {
|
|
0,
|
|
31, // January
|
|
28, // February
|
|
31, // March
|
|
30, // April
|
|
31, // May
|
|
30, // June
|
|
31, // July
|
|
31, // August
|
|
30, // September
|
|
31, // October
|
|
30, // November
|
|
31 // December
|
|
};
|
|
|
|
typedef struct {
|
|
byte seconds;
|
|
byte minutes;
|
|
byte hours;
|
|
byte weekday;
|
|
byte day;
|
|
byte month;
|
|
byte year;
|
|
byte century;
|
|
byte am_pm;
|
|
|
|
} TIME;
|
|
volatile static TIME clock;
|
|
|
|
void RTC_get_time()
|
|
{
|
|
cmos_read();
|
|
|
|
if ((cmos_data[0x0b]&4)==0) // BCD = true;
|
|
{
|
|
clock.seconds = (cmos_data[0x00]%16) + 10*(cmos_data[0x00]/16);
|
|
clock.minutes = (cmos_data[0x02]%16) + 10*(cmos_data[0x02]/16);
|
|
if ((cmos_data[0x0b]&2)==0) { // AM/PM
|
|
if (cmos_data[0x04]&80) { // pm
|
|
clock.hours = ((cmos_data[0x04]-0x80)%16) + 10*((cmos_data[0x04]-0x80)/16);
|
|
clock.am_pm = 1;
|
|
}
|
|
else { // am
|
|
clock.hours = (cmos_data[0x04]%16) + 10*(cmos_data[0x04]/16);
|
|
clock.am_pm = 0;
|
|
}
|
|
}
|
|
else { // 24 hours
|
|
clock.hours = (cmos_data[0x04]%16) + 10*(cmos_data[0x04]/16);
|
|
if (clock.hours > 12) {
|
|
clock.am_pm = 1;
|
|
clock.hours -= 12;
|
|
}
|
|
else clock.am_pm = 0;
|
|
}
|
|
|
|
clock.weekday = (cmos_data[0x06]%16) + 10*(cmos_data[0x06]/16);
|
|
clock.day = (cmos_data[0x07]%16) + 10*(cmos_data[0x07]/16);
|
|
clock.month = (cmos_data[0x08]%16) + 10*(cmos_data[0x08]/16);
|
|
clock.year = (cmos_data[0x09]%16) + 10*(cmos_data[0x09]/16);
|
|
clock.century = (cmos_data[0x32]%16) + 10*(cmos_data[0x32]/16);
|
|
}
|
|
|
|
else {//BCD = false;
|
|
clock.seconds = cmos_data[0x00];
|
|
clock.minutes = cmos_data[0x02];
|
|
if ((cmos_data[0x0b]&2)==0) { // AM/PM
|
|
if (cmos_data[0x04]&80) { // pm
|
|
clock.hours = cmos_data[0x04]-0x80;
|
|
clock.am_pm = 1;
|
|
}
|
|
else { // am
|
|
clock.hours = cmos_data[0x04];
|
|
clock.am_pm = 0;
|
|
}
|
|
}
|
|
else { // 24 hours
|
|
clock.hours = cmos_data[0x02];
|
|
if (clock.hours > 12) {
|
|
clock.am_pm = 1;
|
|
clock.hours -= 12;
|
|
}
|
|
else clock.am_pm = 0;
|
|
}
|
|
clock.weekday = cmos_data[0x06];
|
|
clock.day = cmos_data[0x07];
|
|
clock.month = cmos_data[0x08];
|
|
clock.year = cmos_data[0x09];
|
|
clock.century = cmos_data[0x32];
|
|
}
|
|
// Leap years
|
|
if (clock.year % 4 == 0) clock_months_len[2]=29;
|
|
|
|
}
|
|
|
|
void clock_inc()
|
|
{
|
|
// New minute
|
|
if (++clock.seconds > 59) {
|
|
clock.seconds = 0;
|
|
// New hour
|
|
if (++clock.minutes > 59) {
|
|
clock.minutes = 0;
|
|
clock.hours++;
|
|
if (clock.hours == 12 && clock.am_pm == 1) { // 11:59pm -> 0:00am
|
|
clock.hours = 0; clock.am_pm = 0;
|
|
// New day
|
|
clock.weekday = 1+(clock.weekday%7);
|
|
// New month
|
|
if (++clock.day > clock_months_len[clock.month]) {
|
|
clock.day = 1;
|
|
// New year
|
|
if (++clock.month>12) {
|
|
clock.month = 1;
|
|
// New century
|
|
if (++clock.year > 99) {
|
|
clock.year = 0;
|
|
clock.century++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (clock.hours == 12 && clock.am_pm == 0) // 11:59am -> 12:00pm
|
|
clock.am_pm = 1;
|
|
else if (clock.hours == 13 && clock.am_pm == 1) // 12:59pm -> 1:59pm
|
|
clock.hours = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif |