BRTOS: Basic Real Time Operating System for PICmicro - Part 2

By JohnB

 

In this article I am going to describe the Clock module, but first, a bit about messages. 

There are plenty of times when it is necessary to send a text string either to a display or to a serial port.  You could take the obvious approach of using the string building facilities built into the Proton HSerOut and Print commands but using these commands restricts you to the specific peripheral.  I prefer to build up my messages in a common Message Array which I can then sent to any peripheral supported by the hardware without having to rebuild the message each time.   Some of you may have noted that I used this technique in the TASK_DEBUG code in the previous article.  The approach is also used in the Clock module described here.

The Clock Module

This module contains a set of routines designed to present clock and calendar information, to facilitate the adjustment of the 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.

Initialisation and getting the clock Running

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 application’s 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 I only read the clock every minute.  I keep track of seconds by decrementing the seconds counter every second.  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 DS1307’s NVRam.

Note – In RTCUpdate I have used the long winded version of HBusOut 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.  This would also probably apply to GetTimeDate which still uses the Str Array modifier.

Creating and Displaying Time and Date Strings

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.

Making Time and Date Adjustments

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.

Attached Code

RTC_P+.inc – The include file for the Clock module

Further Reading

The next article, written by JohnB,will describe the Menu system.

About the Proton Compiler

Crownhill's Proton Plus Compiler is a part of the Proton Development Suite - A suite of British-developed applications enabling fast development of PICmicro's using the PICBASIC Language.

For more information on the Proton Development Suite, please visit www.picbasic.org