DS1338 RTC library RTC + 55 bytes nvram

This library let you access a DS1338, which includes a RTC and some nvram.

Most of the mbed chip already have a good rtc, but they can't be powered by a separate backup battery.

With a DS1338, plus a small lithium 3V battery, you will keep trace of time.

You will also have 55 bytes (DS1338 says 56 bytes, but I use one of them for the library) of NVRAM backed up by the battery, to store fast changing data (which would tear down an eeprom), and keep it, even in the case of a watchdog reset.

Demo code

#include "mbed.h"
#include "fr_time.h"
#include "ds1338.h"

int main() {
    struct tm time;
    int count;

    pc=new RawSerial(USBTX, USBRX);
    pc->baud(115200);
    pc->printf("DS1338 Demo\r\n");
    DS1338 ds1338(P0_19,P0_20);
#ifdef INIT_TIME
    count=0;
    time.tm_sec=0;
    time.tm_min=0;
    time.tm_hour=8;
    time.tm_mday=4;
    time.tm_mon=2;
    time.tm_year=115;
    time.tm_wday=1;
    time.tm_yday=0;
    time.tm_isdst=0;
    ds1338.writeTime(&time);
#endif


    while (true) {
        wait(0.5);
        ds1338.readTime(&time);
        ds1338.read(0,4,(char *)(&count));
        count++;
        ds1338.write(0,4,(char *)(&count));
        pc->printf("loop %d at %s\r\n",count,asctime(&time));
    }
}
Committer:
scachat
Date:
Wed Mar 04 13:09:54 2015 +0000
Revision:
1:e77d69913c46
Parent:
0:0ffb7046206a
bug in month handling

Who changed what in which revision?

UserRevisionLine numberNew contents of line
scachat 0:0ffb7046206a 1 #include "mbed.h"
scachat 0:0ffb7046206a 2 #include "ds1338.h"
scachat 0:0ffb7046206a 3
scachat 0:0ffb7046206a 4 /*
scachat 0:0ffb7046206a 5 * Constructor, initialize the ds1338 on i2c interface.
scachat 0:0ffb7046206a 6 * @param sda : sda i2c pin (PinName)
scachat 0:0ffb7046206a 7 * @param scl : scl i2c pin (PinName)
scachat 0:0ffb7046206a 8 */
scachat 0:0ffb7046206a 9 DS1338::DS1338(PinName sda, PinName scl): _i2c(sda, scl) {
scachat 0:0ffb7046206a 10 _i2c.frequency(400000);
scachat 0:0ffb7046206a 11 buffer[0]=0x07;
scachat 0:0ffb7046206a 12 _i2c.write(DS1338_ADR,buffer,1,true);
scachat 0:0ffb7046206a 13 _i2c.read(DS1338_ADR,buffer,1);
scachat 0:0ffb7046206a 14 if (buffer[0]&0x20){
scachat 0:0ffb7046206a 15 buffer[0]=0x07;
scachat 0:0ffb7046206a 16 buffer[1]=0xB0;//do not erase error condition !
scachat 0:0ffb7046206a 17 }else{
scachat 0:0ffb7046206a 18 buffer[0]=0x07;
scachat 0:0ffb7046206a 19 buffer[1]=0x90;
scachat 0:0ffb7046206a 20 }
scachat 0:0ffb7046206a 21 _i2c.write(DS1338_ADR,buffer,1+1);
scachat 0:0ffb7046206a 22 }
scachat 0:0ffb7046206a 23 /**
scachat 0:0ffb7046206a 24 * read bytes from nvram (55 bytes available)
scachat 0:0ffb7046206a 25 * @param adr the start address (starts at 0)
scachat 0:0ffb7046206a 26 * @param count number of byte to read
scachat 0:0ffb7046206a 27 * @param data where to put the bytes
scachat 0:0ffb7046206a 28 * @return the byte
scachat 0:0ffb7046206a 29 */
scachat 0:0ffb7046206a 30 void DS1338::read(unsigned char adr,unsigned char count,char * data) {
scachat 0:0ffb7046206a 31 if (count>DS1338_BUFFER_SIZE) {
scachat 0:0ffb7046206a 32 count=DS1338_BUFFER_SIZE;
scachat 0:0ffb7046206a 33 }
scachat 0:0ffb7046206a 34 buffer[0]=9+adr;
scachat 0:0ffb7046206a 35 _i2c.write(DS1338_ADR,&(buffer[0]),1,true);
scachat 0:0ffb7046206a 36 _i2c.read(DS1338_ADR,data,count);
scachat 0:0ffb7046206a 37 }
scachat 0:0ffb7046206a 38 /**
scachat 0:0ffb7046206a 39 * write bytes to nvram (55 bytes available)
scachat 0:0ffb7046206a 40 * @param adr the start address (starts at 0)
scachat 0:0ffb7046206a 41 * @param count number of byte to write
scachat 0:0ffb7046206a 42 * @param data to be written
scachat 0:0ffb7046206a 43 * @return the byte
scachat 0:0ffb7046206a 44 */
scachat 0:0ffb7046206a 45 void DS1338::write(unsigned char adr,unsigned char count,char * data) {
scachat 0:0ffb7046206a 46 if (count>DS1338_BUFFER_SIZE-1) {
scachat 0:0ffb7046206a 47 count=DS1338_BUFFER_SIZE-1;
scachat 0:0ffb7046206a 48 }
scachat 0:0ffb7046206a 49 buffer[0]=9+adr;
scachat 0:0ffb7046206a 50 for (unsigned char i=0; i<count; i++) {
scachat 0:0ffb7046206a 51 buffer[1+i]=*(data+i);
scachat 0:0ffb7046206a 52 }
scachat 0:0ffb7046206a 53 _i2c.write(DS1338_ADR,buffer,1+count);
scachat 0:0ffb7046206a 54 }
scachat 0:0ffb7046206a 55 /**
scachat 0:0ffb7046206a 56 * read the current time
scachat 0:0ffb7046206a 57 * @param x the time;
scachat 0:0ffb7046206a 58 */
scachat 0:0ffb7046206a 59 void DS1338::readTime(tm * time) {
scachat 0:0ffb7046206a 60 buffer[0]=0;
scachat 0:0ffb7046206a 61 _i2c.write(DS1338_ADR,&(buffer[0]),1,true);
scachat 0:0ffb7046206a 62 _i2c.read(DS1338_ADR,buffer,9);
scachat 0:0ffb7046206a 63 time->tm_sec=((buffer[0]>>4)&0x07)*10+(buffer[0]&0x0F);
scachat 0:0ffb7046206a 64 time->tm_min=((buffer[1]>>4)&0x07)*10+(buffer[1]&0x0F);
scachat 0:0ffb7046206a 65 time->tm_hour=((buffer[2]>>4)&0x03)*10+(buffer[2]&0x0F);
scachat 0:0ffb7046206a 66 time->tm_mday=((buffer[4]>>4)&0x03)*10+(buffer[4]&0x0F);
scachat 0:0ffb7046206a 67 time->tm_mon=((buffer[5]>>4)&0x01)*10+(buffer[5]&0x0F)-1;
scachat 0:0ffb7046206a 68 time->tm_year=((buffer[6]>>4)&0x0F)*10+(buffer[6]&0x0F);
scachat 0:0ffb7046206a 69 if (time->tm_year<70){
scachat 0:0ffb7046206a 70 time->tm_year+=100;
scachat 0:0ffb7046206a 71 }
scachat 0:0ffb7046206a 72 time->tm_wday=buffer[3]&0x07;
scachat 0:0ffb7046206a 73 time->tm_yday=0;
scachat 0:0ffb7046206a 74 time->tm_isdst=0;
scachat 0:0ffb7046206a 75 if (time->tm_sec>=60||
scachat 0:0ffb7046206a 76 time->tm_min>=60||
scachat 0:0ffb7046206a 77 time->tm_hour>=24||
scachat 0:0ffb7046206a 78 time->tm_mday>31 || time->tm_mday<1||
scachat 0:0ffb7046206a 79 time->tm_mon>11||
scachat 0:0ffb7046206a 80 time->tm_wday>=7||
scachat 0:0ffb7046206a 81 buffer[0x08]!=0xCA||//checksum
scachat 0:0ffb7046206a 82 (buffer[0x07]&0x20)!=0){//error condition
scachat 0:0ffb7046206a 83 time->tm_sec=0;
scachat 0:0ffb7046206a 84 time->tm_min=0;
scachat 0:0ffb7046206a 85 time->tm_hour=0;
scachat 0:0ffb7046206a 86 time->tm_mday=1;
scachat 0:0ffb7046206a 87 time->tm_mon=0;
scachat 0:0ffb7046206a 88 time->tm_year=70;
scachat 0:0ffb7046206a 89 time->tm_wday=1;
scachat 0:0ffb7046206a 90 time->tm_yday=0;
scachat 0:0ffb7046206a 91 time->tm_isdst=0;
scachat 0:0ffb7046206a 92 writeTime(time);
scachat 0:0ffb7046206a 93 }
scachat 0:0ffb7046206a 94 }
scachat 0:0ffb7046206a 95 /**
scachat 0:0ffb7046206a 96 * write the current time
scachat 0:0ffb7046206a 97 * @param time the time;
scachat 0:0ffb7046206a 98 */
scachat 0:0ffb7046206a 99 void DS1338::writeTime(tm * time) {
scachat 0:0ffb7046206a 100 buffer[0]=0;
scachat 0:0ffb7046206a 101 buffer[1]=(((time->tm_sec/10)<<4)+(time->tm_sec%10))&0x7F;//clock not halted
scachat 0:0ffb7046206a 102 buffer[2]=(((time->tm_min/10)<<4)+(time->tm_min%10))&0x7F;
scachat 0:0ffb7046206a 103 buffer[3]=(((time->tm_hour/10)<<4)+(time->tm_hour%10))&0x3F;//mode 24h
scachat 0:0ffb7046206a 104 buffer[4]=(time->tm_wday)&0x03;
scachat 0:0ffb7046206a 105 buffer[5]=(((time->tm_mday/10)<<4)+(time->tm_mday%10))&0x3F;
scachat 1:e77d69913c46 106 buffer[6]=((((time->tm_mon+1)/10)<<4)+((time->tm_mon+1)%10))&0x1F;
scachat 0:0ffb7046206a 107 buffer[7]=((((time->tm_year%100)/10)<<4)+(time->tm_year%10))&0xFF;
scachat 0:0ffb7046206a 108 buffer[8]=0x90;//1Hz, erase error cond
scachat 0:0ffb7046206a 109 buffer[9]=0xCA;
scachat 0:0ffb7046206a 110 _i2c.write(DS1338_ADR,buffer,1+9);
scachat 0:0ffb7046206a 111 }