Library to make use of the DS1302 timekeeping IC. The functions are identical to those used by the mbed RTC's
Dependents: temp_humid_time_DS1302_LM35_DHT11 temp_humid_light_time_DS1302_LM35_DHT11_LDR DSKY DS1302_HelloWorld ... more
HelloWorld program: https://mbed.org/users/Sissors/code/DS1302_HelloWorld/
For usage of the returned UNIX time code, see for example https://mbed.org/handbook/Time, http://www.cplusplus.com/reference/ctime/strftime/?kw=strftime and http://mbed.org/handbook/Time?action=view&revision=11592
Revision 0:c7cea2a415c3, committed 2014-03-31
- Comitter:
- Sissors
- Date:
- Mon Mar 31 20:53:13 2014 +0000
- Child:
- 1:9a746f303e59
- Commit message:
- v1.0
Changed in this revision
DS1302.cpp | Show annotated file Show diff for this revision Revisions of this file |
DS1302.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DS1302.cpp Mon Mar 31 20:53:13 2014 +0000 @@ -0,0 +1,117 @@ +#include "DS1302.h" + +DS1302::DS1302(PinName SCLK, PinName IO, PinName CE) : _SCLK(SCLK), _IO(IO), _CE(CE) +{ + _CE = 0; + _SCLK = 0; + _IO.input(); + writeProtect = true; +} + +void DS1302::set_time(time_t t) +{ + struct tm *_t = localtime(&t); + writeReg(Seconds, (_t->tm_sec % 10) + ((_t->tm_sec / 10) << 4)); + writeReg(Minutes, (_t->tm_min % 10) + ((_t->tm_min / 10) << 4)); + writeReg(Hours, (_t->tm_hour % 10) + ((_t->tm_hour / 10) << 4)); + writeReg(Dates, (_t->tm_mday % 10) + ((_t->tm_mday / 10) << 4)); + writeReg(Months, ((_t->tm_mon + 1) % 10) + (((_t->tm_mon + 1) / 10) << 4)); + writeReg(Days, _t->tm_wday + 1); + writeReg(Years, ((_t->tm_year - 100) % 10) + (((_t->tm_year - 100) / 10) << 4)); +} + +time_t DS1302::time(time_t *t) +{ + char regs[7]; + _CE = 1; + wait_us(4); + writeByte(ClockBurst | 1); + for (int i = 0; i<7; i++) + regs[i] = readByte(); + _CE = 0; + + struct tm _t; + _t.tm_sec = (regs[0] & 0xF) + (regs[0] >> 4) * 10; + _t.tm_min = (regs[1] & 0xF) + (regs[1] >> 4) * 10; + _t.tm_hour = (regs[2] & 0xF) + (regs[2] >> 4) * 10; + _t.tm_mday = (regs[3] & 0xF) + (regs[3] >> 4) * 10; + _t.tm_mon = (regs[4] & 0xF) + (regs[4] >> 4) * 10 - 1; + _t.tm_year = (regs[6] & 0xF) + (regs[6] >> 4) * 10 + 100; + + // convert to timestamp and display (1256729737) + return mktime(&_t); +} + +void DS1302::storeByte(char address, char data) +{ + if (address > 30) + return; + char command = RAMBase + (address << 1); + writeReg(command, data); +} + +char DS1302::recallByte(char address) +{ + if (address > 30) + return 0; + char command = RAMBase + (address << 1) + 1; + return readReg(command); +} + +char DS1302::readReg(char reg) +{ + char retval; + + _CE = 1; + wait_us(4); + writeByte(reg); + retval = readByte(); + wait_us(4); + _CE = 0; + return retval; +} + +void DS1302::writeReg(char reg, char val) +{ + if (writeProtect) { + writeProtect = false; + writeReg(WriteProtect, 0); + } + _CE = 1; + wait_us(4); + writeByte(reg); + writeByte(val); + wait_us(4); + _CE = 0; +} + + +/*********************PRIVATE***********************/ +void DS1302::writeByte(char data) +{ + _IO.output(); + for (int i = 0; i<8; i++) { + _IO = data & 0x01; + wait_us(1); + _SCLK = 1; + wait_us(1); + _SCLK = 0; + data >>= 1; + } + _IO.input(); +} + +char DS1302::readByte(void) +{ + char retval = 0; + + _IO.input(); + for (int i = 0; i<8; i++) { + retval |= _IO << i; + wait_us(1); + _SCLK = 1; + wait_us(1); + _SCLK = 0; + } + return retval; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DS1302.h Mon Mar 31 20:53:13 2014 +0000 @@ -0,0 +1,151 @@ +//The license: Its on the internet, have fun with it. + +#ifndef DS1302_H +#define DS1302_H + +#include "mbed.h" + +/** +* Library to make use of the DS1302 timekeeping IC +* +* The library functions the same as the standard mbed time function, +* only now you have to first make a DS1302 object and apply the +* functions on the object. +* +* Example code: +* @code +* #define SCLK PTC5 +* #define IO PTC4 +* #define CE PTC3 +* +* //Comment this line if the DS1302 is already running +* #define INITIAL_RUN +* +* #include "mbed.h" +* #include "DS1302.h" +* +* DS1302 clk(SCLK, IO, PTC3); +* +* int main() { +* #ifdef INITIAL_RUN +* clk.set_time(1256729737); +* #endif +* +* char storedByte = clk.recallByte(0); +* printf("Stored byte was %d, now increasing by one\r\n", storedByte); +* clk.storeByte(0, storedByte + 1); +* +* while(1) { +* time_t seconds = clk.time(NULL); +* printf("Time as a basic string = %s\r", ctime(&seconds)); +* wait(1); +* } +* } +* @endcode +* +* See for example http://mbed.org/handbook/Time for general usage +* of C time functions. +* +* Trickle charging is not supported +**/ +class DS1302 +{ +public: + /** + * Register map + */ + enum { + Seconds = 0x80, + Minutes = 0x82, + Hours = 0x84, + Dates = 0x86, + Months = 0x88, + Days = 0x8A, + Years = 0x8C, + WriteProtect = 0x8E, + Charge = 0x90, + ClockBurst = 0xBE, + RAMBase = 0xC0 + }; + + /** + * Create a new DS1302 object + * + * @param SCLK the pin to which SCLK is connectd + * @param IO the pin to which IO is connectd + * @param CE the pin to which CE is connected (also called RST) + */ + DS1302(PinName SCLK, PinName IO, PinName CE); + + /** Set the current time + * + * Initialises and sets the time of the DS1302 + * to the time represented by the number of seconds since January 1, 1970 + * (the UNIX timestamp). + * + * @param t Number of seconds since January 1, 1970 (the UNIX timestamp) + * + */ + void set_time(time_t t); + + /** Get the current time + * + * Use other functions to convert this value, see: http://mbed.org/handbook/Time + * + * @param t ignored, supply NULL + * @return number of seconds since January 1, 1970 + */ + time_t time(time_t *t = NULL); + + /** + * Store a byte in the battery-backed RAM + * + * @param address address where to store the data (0-30) + * @param data the byte to store + */ + void storeByte(char address, char data); + + /** + * Store a byte in the battery-backed RAM + * + * @param address address where to retrieve the data (0-30) + * @return the stored data + */ + char recallByte(char address); + + /** + * Read a register + * + * Only required to for example manually set trickle charge register + * + * @param reg register to read + * @return contents of the register + */ + char readReg(char reg); + + /** + * Write a register + * + * Only required to for example manually set trickle charge register + * + * @param reg register to write + * @param val contents of the register to write + */ + void writeReg(char reg, char val); + +protected: + + void writeByte(char data); + char readByte(void); + + DigitalOut _SCLK; + DigitalInOut _IO; + DigitalOut _CE; + bool writeProtect; + + +}; + + + +#endif