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 KingdomPosts: 8584 |
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; } |
||||
WhiteWizzard Guru Joined: 05/04/2013 Location: United KingdomPosts: 2794 |
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: AustraliaPosts: 320 |
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: AustraliaPosts: 902 |
This wouldn't be another uppercase/lower case issue would it? GM |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8584 |
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 ZealandPosts: 711 |
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 Jman |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8584 |
&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 |