Vous êtes sur la page 1sur 4

Using the Dallas Semiconductor DS1307 I2 C RTC

(Real Time Clock) IC with the BasicMicro Atom Series


8 April 2010 By Ken Jennejohn
This part is usable with all BasicMicro AtomPro parts except for the Pro One. The P#s used in the
code were based on the use of BasicMicro Development Boards, which hardwire the PortB pins (P0
thru P7) for LCD use. The user is free to breadboard this circuitry and use any pinouts he/she wishes.
The Maxim data sheet for this Dallas Semi part is available at:
http://datasheets.maxim-ic.com/en/ds/DS1307.pdf
These are available at DigiKey, Mouser, Jameco Electronics (cheapest), or any number of online sites
selling to hobbyists.
A quick dump of the features set from the DS1307 sheet:

GENERAL DESCRIPTION
The DS1307 serial real-time clock (RTC) is a lowpower, full binary-coded decimal (BCD)
clock/calendar plus 56 bytes of NV SRAM. Address and data are transferred serially through
an I2 C, bi-directional bus.
The clock/calendar provides seconds, minutes, hours, day, date, month, and year
information. The end of the month date is automatically adjusted for months with fewer than
31 days, including corrections for leap year. The clock operates in either the 24-hour or 12hour format with AM/PM indicator. The DS1307 has a built-in power-sense circuit that detects
power failures and automatically switches to the backup supply.
Timekeeping operation continues while the part operates from the backup supply.
I got interested in this chip because I had started doing an app note on various methods to arrive at
RTC (Real Time Clocks) with Atom parts. For now, you get this sheet.
My original RTC application was in implementing a 100-hour burn-in timer for new circuit boards at
my place of employment. I found just doing PAUSE 1000 to fake the passage of a single second led
to wildly inaccurate timing. This led to using interrupts using internal timers, which worked better and
accurately, but fell down when adding other testing tasks to the burn-in process. This led to other
methods, such as using an RTC crystal across PortC pins to implement a really good clock (check out
the post at:
http://forums.basicmicro.net/viewtopic.php?f=497&t=9149&sid=a4f30773ec69cb66e69cfd51755406fe
or using the 60Hz output of an AC adapter (low voltage, of course) to drive an interrupt pin to get a
satisfactory clock to arrive at a TOD (Time Of day) clock. For purposes of data logging or time
stamping your test results, this becomes a real burden on the processor. I mean, you can miss these
time-keeping interrupts when doing other work. Thats one of the limitations of BASIC interrupts on
the Atom. Using PAUSE or SERxxx commands blocks timely interrupts. Even using ISRASM (real
assembly interrupts) now available in Studio compilers, which I tried, found that time keeping became
inaccurate for various physical reasons.
Which brings us to the DS1307. It suffers no distractions from its time keeping job. This IC has its
own RTC crystal, running at 32.768 KHz, to keep rock-steady timing. It even offers some handy
options beyond the RTC: It has 56 bytes of storage beyond the original 8 bytes for date and time
values, a square wave output for interrupts (or whatever), and even offers battery backup when power
goes out.
NOTE: The options mentioned are touched on here, but never really put to use.

The extra memory registers are a moot point with an AtomPro28-M and Pro40-M, as both have 4K
EEPROM ICs. However, The AtomPro24-M has none, so this may prove useful indeed.
Adding a battery is a pretty simple process. A two-battery holder from RadioShack using AAs
worked just fine. If no battery is used, the sheet says to install pin 3 to ground. Battery voltage can be
2V to 3.5V. Since all the memory on this is SRAM, including the date/time registers, the battery
becomes important if you want to maintain time keeping and/or data when Vcc is removed from pin 8.
Battery power can be as low as 10 nA (oscillator off) to 300 nA typical, 500 nA worst case. Even two
AAA batteries will suffice for several days.
The square wave output can be disabled or set to 1Hz, 4096 Hz, 8192 Hz or 32,768 Hz operations.
In the code I just have the AtomPro read the date/time registers every 330 milliseconds. If the seconds
value has changed, I update the displayed date and time. Setting the square wave output to 1 Hz and
driving a time-updating interrupt with it guarantees this never happens. Or you can use a higher output
rate and use the exact timings to achieve accurate data scans with known time-stamps if the I2C access
rate is high enough. Youll note in the circuit drawing it points to an optional pullup resistor on pin 7,
the SQW-OUT pin. Yep, this is for the square wave output. If you dont use this feature you can leave
this resistor out. Use the following values for setting up the square wave output:
Value $0
$10
$11
$12
$13
Output is None
1 Hz
4096 Hz
8192 Hz
32,768 Hz

Here is the circuit diagram.

I show the optional square wave output on pin 7 going to P0 to use the EXTINT (external interrupt)
feature of the AtomPro module. If youre using one of the BasicMicro Development Boards and you
want to use the LCD for display, this feature is lost to you. P0 is the RegSel pin on the LCD. Of
course, if this is simply a TOD clock, or users code is a set of minor tasks with date/time displayed,
you can have the code check the input level on one of the pins and react to the square waves level.
Using P10 for this input, this would look like:
IF IN10 = 0 then GOSUB Read_Time ; look for P10 to go low. If so, go
to subroutine that gets date/time info from DS1307 and display it.

And so we come to the code.


This code is well commented, so lots of explanation is unneeded. The short explanation is:
1. Hand enter the values for seconds, minutes, hours, day number (1 to 7), date, month, year
(The day value refers to the day of the week. This register increments 1 thru 7, as the days pass.
The user can use this value and a lookup table to track which day of the week it is. It isnt used in
this demo.) The bin2bcd converts these values to BCD, Binary Coded Decimal. Search the
manual using bin2bcd for an explanation.
2. Set the date/time registers (0 to 7) using I2COUT.
3. A one second pause to let DS1307 start up and run time registers
4. The read routine, which consists of
4a. an I2COUT to set the starting register address to 0
4b. an I2CIN to read the date/time registers in
4c. Several bcd2bin commands convert the BCD values back to normal
5. A report_ routine to display the time and date information to the LCD and terminal display built
into the IDE.
We then loop back to the read routine and do it all over.
And now for the dingbat part: If the user plans to keep adding or changing the code, you have to
watch for one problem. After programming the Atom and running it, if you cycle power (on/off) or
press the RESET switch, the Atom reprograms the DS1307 with the old time you set originally. This is
rather upsetting if youve gone to the trouble to install a backup battery so as not to lose the time.
The solution is to simply comment out the line that writes the initial date and time info to the DS1307.
BTW, I set this for 24-hour operation. Read the sheet for AM/PM operation.
[CODE STARTS]
; A small program demonstrating the use of a DS1307 RTC IC with the AtomPro28/40
; 8 April 2010 by Ken Jennejohn
; This has been tested with anAtomPro28 module. I dont have the Pro24 or Pro40,
; but am confident this should work OK. If you find otherwise, be sure to let
; me know so I can report it.

;*** A brief pause to allow the ATOM and LCD to initialize after power up ***
PAUSE 1000
;*** Pin Assignments/Constants ***
RegSel con P0
; LCD R/S pin
ClkPin con P1
; LCD enable pin
SCL con P8
; DS1307 clock pin
SDA con P9
; DS1307 data pin
Ctrl1307 con %11010000 ; I2C control value for DS1307
;*** Variable Initialization ***
secs var byte
mins var byte
hrs var byte ; hours
day var byte ; day number (day of week)
date var byte
month var byte
year var byte
flag var byte
CLEAR

; set all variables to zero

; Initialize LCD
LCDINIT RegSel\ClkPin\P7\P6\P5\P4

; Initialize Studio terminal display


; Use programming port for serial communications, clear screen, home cursor, ring
; bell, print Starting, do two carriage returns.
SEROUT s_out, i9600, [0, 7, Starting, 13, 13]
HIGH P3

; Turn on LCD backlight

; Enter initial DS1307 Time/Date values: 19:30 (7:30PM), 5 April 2010


secs = bin2bcd 00 ; might as well start with zero seconds
mins = bin2bcd 30
hrs = bin2bcd 19
day = bin2bcd 2
; A Monday. I decided it was 2nd day of week
date = bin2bcd 05
month = bin2bcd 04
year = bin2bcd 10 ; note two-digit year. Add 20 later if you want
; Write values to DS1307 with next line
; Once you program the DS1307 initially, I suggest you comment this line out.
; That allows you to change and reprogram code without reprogramming the DS1307.
; Square wave output is set to 1 Hz using $10.
I2COUT SDA, SCL, ctrl1307, [0, secs, mins, hrs, day, date, month, year, $10]
PAUSE 1000

; Wait one second for DS1307 to start up

; MAIN loop
MAIN
I2COUT SDA, SCL, ctrl1307, [0] ; set start register to 0
I2CIN SDA, SCL, ctrl1307, [secs, mins, hrs, day, date, month, year]
; Convert values from BCD back to normal
secs = bcd2bin secs
mins = bcd2bin mins
hrs = bcd2bin hrs
date = bcd2bin date
month = bcd2bin month
year = bcd2bin year
; print date/time to LCD and serial port
LCDWRITE RegSel\ClkPin\P7\P6\P5\P4,[lcdclear, lcdhome, Time: , dec hrs\2, :, dec
mins\2, :, dec secs\2]
LCDWRITE RegSel\ClkPin\P7\P6\P5\P4, [scrram+$40, Date: , dec date, /, dec month, /,
dec year]
; Note the pipe symbol at the end of the next line. This allows the command to continue to
; the next line down. The 0 (zero) clears the screen and homes the cursor if using
; Studios terminal window.
SEROUT s_out, i9600, [0, Time: , dec hrs\2, :, dec mins\2, :, dec secs\2, 13, |
Date: , dec date, /, dec month, /, dec year, 13, 13] ; ends in 2 new-lines.
PAUSE 330 ; Read DS1307 three times a second
GOTO MAIN
[CODE ENDS]

And now for some notes:


1. Feel free to place more code in the MAIN loop to do extra work. This added code would probably
use the DS1307 to provide date, time and data storage.
2. Its a pain, but when you program this, your seconds count wont typically be right if you expect 0
seconds at the start when the clock or watch says it is zero seconds. I found if I started
programming 25 to 30 seconds before the exact time I set it for, it was close to within a couple of
seconds of the clocks zero when done. That is, if you set the DS1307 time to start at 7:30:00, then
you want to start programming the Atom around 7:29:30.
Of course, if you just want a TOD clock, dont report the seconds in the display.

Vous aimerez peut-être aussi