phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 3144
Posted: 07:20am 28 Oct 2025
In case the RTC SetReg and RTC GetReg method of setting/getting the year doesn't work here are two RTC Subs to do the job.
Not tested on a PCF85063A but with appropriate adjustments work on a DS1307, DS2321 and simulated PCF85063A in a EEPROM (was too wet to go out to play yesterday).
Sub PCF85063A.Get 'Load Date$ and Time$ with values from the RTC Local integer dt(6), n Local D.o.W$(7)=("Day-of-Week not set. ","Sun ","Mon ","Tue ","Wed ","Thu ","Fri ","Sat ") I2C WRITE &H51,0,1,4 : I2C READ &h51,0,7,dt() 'set register address pointer to 4 then read registers For n=0 To 6 : dt(n)=(dt(n)>>4)*10+(dt(n)And 15) : Next 'convert BCD byte to integer Time$ = Str$(dt(2),2,0,"0")+":"+Str$(dt(1),2,0,"0")+":"+Str$(dt(0),2,0,"0") 'assemble time Date$ = Str$(dt(3),2,0,"0")+"-"+Str$(dt(5),2,0,"0")+"-20"+Str$(dt(6),2,0,"0") 'assemble date Print "Date$ and Time$ have been updated from the RTC to "+T$+" "+D.o.W$(dt(4)) ' : Math v_print dt() End Sub
'To update the Day-of-Week after setting the RTC run this at the command prompt:- 'I2C write &h51,0,2,7,DoW 'DoW = 1 for Sunday to 7 for Saturday
Sub PCF85063A.Set 'Set Date$ and Time$ first then call PCF85063A.Set to set the RTC Local T$=Time$+" "+Date$ ' "hh:mm:ss dd-mm-20yy" Local integer dt(7), n dt(0)=0 : dt(1)=Val(Mid$(T$,7,2)) : dt(2)=Val(Mid$(T$,4,2)) : dt(3)=Val(Left$(T$,2)) dt(4)=Val(Mid$(T$,10,2)) : dt(5)=0 : dt(6)=Val(Mid$(T$,13,2)) : dt(7)=Val(Right$(T$,2)) 'Start at register address 4, seconds, minutes, hours, day, DoW=0, month, year (2 digit) For n = 2 To 7 : dt(n) = (dt(n)\10 << 4)+(dt(n) Mod 10) : Next 'convert integer byte to BCD I2C WRITE &H51,0,9,dt() 'send data to RTC Print "PCF85063A RTC time and date have been set to "+T$ ' : Math v_print dt() End Sub
As most people have no use for these Subs (see Mick's comment), except those who have bought a module with one on it, they are quite rudimentary and there is no error detection built in. To minimize operator error they don't accept any parameters. Sub PCF85063A.Set Just takes the values from Time$ and Date$ and loads them into the RTC. Sub PCF85063A.Get Does the reverse. You can manually set the Day-of-Week register if you wish but it isn't needed as MMBasic has the DAY$() Function. Edited 2025-10-28 21:27 by phil99
Footnote added 2025-10-29 21:37 by phil99 Spotted an error in Sub PCF85063A.Set This line:-
dt(0)=4 is the correct register address to start loading the data.
The EEPROM simulation needed a 2 byte register address "dt(0)=0 : dt(1)=4 + data" and I deleted the wrong one for the final version.
Footnote added 2025-10-29 22:12 by phil99 Yet more corrections related to the EEPROM simulation.
For n = 1 To 7 : dt(n) = (dt(n)\10 << 4)+(dt(n) Mod 10) : Next 'convert integer byte to BCD I2C WRITE &H51,0,8,dt() 'send data to RTC
So here is the whole Sub again.
Sub PCF85063A.Set 'Set Date$ and Time$ first then call PCF85063A.Set to set the RTC Local T$=Time$+" "+Date$ ' "hh:mm:ss dd-mm-20yy" Local integer dt(7), n dt(0)=4 : dt(1)=Val(Mid$(T$,7,2)) : dt(2)=Val(Mid$(T$,4,2)) : dt(3)=Val(Left$(T$,2)) dt(4)=Val(Mid$(T$,10,2)) : dt(5)=0 : dt(6)=Val(Mid$(T$,13,2)) : dt(7)=Val(Right$(T$,2)) 'Start at register address 4, seconds, minutes, hours, day, DoW=0, month, year (2 digit) For n = 1 To 7 : dt(n) = (dt(n)\10 << 4)+(dt(n) Mod 10) : Next 'convert integer bytes to BCD I2C WRITE &H51,0,8,dt() 'send data to RTC Print "PCF85063A RTC time and date have been set to "+T$ ' : Math v_print dt() End Sub