I2CIN SDA,DS1307_Address,SPSEC,[SPSTR 7] ' read clock into SPRAM
FOR y = SPSEC TO SPYR ' 7 bytes (second to year)
GET y,x : PUT y,$7 & x.NIB1 * 10 + x.NIB0 ' convert from BCD to decimal and put back in SPRAM
GET SPHR,hour : GET SPMIN,minute : GET SPSEC,second ' get time
IF hour = 2 AND minute = 0 AND second = 0 THEN ' check for Daylight Saving Time
GET SPMON,month : GET SPDAY,day : GET SPDOW,dow ' get month, day and dow from SPRAM
IF month = 3 AND dow = 7 THEN ' March and Sunday
IF day >= 8 AND day < 15 THEN ' second week
WRITE E_DST,1 ' set DST in EEPROM
hour = 3 ' set hour to 3
IF month = 11 AND dow = 7 THEN ' November and Sunday
IF day < 8 THEN ' first week
READ E_DST,dst ' get DST from EEPROM
IF dst THEN ' DST is set
WRITE E_DST,0 ' clear DST in EEPROM
hour = 1 ' set hour to 1
IF hour <> 2 THEN ' time was changed
PUT SPHR,hour ' set new hour SPRAM
I2COUT SDA,DS1307_Address,SPHR,[hour] ' set new hour in DS1307 clock
ENDIF ' no BCD conversion necessary as hour can only be 1 or 3
READ E_DST,dst ' read DST bit from EEPROM
RETURN ' done
IMO it's wrong to apply the DST change to the RTC itself.
PUB CheckDST | hh24
This routine checks the current date and time to see if an adjustment is necessary into or out of Daylight Savings Time.
The RTC's DST flag is stored in its free register.
The rules for DST changed in 2007 for the first time in more than 20 years. The new changes were enacted
by the Energy Policy Act of 2005, which extended the length of DST in the interest of reducing energy
consumption. The new rules increased the duration of DST by about one month. DST will now be in effect
for 238 days, or about 65% of the year, although Congress retained the right to revert to the prior law
should the change prove unpopular or if energy savings are not significant.
At present, daylight saving time in the United States
begins at 2:00 a.m. on the second Sunday of March, and
ends at 2:00 a.m. on the first Sunday of November
4..10 : DST := +1 'If the RTC month is between April (4) and October (10) then it is currently DST
1..2 : DST := 0 'If the RTC month is between December (12) and February (2) then it is not DST
3 : 'DST begins at 2:00 AM on the second Sunday of March (3)
IF ( ClockDate - ClockDay ) =>8 'If the date (1-31) minus the day of the week (0-6) is 8 or more then
DST := +1 'we are past the first Sunday so DST is in effect.
DST := 0
11 : 'DST ends at 2:00 a.m. on the first Sunday of November
IF ( ClockDate - ClockDay ) =<0 'If the date (1-31) minus the day of the week (0-6) is less than 0 then
DST := +1 'DST is still in effect.
DST := 0
' If the value of DST matches the free register value then no change is needed so just return.
IF readDSTRegister == DST
' They do not agree so we are on the first day of the DST change.
' Chect to see if we are at 2 AM or later before we make the change, if not just return.
hh24 := ClockHour
IF hh24 < 2
IF DST == 1
'We are at or past 2 AM so make the change accordingly
IF DST == 1
hh24 := hh24 + 1 'DST now in effect so add 1 to the hour ("spring ahead").
hh24 := hh24 - 1 'DST is not in effect so substract 1 from the hour ("fall back")
writeTime( time, time, hh24, time, time, time, ClockYear )
' Update the DST register on the RTC to reflect this change (on subsequent passes through this routine the DST will match this new
' resister value and no RTC time change will be made until the next DST date and time event occurs).
writeDSTRegister( DST )
Sapphire wrote: »
The best solution I have found is to use a RTC with automatic DST adjustment, like the ISL12022MA which is a very nice chip.