Posted: 03:40am 26 Nov 2014 |
Copy link to clipboard |
 Print this post |
|
The DS3231 is probably the best of the real time clock chips around at the moment. It is very accurate and has an internal crystal. It supports 400Khz i2c, 3.3V, has battery backup and most importantly can be bought on the usual auction site complete with battery and i2c eeprom for much less than the PCF8563 (lowest price I've found for the complete module including battery is £0.99!)
The attached code includes two routines:
DSsettime which takes the current time$ and date$ and updates the DS3231 with them
DSgettime which does exactly the same as RTC GETTIME and updates time$ and date$ from the RTC.
The cFunctions do the packing and unpacking of the BCD to the strings TIME$ and DATE$, no magic just easier and quicker in C. I've included the c code as text to avoid the code brackets corrupting C syntax using square brackets.
The code checks whether the i2c port is already open and leaves it open if it is. If it isn't it opens the i2c port to do the reads and writes and then closes it again
Option EXPLICIT
option default NONE
'
' Use of DS3231 as RTC
'
time$="12:15:22"
date$="26-11-2014"
print "Time and date after intialising",time$,date$
DSsettime
print "Time and date after setting",time$,date$
time$="00:00:00"
date$="01-01-2000"
print "Time and date after re-initialising",time$,date$
DSgettime
pause 1000 'give time for the seconds to tick
print "Time and date after reading from DS3231",time$,date$
end
'
sub DSSettime
local clock$
local as integer i
local as integer i2clook=peek(WORD &HBF805000) AND &H8000
if not i2clook then i2c open 400,1000
i=rtcsetDS(clock$,time$,date$)
I2C write &b1101000,0,len(clock$),clock$
if not i2clook then i2c close
end sub
'
sub DSGettime
local clock$ ,DSdate$ ,DStime$
local as integer i2clook=peek(WORD &HBF805000) AND &H8000
if not i2clook then i2c open 400,1000
I2C WRITE &b1101000,1,1,0 'set the read address to 0
I2C READ &b1101000,0,7,clock$
local as integer i=rtcgetDS(clock$,DStime$,DSdate$)
if not i2clook then i2c close
time$=dstime$
date$=dsdate$
end sub
'
CFunction rtcsetDS
00000000
27bdfff8 afbe0004 03a0f021 afc40008 afc5000c
afc60010 8fc20008 24030011 a0430000 8fc20008 24420001 a0400000 8fc20008
24420002 8fc3000c 24630007 90630000 2463ffd0 00031900 7c032420 8fc3000c
24630008 90630000 2463ffd0 306300ff 7c031c20 00831825 7c031c20 306300ff
a0430000 8fc20008 24420003 8fc3000c 24630004 90630000 2463ffd0 00031900
7c032420 8fc3000c 24630005 90630000 2463ffd0 306300ff 7c031c20 00831825
7c031c20 306300ff a0430000 8fc20008 24420004 8fc3000c 24630001 90630000
2463ffd0 00031900 7c032420 8fc3000c 24630002 90630000 2463ffd0 306300ff
7c031c20 00831825 7c031c20 306300ff a0430000 8fc20008 24420005 24030001
a0430000 8fc20008 24420006 8fc30010 24630001 90630000 2463ffd0 00031900
7c032420 8fc30010 24630002 90630000 2463ffd0 306300ff 7c031c20 00831825
7c031c20 306300ff a0430000 8fc20008 24420007 8fc30010 24630004 90630000
2463ffd0 00031900 7c032420 8fc30010 24630005 90630000 2463ffd0 306300ff
7c031c20 00831825 7c031c20 306300ff a0430000 8fc20008 24420008 8fc30010
24630009 90630000 2463ffd0 00031900 7c032420 8fc30010 2463000a 90630000
2463ffd0 306300ff 7c031c20 00831825 7c031c20 306300ff a0430000 8fc20008
24420009 a0400000 8fc20008 2442000a a0400000 8fc20008 2442000b a0400000
8fc20008 2442000c a0400000 8fc20008 2442000d a0400000 8fc20008 2442000e
a0400000 8fc20008 2442000f 24030004 a0430000 8fc20008 24420010 a0400000
00001021 00001821 03c0e821 8fbe0004 27bd0008 03e00008 00000000
End CFunction
'
CFunction rtcgetDS
00000000
27bdfff8 afbe0004 03a0f021 afc40008 afc5000c afc60010 8fc2000c 24420008
8fc30008 24630001 90630000 3063000f 306300ff 24630030 306300ff a0430000
8fc2000c 24420007 8fc30008 24630001 90630000 00031902 306300ff 24630030
306300ff a0430000 8fc2000c 24420006 2403003a a0430000 8fc2000c 24420005
8fc30008 24630002 90630000 3063000f 306300ff 24630030 306300ff a0430000
8fc2000c 24420004 8fc30008 24630002 90630000 00031902 306300ff 24630030
306300ff a0430000 8fc2000c 24420003 2403003a a0430000 8fc2000c 24420002
8fc30008 24630003 90630000 3063000f 306300ff 24630030 306300ff a0430000
8fc2000c 24420001 8fc30008 24630003 90630000 00031902 306300ff 24630030
306300ff a0430000 8fc2000c 24030008 a0430000 8fc20010 2403000a a0430000
8fc20010 24420002 8fc30008 24630005 90630000 3063000f 306300ff 24630030
306300ff a0430000 8fc20010 24420001 8fc30008 24630005 90630000 00031902
306300ff 24630030 306300ff a0430000 8fc20010 24420003 2403002d a0430000
8fc20010 24420005 8fc30008 24630006 90630000 3063000f 306300ff 24630030
306300ff a0430000 8fc20010 24420004 8fc30008 24630006 90630000 00031902
306300ff 24630030 306300ff a0430000 8fc20010 24420006 2403002d a0430000
8fc20010 2442000a 8fc30008 24630007 90630000 3063000f 306300ff 24630030
306300ff a0430000 8fc20010 24420009 8fc30008 24630007 90630000 00031902
306300ff 24630030 306300ff a0430000 8fc20010 24420007 24030032 a0430000
8fc20010 24420008 24030030 a0430000 00001021 00001821 03c0e821 8fbe0004
27bd0008 03e00008 00000000
End CFunction
long long rtcgetDS(unsigned char i2c[],unsigned char t[],unsigned char d[]) {
t[8]=(i2c[1] & 0x0F) +48;
t[7]=(i2c[1]>>4) +48;
t[6]=':';
t[5]=(i2c[2] & 0x0F) +48;
t[4]=(i2c[2]>>4) +48;
t[3]=':';
t[2]=(i2c[3] & 0x0F) +48;
t[1]=(i2c[3]>>4) +48;
t[0]=8;
d[0]=10;
d[2]=(i2c[5] & 0x0F) +48;
d[1]=(i2c[5]>>4) +48;
d[3]='-';
d[5]=(i2c[6] & 0x0F) +48;
d[4]=(i2c[6]>>4) +48;
d[6]='-';
d[10]=(i2c[7] & 0x0F) +48;
d[9]=(i2c[7]>>4) +48;
d[7]=50;
d[8]=48;
return 0;
}
long long rtcsetDS(unsigned char i2c[],unsigned char t[],unsigned char d[]) {
i2c[0]=17;
i2c[1]=0; //set the write address
i2c[2]=((t[7]-48)<<4)|(t[8]-48);
i2c[3]=((t[4]-48)<<4)|(t[5]-48);
i2c[4]=((t[1]-48)<<4)|(t[2]-48);
i2c[5]=1; //always set the day to 1 we don't use this
i2c[6]=((d[1]-48)<<4)|(d[2]-48);
i2c[7]=((d[4]-48)<<4)|(d[5]-48);
i2c[8]=((d[9]-48)<<4)|(d[10]-48);
i2c[9]=0;
i2c[10]=0;
i2c[11]=0;
i2c[12]=0;
i2c[13]=0;
i2c[14]=0;
i2c[15]=4; //1hz output
i2c[16]=0;//turn on the oscillator if off'
return 0;
}
Edited by matherp 2014-11-27 |