|
|
View previous topic :: View next topic |
Author |
Message |
PICoHolic
Joined: 04 Jan 2005 Posts: 224
|
Software-based calendar (RTC) |
Posted: Thu Mar 26, 2009 7:30 am |
|
|
Here's a software-based calendar. Timer 1 is fed from an external 32.768 KHz crystal.
The calendar will still run in sleep mode.
Any comments/modifications/enhancements are welcome!
Code: |
#ifndef CALENDAR_H
#define CALENDAR_H
///////////////////////////////////////////////////////////////////////////////
#define EnableCalendar() enable_interrupts(INT_TIMER1)
#define DisableCalendar() disable_interrupts(INT_TIMER1)
///////////////////////////////////////////////////////////////////////////////
const char DaysStr[7][5] = {"SUN\0", "MON\0", "TUE\0", "WED\0", "THU\0", "FRI\0", "SAT\0"};
const char MonthsStr[12][4]= {"JAN", "FEB", "MAR", "ARP", "MAY", "JUN", "JUL",
"AUG", "SEP", "OCT", "NOV", "DEC"};
///////////////////////////////////////////////////////////////////////////////
#define IS_LEAP(year) (year%4 == 0)
///////////////////////////////////////////////////////////////////////////////
#define AM 0
#define PM 1
#define H_12 0
#define H_24 1
///////////////////////////////////////////////////////////////////////////////
typedef struct _calendar {
int8 Seconds;
int8 Minutes;
int8 Hours;
int8 DayOfWeek;
int8 Day;
int8 Month;
int8 Year;
int1 H_12_24;
int1 AM_PM;
}Calendar;
Calendar MyCalendar;
///////////////////////////////////////////////////////////////////////////////
void IncrementDate(void)
{
MyCalendar.DayOfWeek = (MyCalendar.DayOfWeek % 7) + 1; //increment day of week
MyCalendar.Day++; //increment day
if ( (MyCalendar.Day == 29 && MyCalendar.Month==2 && !IS_LEAP(MyCalendar.Year))
|| (MyCalendar.Day == 30 && MyCalendar.Month==2)
|| (MyCalendar.Day == 31 && (MyCalendar.Month==4 || MyCalendar.Month==6
|| MyCalendar.Month==9 || MyCalendar.Month==11 ))
|| (MyCalendar.Day == 32) )
{
MyCalendar.Day=1;
if(++MyCalendar.Month == 13)
{
MyCalendar.Month=1;
MyCalendar.Year++;
}
}
}
///////////////////////////////////////////////////////////////////////////////
void IncrementTime(void)
{
if (++MyCalendar.Seconds == 60) //increment seconds
{
MyCalendar.Seconds = 0; //clear seconds
if (++MyCalendar.Minutes == 60) //increment minutes
{
MyCalendar.Minutes = 0; //clear minutes
if (MyCalendar.H_12_24 == H_12) //12 hours
{
if (++MyCalendar.Hours == 13)
{
MyCalendar.Hours = 1;
if (MyCalendar.AM_PM == AM)
{
IncrementDate();
}
}
else if (MyCalendar.Hours == 12)
{
MyCalendar.AM_PM ^= 1;
}
}
else //24 hours
{
if (++MyCalendar.Hours == 24)
{
MyCalendar.Hours = 0;
IncrementDate();
}
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
int1 Sflg;
///////////////////////////////////////////////////////////////////////////////
#int_TIMER1 //Real Time Clock
void TIMER1_isr()
{
Bit_Set(TMR1H,7);
Sflg=true;
IncrementTime();
//one sec toggle
//#ASM btg PORTD, 4 #ENDASM
}
///////////////////////////////////////////////////////////////////////////////
void delay_s(int8 s)
{
while(s--)
{
Sflg = false;
while(!Sflg);
}
}
///////////////////////////////////////////////////////////////////////////////
void init_Calendar()
{
MyCalendar.Seconds = 00;
MyCalendar.Minutes = 00;
MyCalendar.Hours = 12;
MyCalendar.DayOfWeek = 5; //Thursday
MyCalendar.Day = 1; //1st
MyCalendar.Month = 1; //Jan
MyCalendar.Year = 9; //2009
MyCalendar.H_12_24 = H_12; //12 hours
MyCalendar.AM_PM = AM; //AM
bit_clear(T1CON,7);
EnableCalendar();
}
///////////////////////////////////////////////////////////////////////////////
#endif
|
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jan 11, 2012 4:47 pm |
|
|
Code: | const char DaysStr[7][5] = {"SUN\0", "MON\0", "TUE\0", "WED\0", "THU\0", "FRI\0", "SAT\0"}; | Quoted strings will be zero terminated by the compiler so this line can be simplified to: Code: | const char DaysStr[7][4] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"}; | Or, remove the whole line as it isn't used.
MonthsStr[] isn't used either and can be removed too. Strange but here you have not added the extra terminating zero, so why did you do it to the other line?
Code: | //one sec toggle
//#ASM btg PORTD, 4 #ENDASM | Easier to read and higher portability: Code: | //one sec toggle
//output_toggle(PIN_D4); |
Code: | void delay_s(int8 s)
{
while(s--)
{
Sflg = false;
while(!Sflg);
}
} | Why bother to create your own blocking delay function? The CCS delay_ms() is not perfect, but your delay_s function is not synchronized to the interrupt and can be as far off as 0.99999 seconds. Then I rather use the delay_ms function which is accurate up to a few microseconds. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|