RTC Help! Please

#1
Hello, i was wondering if anyone could help me with my program for real time clock. i have used the Picaxe Programming Editor Wizard to generate a program, this is what it has generated.

'AXE110 BASIC Program to set time/date on DS1307 RTC
'Automatically generated by Wizard

'Make sure DS1307 chip and cell inserted on datalogger module
'and that the cable is in the 'run' position.
'After downloading, status LED will be Green for pass or Red for fail.
'After success, download empty program to PICAXE to prevent
'time being reset on next power-up of board.

'First program the date
high 5 ' write protect eeprom

i2cslave %11010000, i2cslow, i2cbyte
writei2c 0, ($00, $34, $15, $05, $23, $08, $07, $10)
pause 50

'Now check has been set OK
let b8 = $05
let b9 = $23
let b10 = $08
let b11 = $07
let b12 = $10

readi2c 0, (b0,b1,b2,b3,b4,b5,b6,b7)

if b7 <> b12 then fail
if b6 <> b11 then fail
if b5 <> b10 then fail
if b4 <> b9 then fail
if b3 <> b8 then fail
ok:
high 3
goto ok
fail:
high 2
goto fail

Does anyone know a webpage that i can post a picture to (for my PCB design)
thanks
 

Tom2000

Senior Member
#2
You didn't mention what problem you might be having.

The only possible problem I see is in the way you're writing the set info to the 1307. I think you need to write to all other registers before you write seconds.

Try changing

<code><pre><font size=2 face='Courier'>

writei2c 0, ($00, $34, $15, $05, $23, $08, $07, $10)

</font></pre></code>

to

<code><pre><font size=2 face='Courier'>

writei2c 1, ($34, $15, $05, $23, $08, $07, $10)
writei2c 0,(0)

</font></pre></code>

I'm not sure you need to do this, but I took a look at some code I wrote for a 1307 and 18X a while back, and noticed I was using that method.

If that still doesn't work, please post the problems you're experiencing.

Good luck!

Tom
 
#3
I have no problem with the program downloading to the Real time Clock,(i am using a PICAXE 18X by the way). Is there any way that i can display the time been read from the real time clock via the computer?
also i think i may need to change come of the settings on the program, things such as

Fail:
high 2
goto fail.

this is a problem as the LED which is used to indicate the program Fail is running isnt connected to the picaxe, it is connected to the output of the Real Time Clock.
Secondly i do not have an EEPROM on my board, or does the PICAXE 18X work as one of these.

if anyone could help it would be a great help, its for a school project and its due in about 2 weeks, thanks
 

Tom2000

Senior Member
#5
OK. Let's see what we can do.

First of all, you haven't mentioned what sort of display you want to use to display the time. Second, since it's a school project, I'll just give you some tips you can use to build your own solution rather than posting finished code.

Your first task is to become familiar with the internals of the DS1307. You can find the data sheet here: <A href='http://datasheets.maxim-ic.com/en/ds/DS1307.pdf' Target=_Blank>External Web Link</a> If you haven't previously done so, please download and familarize yourself with this document before proceeding.

The data format used by the 1307 is, for the most part, BCD, with the most significant decimal digit stored in the top four bits, and the least signifgant decimal digit stored in the bottom four bits. PicBASIC has a function, bcdtoascii, that you can use to easily parse these two packed BCD digits into ASCII characters that you can send to a display.

Handling the Hours register is a little tricky. Contained in the upper bits of that register is a flag (bit 6) that sets the 1307's internal timekeeping format to either 12 or 24 hour mode. When you set the time, you need to either set or clear this bit, depending upon your desired timekeeping format. Also, in 12 hour mode, a flag in bit 5 indicates either AM (cleared) or PM (set).

Let's say you're going to use 12 hour mode, and the time is 3 AM. You're using b6 to store the value that you'll be writing to the 1307's Hours register. You'd set the time like this:

1. First, load the time into b6:

<code><pre><font size=2 face='Courier'>


b6 = $03
</font></pre></code>

2. Set the 12/24 hour flag:

<code><pre><font size=2 face='Courier'>


b6 = b6 | %01000000
</font></pre></code>

3. It's AM, so clear the AM/PM flag:

<code><pre><font size=2 face='Courier'>


b6 = b6 &amp; %11011111
</font></pre></code>

Now b6 is ready to be written to the 1307 when you set the time.

Likewise, when you read the Hours register, you need to first, capture and store the AM/PM flag's state, then strip the AM/PM flag and 12/24 hour flag bits before you process the Hours register value in your display routine.

Let's say that you're using b9 to temporarily store the state of the AM/PM flag, and that you've read the 1307's raw Hours register value into b6. You can also use b9 as a scratchpad register, as shown below:

<code><pre><font size=2 face='Courier'>


b9 = b6 &amp; %00100000 'capture the AM/PM flag's value
if b9 &gt; 0 then 'save the flag's value
b9 = 1
else
b9 = 0
endif
b6 = b6 &amp; %00011111 'strip flag bits
bcdtoascii b6,b0,b1 'ASCII hours x 10 value to b0, hours x 1 value to b1
</font></pre></code>

Processing the rest of the 1307's registers is straightforward.

When I initialize a 1307, I first wait one second after the program starts, then make
sure the CH bit (bit 7 of the Seconds register) is cleared. Also, since the 1307 is probably running on a backup battery when I start my program, I make sure that I don't
change the 1307's time value while I'm initializing the chip. Here's how I do that with the seconds register, and initialize the chip to the 12 hour format while I'm at it:

<code><pre><font size=2 face='Courier'>


Main:

pause 1000
i2cslave %11010000,i2cslow,i2cbyte
pause 100
readi2c 0,(b0) 'clear the CH bit
b0 = b0 &amp; %01111111
writei2c 0,(b0)
readi2c 2,(b0) 'set 12-hour display format
b0 = b0 | %01000000
writei2c 2,(b0)

.

.

.

end
</font></pre></code>

Finally...

You'll probably want to have your program read the time in a loop. It doesn't make any sense to update your time display each time your loop reads the 1307's time, so you'll probably want to update your display only when the seconds change.

To do this, set a variable to store the value of the previous seconds value:

<code><pre><font size=2 face='Courier'>


symbol PrevSecs = b13
</font></pre></code>

In your loop, read the seconds value like this, then call your display routine only when needed:

<code><pre><font size=2 face='Courier'>


do
readi2c 0,(b0)
if b0 &lt;&gt; PrevSecs then
PrevSecs = b0
gosub DisplayTime
endif
loop
</font></pre></code>

That should be enough to get you started. If you have further problems as you work through your assignment, feel free to post them here.

Have fun!

Tom





Edited by - Tom2000 on 23/08/2007 11:03:19

Edited by - Tom2000 on 23/08/2007 11:05:20

Edited by - Tom2000 on 23/08/2007 11:14:49
 

Tom2000

Senior Member
#6
<i>&quot;its connected to the RTC (DS1307) pin SQW&quot; </i>

In the DS1307 data sheet, refer to the Control Register info on page 9 to learn how to handle the SQW/OUT pin.

(I just had an idea. If you want to build an alarm clock, you could use the 4 kHz SQW/OUT signal to drive a piezo or small speaker through a driver transistor. Hmmm.... I feel a new project coming on!)

Tom

Edited by - Tom2000 on 23/08/2007 11:28:06
 
Top