Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 22:41 29 Apr 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Micromite MK2: Using the DS3231 RTC

Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8584
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
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2794
Posted: 05:51am 26 Nov 2014
Copy link to clipboard 
Print this post

Thanks once again for some more useful code

(By the way - your OLED code is working brilliantly - I just need to speed up the screen refresh now and all is done )
For everything Micromite visit micromite.org

Direct Email: whitewizzard@micromite.o
 
centrex

Guru

Joined: 13/11/2011
Location: Australia
Posts: 320
Posted: 10:19pm 27 Nov 2014
Copy link to clipboard 
Print this post

Hi Matherp
I get this error message....RUN
Time and date after intialising 12:15:22 26-11-2014
[24] If Not i2clook Then I2C open 400,1000
Error: Variable type not specified

170 with early beta.
Any fix.
Regards
Cliff

Cliff
 
OA47

Guru

Joined: 11/04/2012
Location: Australia
Posts: 902
Posted: 10:27pm 27 Nov 2014
Copy link to clipboard 
Print this post

  Quote  [24] If Not i2clook Then I2C open 400,1000
Error: Variable type not specified

This wouldn't be another uppercase/lower case issue would it?

GM
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8584
Posted: 10:33pm 27 Nov 2014
Copy link to clipboard 
Print this post

You need to be on b25. Depending on beta there were various issues Geoff was working through on data typing and interaction with the OPTION commands
 
jman

Guru

Joined: 12/06/2011
Location: New Zealand
Posts: 711
Posted: 04:38pm 28 Nov 2014
Copy link to clipboard 
Print this post

Hi
Thanks for the code could you explain were / how you got the hex values for this line i2clook=peek(WORD &HBF805000) AND &H8000

Regards
JmanEdited by jman 2014-11-30
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8584
Posted: 10:31pm 28 Nov 2014
Copy link to clipboard 
Print this post

&HBF805000 comes from the datasheet for the PIC32MX170 and is the address of the i2c control register used by micromite basic. &H8000 is a mask for bit 16 which is the enable bit in the control register. So by looking at the bit I can tell if the software is already using i2c. If it is I don't need to execute the "i2c open" command. If it isn't I will open i2c and then close it again after the read to keep things tidy.
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024