Management of the RTC DS1307 module
published: 12 November 2019 / updated 12 November 2019
The real-time clock or RTC (Real Time Clock) DS1307 provides the date and time to the Arduino board via the I2C link.
Introduction
Find all the explanations on the RTC DS1307 module here:
Module DS1307 RTC
Example of connecting the RTC DS1307 module to an ARDUINO MEGA board:
Find all the explanations on the I2C bus here:
L'interface I2C des cartes ARDUINO
Programming and using the RTC DS1307 module via the I2C bus
addr-ds1307
constant contains the hexadecimal value $68.
This value was determined by analyzing the connected and active modules on our I2C bus,
via the word i2c.detect
available here:
L'interface I2C des cartes ARDUINO
\ i2c device address
$68 constant addr-ds1307
The word i2c!
passes a byte on the I2C bus and rejects the status flag of
transmission:
: i2c! ( c ---)
i2c.c! drop ;
The word ds1307.addr!
passes a byte to our RTC DS1307 module:
: ds1307.addr! ( c -- ) \ Set ds1307 register address i2c.init addr-ds1307 i2c.addr.write drop i2c! i2c.stop ;
Initialization and recovery date and time
The word time!
passes the date and time information to the RTC DS1307 module:
: time! ( Y M D d HH MM SS -- )
i2c.init addr-ds1307 i2c.addr.write drop
0 i2c!
i2c! i2c! i2c!
i2c! i2c! i2c! i2c!
i2c.stop
;
The word time@
retrieves the date and time information from the
RTC module DS1307.
: time@ ( -- S M H d D M Y )
0 ds1307.addr!
addr-ds1307 i2c.addr.read drop
i2c.c@.ack i2c.c@.ack i2c.c@.ack
i2c.c@.ack i2c.c@.ack i2c.c@.ack i2c.c@.nack
i2c.stop
;
ATTENTION: information transmitted and received to and from RTC module DS1307 must be in BCD format.
BCD format
The BCD format is a format that encodes in one byte two decimal values. Example:
- 1 will be encoded %00000001
- 9 will be encoded %00001001
- 10 will be encoded %00010000
- 99 will be encoded %10011001
Chaque moitié d'octet correspond à la valeur en binaire d'un chiffre allant de 0 à 9 exclusivement. Sur un octet, on ne peut donc coder que des valeurs allant de 00 à 99.
L'encodage BCD permet de simplifer la transformation binaire vers décimal et inversement.
Le mot bin>bcd
transforme une valeur binaire pure en valeur encodée en BCD.
: bin>bcd ( c -- c )
#10 u/mod #4 lshift or
;
Example: 13 in pure binary is written %00001101. Once converted
in BCD, 13 bin>bcd
, 13 will be written as% 00010011.
If we cut in two our byte %00010011, we find %0001 at the top, therefore the number 1 of the number 13, %0011 in the lower part, so the number 3 of the number 13.
Transmission date and time
This is the word set-time
that we will use to transmit
the date and time information to initialize the RTC DS1307 module:
: set-time ( year month date day hour min sec -- ) >r >r >r >r >r >r \ $00 swap \ 11 = 4.096 KHz output 00 = no output bin>bcd \ Year 0-99 r> bin>bcd \ Month r> bin>bcd \ Date r> \ Day 1-7 r> bin>bcd \ Hours r> bin>bcd \ Minutes r> bin>bcd \ Seconds time! ;
The word set-time
expects 7 parameters, which are in order:
- year: current year, on two digits. 19 for 2019 li>
- month: Current month, on one or two digits. 11 for November
- date: current day, one or two digits. 13 by 13 Nov 2019
- day: number of the day in the week, 1 for Monday, 2 for Tuesday, etc ...
- hour: current time, from 0 to 59.
- min: current minute, from 0 to 59.
- sec: current second, from 0 to 59.
The set-time
word performs the necessary BCD encodings before
pass the data to the word time!
.
Example of use:
i2c.init 19 11 12 2 18 06 0 set-time
From this moment, the RTC module advances its internal clock without it is necessary to intervene. You can disconnect the ARDUINO board. The RTC module DS1307 will restore the correct date and time when the ARDUINO board is restarted.
Retrieving and decoding the time and date
The word bcd>bin
transforms BCD encoded data into pure binary:
: bcd>bin ( c --- c)
#16 u/mod 10 * + ;
Formatting data to display
The words that follow are used to format the data to display.
The word :##
transforms 2 digits of the seconds and minutes in the format :SS and :MM.
The word :##
is then used in the HMS
word that handles
three values retrieved from the RTC DS1307 module and reconstructs the time in HH:MM:SS format.
The word DMY
retrieves the data day month and year and restores the date in format DD/MM/YYYY.
: :## ( d1 --- d2 ) decimal # 6 base ! # decimal [char] : hold ; : HMS ( s m h --- adr len) bcd>bin 3600 um* rot bcd>bin 60 um* d+ rot bcd>bin 0 d+ <# :## :## #s #> ; : DMY ( d m y --- adr len) bcd>bin 0 <# # # [char] 0 hold [char] 2 hold 2drop bcd>bin 0 [char] / hold # # 2drop bcd>bin 0 [char] / hold # # #> ;
And finally, the word .date
retrieves data from the RTC DS1307 module and
displays this data in DD/MM/YYYY format HH:MM:SS
: .date ( ---)
time@ DMY type space
drop HMS type
;
Example of running .date
:
.date 12/11/2019 18:06:00 ok<#,ram> .date 12/11/2019 18:06:06 ok<#,ram> .date 12/11/2019 18:06:11 ok<#,ram> .date 12/11/2019 18:06:50 ok<#,ram>