Skip to content

Instantly share code, notes, and snippets.

@HorlogeSkynet
Last active April 10, 2023 21:02
Show Gist options
  • Save HorlogeSkynet/2d767c3af4862580c6287aa7901cf031 to your computer and use it in GitHub Desktop.
Save HorlogeSkynet/2d767c3af4862580c6287aa7901cf031 to your computer and use it in GitHub Desktop.
A library for the DS1302 RTC module

DS1302

A library for the DS1302 RTC Module

How to use it

Just follow the example.ino file, everything is detailed there !

PINS

  • RST : 11
  • DAT : 12
  • CLK : 13

Access variables

You can access these variables :

rtc.dateTime.Seconds10, rtc.dateTime.Seconds
rtc.dateTime.Minutes10, rtc.dateTime.Minutes
rtc.dateTime.h24.Hour10, rtc.dateTime.h24.Hour
rtc.dateTime.h12.Hour10, rtc.dateTime.h12.Hour
rtc.dateTime.Date10, rtc.dateTime.Date
rtc.dateTime.Month10, rtc.dateTime.Month
rtc.dateTime.Year10, rtc.dateTime.Year
rtc.dateTime.Day

... after having updated the buffer with :

rtc.read();
#include "DS1302.h"
DS1302::DS1302()
{
//
}
void DS1302::_DS1302_start(void)
{
digitalWrite(DS1302_CE_PIN, LOW);
pinMode(DS1302_CE_PIN, OUTPUT);
digitalWrite(DS1302_SCLK_PIN, LOW);
pinMode(DS1302_SCLK_PIN, OUTPUT);
pinMode(DS1302_IO_PIN, OUTPUT);
digitalWrite(DS1302_CE_PIN, HIGH);
delayMicroseconds(4);
}
void DS1302::_DS1302_stop(void)
{
digitalWrite(DS1302_CE_PIN, LOW);
delayMicroseconds(4);
}
uint8_t _DS1302_toggleread(void)
{
uint8_t i, data;
data = 0;
for(i = 0; i <= 7; i++)
{
digitalWrite(DS1302_SCLK_PIN, HIGH);
delayMicroseconds(1);
digitalWrite(DS1302_SCLK_PIN, LOW);
delayMicroseconds(1);
bitWrite(data, i, digitalRead(DS1302_IO_PIN));
}
return(data);
}
void DS1302::_DS1302_togglewrite(uint8_t data, uint8_t release)
{
for(int i = 0; i <= 7; i++)
{
digitalWrite(DS1302_IO_PIN, bitRead(data, i));
delayMicroseconds(1);
digitalWrite(DS1302_SCLK_PIN, HIGH);
delayMicroseconds(1);
if(release && i == 7)
{
pinMode(DS1302_IO_PIN, INPUT);
#if ARDUINO < 10003
// For Arduino 1.0.3, removing the pull-up is no longer needed.
// Setting the pin as 'INPUT' will already remove the pull-up.
digitalWrite(DS1302_IO, LOW);
#endif
}
else
{
digitalWrite(DS1302_SCLK_PIN, LOW);
delayMicroseconds(1);
}
}
}
uint8_t DS1302::DS1302_read(int address)
{
uint8_t data;
bitSet(address, DS1302_READBIT);
_DS1302_start();
_DS1302_togglewrite(address, true);
data = _DS1302_toggleread();
_DS1302_stop();
return(data);
}
void DS1302::DS1302_write(int address, uint8_t data)
{
bitClear(address, DS1302_READBIT);
_DS1302_start();
_DS1302_togglewrite(address, false);
_DS1302_togglewrite(data, false);
_DS1302_stop();
}
void DS1302::DS1302_clock_burst_read(uint8_t *p)
{
_DS1302_start();
_DS1302_togglewrite(DS1302_CLOCK_BURST_READ, true);
for(int i = 0; i < 8; i++)
{
*p++ = _DS1302_toggleread();
}
_DS1302_stop();
}
void DS1302::DS1302_clock_burst_write(uint8_t *p)
{
_DS1302_start();
_DS1302_togglewrite(DS1302_CLOCK_BURST_WRITE, false);
for(int i = 0; i < 8; i++)
{
_DS1302_togglewrite(*p++, false);
}
_DS1302_stop();
}
void DS1302::init(int seconds, int minutes, int hours, int dayOfWeek, int dayOfMonth, int month, int year, bool format, bool morning)
{
DS1302_write(DS1302_ENABLE, 0);
DS1302_write(DS1302_TRICKLE, 0x00);
memset((char *) &dateTime, 0, sizeof(dateTime));
dateTime.Seconds = bin2bcd_l(seconds);
dateTime.Seconds10 = bin2bcd_h(seconds);
dateTime.CH = 0;
dateTime.Minutes = bin2bcd_l(minutes);
dateTime.Minutes10 = bin2bcd_h(minutes);
if(format == H24)
{
dateTime.h24.Hour = bin2bcd_l(hours);
dateTime.h24.Hour10 = bin2bcd_h(hours);
dateTime.h24.hour_12_24 = 0;
}
else
{
dateTime.h12.Hour = bin2bcd_l(hours);
dateTime.h12.Hour10 = bin2bcd_h(hours);
dateTime.h12.AM_PM = morning;
dateTime.h12.hour_12_24 = 1;
}
dateTime.Date = bin2bcd_l(dayOfMonth);
dateTime.Date10 = bin2bcd_h(dayOfMonth);
dateTime.Month = bin2bcd_l(month);
dateTime.Month10 = bin2bcd_h(month);
dateTime.Day = dayOfWeek;
dateTime.Year = bin2bcd_l(year - 2000);
dateTime.Year10 = bin2bcd_h(year - 2000);
dateTime.WP = 0;
DS1302_clock_burst_write((uint8_t *) &dateTime);
}
void DS1302::read(void)
{
DS1302_clock_burst_read((uint8_t *) &dateTime);
}
void DS1302::print(void)
{
char buffer[128];
sprintf(buffer, "Time = %02d:%02d:%02d, ",
bcd2bin(dateTime.h24.Hour10, dateTime.h24.Hour),
bcd2bin(dateTime.Minutes10, dateTime.Minutes),
bcd2bin(dateTime.Seconds10, dateTime.Seconds));
Serial.print(buffer);
sprintf(buffer, "Date(day of month) = %d, Month = %d, Day(day of week) = %d, Year = %d",
bcd2bin(dateTime.Date10, dateTime.Date),
bcd2bin(dateTime.Month10, dateTime.Month),
dateTime.Day,
2000 + bcd2bin(dateTime.Year10, dateTime.Year));
Serial.println(buffer);
}
#ifndef DS1302_H
#define DS1302_H
#include <stdint.h>
#include <Arduino.h>
#define DS1302_CE_PIN 11 // Reset : 'RST'
#define DS1302_IO_PIN 12 // DATA : 'DAT'
#define DS1302_SCLK_PIN 13 // CLOCK : 'CLK'
#define bcd2bin(h, l) (((h) * 10) + (l))
#define bin2bcd_h(x) ((x) / 10)
#define bin2bcd_l(x) ((x) % 10)
#define DS1302_SECONDS 0x80
#define DS1302_MINUTES 0x82
#define DS1302_HOURS 0x84
#define DS1302_DATE 0x86
#define DS1302_MONTH 0x88
#define DS1302_DAY 0x8A
#define DS1302_YEAR 0x8C
#define DS1302_ENABLE 0x8E
#define DS1302_TRICKLE 0x90
#define DS1302_CLOCK_BURST 0xBE
#define DS1302_CLOCK_BURST_WRITE 0xBE
#define DS1302_CLOCK_BURST_READ 0xBF
#define DS1302_RAMSTART 0xC0
#define DS1302_RAMEND 0xFC
#define DS1302_RAM_BURST 0xFE
#define DS1302_RAM_BURST_WRITE 0xFE
#define DS1302_RAM_BURST_READ 0xFF
#define DS1302_D0 0
#define DS1302_D1 1
#define DS1302_D2 2
#define DS1302_D3 3
#define DS1302_D4 4
#define DS1302_D5 5
#define DS1302_D6 6
#define DS1302_D7 7
#define DS1302_READBIT DS1302_D0
#define DS1302_RC DS1302_D6
#define DS1302_CH DS1302_D7
#define DS1302_AM_PM DS1302_D5
#define DS1302_12_24 DS1302_D7
#define DS1302_WP DS1302_D7
#define DS1302_ROUT0 DS1302_D0
#define DS1302_ROUT1 DS1302_D1
#define DS1302_DS0 DS1302_D2
#define DS1302_DS1 DS1302_D2
#define DS1302_TCS0 DS1302_D4
#define DS1302_TCS1 DS1302_D5
#define DS1302_TCS2 DS1302_D6
#define DS1302_TCS3 DS1302_D7
#define H24 true
#define H12 false
#define AM 0
#define PM 1
class DS1302
{
public:
DS1302();
void _DS1302_start(void);
void _DS1302_stop(void);
void _DS1302_togglewrite(uint8_t data, uint8_t release);
uint8_t DS1302_read(int address);
void DS1302_write(int address, uint8_t data);
void DS1302_clock_burst_read(uint8_t *p);
void DS1302_clock_burst_write(uint8_t *p);
void init(int seconds, int minutes, int hours, int dayOfWeek,
int dayOfMonth, int month, int year,
bool format, bool morning = AM);
void read(void);
void print(void);
struct {
uint8_t Seconds:4;
uint8_t Seconds10:3;
uint8_t CH:1;
uint8_t Minutes:4;
uint8_t Minutes10:3;
uint8_t reserved1:1;
union
{
struct
{
uint8_t Hour:4;
uint8_t Hour10:2;
uint8_t reserved2:1;
uint8_t hour_12_24:1;
} h24;
struct
{
uint8_t Hour:4;
uint8_t Hour10:1;
uint8_t AM_PM:1;
uint8_t reserved2:1;
uint8_t hour_12_24:1;
} h12;
};
uint8_t Date:4;
uint8_t Date10:2;
uint8_t reserved3:2;
uint8_t Month:4;
uint8_t Month10:1;
uint8_t reserved4:3;
uint8_t Day:3;
uint8_t reserved5:5;
uint8_t Year:4;
uint8_t Year10:4;
uint8_t reserved6:7;
uint8_t WP:1;
} dateTime;
};
#endif
#include "DS1302.h"
DS1302 rtc;
void setup()
{
Serial.begin(9600);
/*
RTC initialization (date setter)
ONLY RUN THE FIRST TIME AND COMMENT IT OUT AFTERWARDS !
/!\ Careful : DayOfWeek begins on sunday (= 0) /!\
/!\ PLEASE DON'T USE BOTH OF THE FOLLOWING CALLS /!\
English format setter is not working correctly at the moment, fix is welcome !
*/
// French format
rtc.init(45, 50, 0, 2, 9, 1, 2018, H24);
// English format
rtc.init(45, 47, 1, 2, 9, 1, 2018, H12, PM);
}
void loop()
{
rtc.read();
rtc.print();
delay(5000);
}
@ChaboCode
Copy link

NOTE: If you want to use diferent pins for the module, modify the macros DS1302_CE_PIN, DS1302_IO_PIN and DS1302_SCLCK_PIN

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment