The clock module contains a set of routines designed to present clock and calendar information, to facilitate the adjustment of the Real Time clock and to interface to the DS1307 RTC chip using the I2C bus and the MSSP hardware module of the PIC.
The Clock module sets up 2 arrays RTCArry and SetRTCArry. The arrays are organised to reflect the registers of the DS1307. I.e. Array index [0] holds the Seconds count, [1] Minutes, [2] Hours, [3] Day of Week, [4] Day, [5] Month, [6] Year. These individual array elements are also aliased to aid readability of the code.
RTCArry holds the actual values held in the DS1307, SetRTCArry is used to hold the binary equivalent of the DS1307 registers for editing purposes.
There is no support at present for a 12 hour version. The routines support daylight saving (DS) and can calculate the day of the week from an entered date.
The code is well documented throughout so only the more important routines are described here. You will also start to see examples of how the Task Manager is used to trigger certain tasks associated with the clock.
CheckRTC This routine will check to see if the DS1307 is set up and running. If it is not set up it will prime the RTCArry with a starting date and will return with RTC_Cont false. This should be called as part of the applications initialisation process.
RTC_Init If the CheckRTC routine reported that the DS1307 is set up you can call this routine. I use the 1st byte of the NVRam on the DS1307 to store the daylight saving state (On/Off). The routine extracts the DS state and sets up the internal indicators to indicate winter or summer time. It also loads the Tick Indicator (in this case a colon :) and adds the UpdateSeconds task to the 1 Second task rate list.
Note To keep the reads of the DS1307 to a minimum the clock is only read every minute; the seconds value is determined by decrementing the seconds counter on the 1 Hz interrupt. The seconds count is re-synchronized each time the DS1307 is read.
GetTimeDate The Scheduler calls this routine when the seconds count has reached 0. It saves the current day before reading, reads the first seven DS1307 registers into the RTCArry. If the new RTCDay is different from the saved value the DateChanged flag is set. (This flag will be reset by the scheduler when all the COD tasks have been called).
If the DS1307 has not been set up it will not have an active Square wave output and there will be nothing to trigger the real time updates. To setup the DS1307 it is necessary to set the correct values for time and date in the SetRTCArry and call RTCUpdate.
RTCUpdate This routine takes the values in the SetRTCArry, calculates the day of the week based on the date entered, converts the SetRTCArry values into BCD, saves them to the DS1307 and writes them back into the RTCArry. It also updates the daylight saving flag in the first location of the DS1307s NVRam.
Note In RTCUpdate the long winded version of HBusOut has been used to save the data to the DS1307. Initially this was because the Proton compiler was not able to handle the Array write correctly. Later versions of the compiler have resolved this. However, the code here actually produces shorter PIC code than using the Proton Str Array modifier.
The module contains routines which will build ASCII strings for Time and Date and optionally display them on the LCD.
StrTimeDate Using the RTCArry values, this routine produces a string in the form HH:MM* DD-MMM-YY, where * is the daylight saving indicator. The string is returned in MsgArry.
StrTime Using the RTCArry values, produces a string in the form HH:MM stored in MsgArry
DispTimeDate Using the RTCArry values, displays the time and date on the row defined by TkRow. It also sets TkCol to the position of the tick indicator (:). This is used later when displaying a flashing tick indicator.
StrTimeDate2, StrTime2 and their Display equivalents are similar to the routine above but use the values held in the SetRTCArry. These routines would be used when editing the clock values.
DispTick each time this routine is called it will toggle the Tick Indicator between a colon and a space and display it at the TkRow/TkCol position on the display. When this routine is placed on the 2Hz Task list it will flash a colon on and off at the location defined by TkRow and TkCol.
To do all the above there are a number of supporting routines which can be useful in their own right.
StrMonth Returns a 3 byte string in MsgArry representing the month name from the number in RTC_Data.
StrDayName Similar to StrMonth but returns a 3 byte day name for the day number in RTC_Data. Note day 1 is a Tuesday.
The module contains a set of routines which will enable the adjustment of the clock. These routines would be called from the application code using the menu system.
TSetUp takes a snapshot of the RTCArry and holds it in SetRTCArry in binary form ready for editing.
ToggleDS changes the Daylight Saving state between summer and winter and adjusts the time plus or minus 1 hour.
StepMin/StepHour these 2 routines will increment or decrement the count in SetMin and SetHour respectively according to the state of RTC_Cont. If RTC_Cont is True (1) the count is incremented otherwise it is decremented. The count will roll over to 0 at 59 for minutes and 23 for hours.
StepDay will increment or decrement the day number within the range defined by the current month. RTC_Cont determines the direction.
StepMonth increments or decrements the month number between 1 and 12. It will also adjust the day number if is outside number of days in the current month.
StepYear Increments or decrements the year number between 00 and 99.
ChkTimeAndDate checks that the numbers in the SetRTCArry are valid times and dates and returns with RTC_Cont True if invalid.
ChkValidDate As above but for Date only.
FindDays will return the maximum number of days for a given month corrected by leap year where appropriate.
ConvBIN/ConvBCD These 2 routines take a byte passed to them via the software stack and return the byte converted to the alternative number base.