DS1307

tjetson

Senior Member
I bought the DS1307 mini board from Futurlec. I have been using the DS1307.bas from the samples folder in the Porgramming Editor.

I modified it so instead of outputting to an LCD, it outputs to the Terminal (sertxd).

I am receiving weird numbers, like this:

05/02/03 161:249:320
05/02/03 161:249:321
05/02/03 161:249:322
05/02/03 161:249:323
05/02/03 161:249:324
05/02/03 161:249:325
05/02/03 161:249:326
05/02/03 161:249:327
05/02/03 161:249:328
05/02/03 161:249:329
05/02/03 161:249:480
05/02/03 161:249:481
05/02/03 161:249:482
The date part is good, except the month is meant to be 12 instead of 2.

Code:
; Example of how to use DS1307 Time Clock (i2c device)
; Note the data is sent/received in BCD format.

symbol seconds = b0
symbol mins = b1
symbol hour = b2
symbol day = b3
symbol date = b4
symbol month = b5
symbol year = b6
symbol control = b7
symbol temp = b8

' set DS1307 slave address
	i2cslave %11010000, i2cslow, i2cbyte


' uncomment this line to update the clock time
'' goto start_clock 

	pause 1000
' read time and date and display on serial LCD module

main:
	readi2c 0,(seconds,mins,hour,day,date,month,year)
	
	' debug b0 '(optional debug computer to screen)


	let temp = date & %0011000
	sertxd (#temp)
	
	let temp = date & %00001111
	sertxd (#temp,"/")

	let temp = month & %0001000 
	sertxd (#temp)
	let temp = month & %00001111
	sertxd (#temp,"/")

	let temp = year & %11110000
	sertxd (#temp)
	let temp = year & %00001111
	sertxd (#temp," ")

	let temp = hour & %00110000 
	sertxd (#temp)
	let temp = hour & %00001111
	sertxd (#temp,":")

	let temp = mins & %0111000 
	sertxd (#temp)
	let temp = mins & %00001111
	sertxd (#temp,":")

	let temp = seconds & %01110000
	sertxd (#temp)
	let temp = seconds & %00001111
	sertxd (#temp)

	
	sertxd (cr,lf)
	pause 1000
	goto main



'write time and date e.g. to 11:59:00 on Thurs 25/12/03
start_clock:
	let seconds = $00	' 00 Note all BCD format
	let mins    = $59	' 59 Note all BCD format
	let hour    = $11	' 11 Note all BCD format
	let day     = $03	' 03 Note all BCD format
	let date    = $25	' 25 Note all BCD format
	let month   = $12	' 12 Note all BCD format
	let year    = $03	' 03 Note all BCD format
 	let control = %00010000 ' Enable output at 1Hz

	writei2c 0,(seconds,mins,hour,day,date,month,year,control)

	end
This is the code I am using. Why am I getting these weird numbers?
 

westaust55

Moderator
As a starter,

for the masks for month and date, you are missing a 0 (zero)

let temp = date & %00110000
sertxd (#temp)

let temp = date & %00001111
sertxd (#temp,"/")

let temp = month & %00010000
sertxd (#temp)
let temp = month & %00001111
sertxd (#temp,"/")
 

tjetson

Senior Member
Ok, fixed that. Please note that I added the missing zeros to the start instead. That gave more reasonable date values. There was also a zero missing from the minutes mask. I added that zero to the front and the end, but either way didn't make a difference. Now the output is like this:
05/02/03 162:482:804
05/02/03 162:482:805
05/02/03 162:482:806
05/02/03 162:482:807
05/02/03 162:482:808
05/02/03 162:482:809
05/02/03 162:483:01
05/02/03 162:483:02
05/02/03 162:483:03
05/02/03 162:483:04

I messed around with the masks and that altered the results. This led me to believe there might be a problem with the masks.
 
Last edited:

hippy

Ex-Staff (retired)
You're not doing your BCD conversion quite right ...

let temp = seconds & %01110000
sertxd (#temp)
let temp = seconds & %00001111
sertxd (#temp)

Should be -

let temp = seconds & %01110000 / 16
sertxd (#temp)
let temp = seconds & %00001111
sertxd (#temp)
 

westaust55

Moderator
well spotted hippy.

Tentatively can take that one step further and for the upper digit delete the mask so :

let temp = seconds / 16
sertxd (#temp)
let temp = seconds & %00001111
sertxd (#temp)
 

tjetson

Senior Member
You're not doing your BCD conversion quite right ...
Please note that I did not write this. I found this code in the Editor samples folder. But thank you, I will have to wait until tomorrow to try it.

EDIT: Do I have to divide by 16 for every upper digit mask, or is it a different number for seconds, days etc?
 

westaust55

Moderator
Please note that I did not write this. I found this code in the Editor samples folder. But thank you, I will have to wait until tomorrow to try it.

EDIT: Do I have to divide by 16 for every upper digit mask, or is it a different number for seconds, days etc?

You need to divide by 16 to extract the upper digit form each BCD number
 

westaust55

Moderator
which sample file did you get the code form.

The binary clock includes a / 16

eg:
temp = mins AND %00001111
mins = mins AND %11110000 * 10 / 16 + temp

if you direct Rev Ed to the correct file it can be fixed for the next issue of the PE.
 

hippy

Ex-Staff (retired)
Please note that I did not write this. I found this code in the Editor samples folder.
Apologies for that and it does appear the DS1307.bas sample program is wrong, is missing the divide by 16 for the high nibbles. That file appears to be dated August 2003 so I guess it slipped through the testing regime back then.
 

oracacle

Senior Member
bcdtobin, is eassy to use and changes data on the fly

Code:
main:
i2cslave %11010000, i2cslow, i2cbyte
readi2c 0,(secs,mins,hours,days,date,month,year)
gosub BCD_DEC
sertxd (...insert variable etc etc here...)
goto main


BCD_DEC:
let secs = bcdtobin secs
let mins = bcdtobin mins
let hour = bcdtobin hours
let days = bcdtobin days
let date = bcdtobin date
let month = bcdtobin month
let year = bcdtobin year
return
you can also go the other way with bintodcd - can you tell i just learnt and used recently ;)
 

tjetson

Senior Member
BCD to Bin doesn't appear to be a valid command, at least not for the 18X, which I am using.

EDIT: But, in any case, I have got it to work. Thank you for your help. I used the time setting wizard (which I was previously unaware of) to set the time, then I used the following:
Code:
' set DS1307 slave address
	i2cslave %11010000, i2cslow, i2cbyte


' uncomment this line to update the clock time
'' goto start_clock 
symbol seconds = b0
symbol mins = b1
symbol hour = b2
symbol day = b3
symbol date = b4
symbol month = b5
symbol year = b6
symbol temp = b7
symbol control = b8

	pause 1000
' read time and date and display on serial LCD module

main:
	readi2c 0,(seconds,mins,hour,day,date,month,year)
	
	' debug b0 '(optional debug computer to screen)


	let temp = date & %00110000 / 16
	sertxd (#temp)	
	let temp = date & %00001111
	sertxd (#temp,"/")

	let temp = month & %00010000 / 16
	sertxd (#temp)
	let temp = month & %00001111
	sertxd (#temp,"/")

	let temp = year & %11110000 / 16
	sertxd (#temp)
	let temp = year & %00001111
	sertxd (#temp," ")

	let temp = hour & %00110000 / 16
	sertxd (#temp)
	let temp = hour & %00001111
	sertxd (#temp,":")
	
	let temp = mins & %01110000 /16
	sertxd (#temp)
	let temp = mins & %00001111
	sertxd (#temp,":")

	let temp = seconds & %01110000 / 16
	sertxd (#temp)
	let temp = seconds & %00001111
	sertxd (#temp)

	
	sertxd (cr,lf)
	pause 1000
	goto main



'write time and date e.g. to 11:59:00 on Thurs 25/12/03
start_clock:
	let seconds = $00	' 00 Note all BCD format
	let mins    = $59	' 59 Note all BCD format
	let hour    = $11	' 11 Note all BCD format
	let day     = $03	' 03 Note all BCD format
	let date    = $25	' 25 Note all BCD format
	let month   = $12	' 12 Note all BCD format
	let year    = $03	' 03 Note all BCD format
 	let control = %00010000 ' Enable output at 1Hz

	writei2c 0,(seconds,mins,hour,day,date,month,year,control)

	end
 
Last edited:

westaust55

Moderator
BCD to Bin doesn't appear to be a valid command, at least not for the 18X, which I am using.
You are correct wrt the 18X .

bcdtoascii and bintoascii are valid PICAXE BASIC commands for all chips.


bintobcd and bcdtobin are extra commands that are only supported on the X1 and X2 parts.
See manual 2 (currently Rev6.9) page 23
 
hi, a couple of quick questions, does the 1307, output the time in bcd ?

in the ds1307 program what exactly are these conversions doing ?

let temp = hour & %00110000
serout 7,N2400,(#temp)
let temp = hour & %00001111
serout 7,N2400,(#temp,":")

let temp = mins & %0111000
serout 7,N2400,(#temp)
let temp = mins & %00001111
serout 7,N2400,(#temp,":")

let temp = seconds & %01110000
serout 7,N2400,(#temp)
let temp = seconds & %00001111
serout 7,N2400,(#temp)

for example are they converting bcd to binary or bcd to ascii or ?

and further more how does it work, the conversion i mean.

thanks.
lachlan
 

BeanieBots

Moderator
Yes, the DS1307 does store it's data in BCD.

That code is masking off bits in order to extract the individual digits.

Consider a byte made up of 8 bits numbered 0 to 7
%76543210

If the hour was 23, it would be stored as 2 in the high nibble and 3 in low nibble which would like this.
%00100011

To get the high nibble you would normall AND the byte with %11110000 but because the hour will never be more than 2, there is no point using the higher bits so it gets ANDed with %00110000

This is repeated for each pair of digits for both high and low nibbles.

Hope that makes sense.
I'm sure others will be able to give a fuller and more precise answer but that should get you going for now.
 

hippy

Ex-Staff (retired)
let temp = hour & %00110000
serout 7,N2400,(#temp)


That, and similar, should be ...

let temp = hour & %00110000 / 16
serout 7,N2400,(#temp)

Otherwise the number shown will be 16 times greater than it should be.
 

westaust55

Moderator
DS1307 for 12 or 24 hour mode

I did a post on a more universal interpretation of the time from the DS1307 previous for those who wish to find that thread, but here is the gist of it (as pseudo code):


M12or24 = hours & %01000000 ; extract AM/PM mode flag first
IF M12or24 = 0 THEN ; check if 0 = 12 or 24 hour mode want to look for 24 hour mode – datasheet does not say :eek:
Temp = hours &00110000 /16 ; when the mode is 24 hour
M12or24 = 24
ELSE
Temp = hours &%0001 /16
M12or24 = hours & %00100000 / 32 ; 0 if AM and 1 if PM
ENDIF
IF M12or24 = 0 THEN
Output AM indicator
ELSE IF M12or24 = 1 THEN
Output PM indicator
ENDIF ; no indicator if in 24 hour mode


Deal with output of 10s digit
Temp = hours & %00001111
Deal with output of units digit
 
Last edited:
im not sure if anyone saw another thread where i was trying to get my silly i2c bus working, but anyway i have sorted out all my problems, except that if i set the time with the wizard it seems to be 41 minutes behind. if i use the wizard and change it to manual, it seems to work.
 
Last edited:

hippy

Ex-Staff (retired)
@ Lachlanmiller : Your issues appear to be down to your own implementation and bugs within your code. It is probably best to continue discussions on these issues in your original thread. DS1307 setting and operation will work as expected with bug-free code.
 

Pauldesign

Senior Member
I my opinion, your computer time might be incorrect. Correct the time, click apply then Ok and restart the simulation. (Ensure only one simulation is running at a time)

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Not part of the above thread, but just to comment about the date/time format. PICAXE is using hexadecimal and BCD interchangeably.
Technically, the display is in hexadecimal format (according to the PICAXE manual 2_constant and PICAXE programming Editor) not decimal format.
e.g 11:59 is in Hexadecimal format and its BCD/Bin and Dec equivalent in value are respectively 00010001 : 01011001 and 17:89


What worries me are the following

1) The actual left to right computation.

e.g Can some body pls compute this stepwise,

let temp = year & %11110000/16
serout 7,N2400,(#temp)
let temp = year & %00001111
serout 7,N2400,(#temp," ")

to display a year of $03.

2) Is it possible to write the year as $2003 instead of $03 to avoid the Y2K saga?

3) Is it possible to make the 'second' routine to count continuously at a rate of 1Hz (in real life)? instead of jumping.

Rgds

Paul
 

MartinM57

Moderator
1) more strictly this code displays the string "03" since it has converted the BCD from the DS into two integers and then #'ed them out via sertxd which displays the ASCII string versions of those integers

2) if you really wanted to:
let temp = year & %11110000/16
serout 7,N2400,("20",#temp)
let temp = year & %00001111
serout 7,N2400,(#temp," ")

3) Yes - you could use the 1 Hz SWQ output - either poll it to see if its changed since last time you polled it, or use it to drive an interrupt - and read the DS only when needed. Usefully, from the data sheet "With the square-wave output set to 1Hz, the clock registers update on the falling edge of the square wave" - so if you detect the falling edge only and read the DS pretty quickly afterwards, you will get a good result. A little complex, but someone might come up with some code for you...
 
Last edited:
MartinM57, this doesnt resolve the y2k saga, and Pauldesign, no the ds1307 supports 2 characters to my knowledge, and only supports up to 2100, with leap year correction etc etc anyway
 

hippy

Ex-Staff (retired)
It's not totally clear during which actual period the DS1307 will be valid. The datasheet says "up to 2100" which I take as meaning works correctly until the day of 28th Feb 2100 comes to an end.

Year 2000 was an anomaly in the commonly held, "a leap year is one which can have its year number divided by four with no remainder", rule; but the full rule adds, "except when it's also divisible by 100 with no remainder when it's not a leap year, but it is a leap year if also divisible by 400 with no remainder".

Hence 2000 was a leap year, 2100 will not be.

The DS1307 will report 1st March 2100 as 29th Feb 2100. This can be dealt with programmatically at that time and resetting it correctly will have it continue to work as expected.

It will come back into synch for 2400 to 2499 :)
 

Dippy

Moderator
By 2400 we'll be on pin-head sized 468X6567 PICAXE with direct neural connection or the data sheets and an auto-hippy clairvoyant code-writing state engine algorithmic generator which invites people to say "Awesome" and "cool" every time the code is produced.
Self-inserting Swannboards for protoyping and self-soldering project boards.
On the Forum people will just say "I want" and the Hiptronic code generator will leap into action.
 

BeanieBots

Moderator
On the Forum people will just say "I want" and the Hiptronic code generator will leap into action..
It will be more avanced than that.
The auto-hippy clairvoyant code-writing state engine will have produced the code BEFORE the post, so it's actually back to square one. The poster will need to SEARCH the forum for the answer prior to responding "cool dude".
 

tjetson

Senior Member
I didn't expect this old thread to be getting new replies now. I'm just glad that I finally got the darn thing to work. Now Rev Ed just has to be sure to put a working file in the samples folder for the next release of PE.
 
Last edited:
is the led and resistor manditory on the sqw output, because i think that my chip lost a second in the last few hours after i removed the led and resistor. although, it could just be that the chip has the correct time. and that my program looping reporting the time, is taking different times sometimes. if that makes sense.
 

BeanieBots

Moderator
No, it is not required and will not effect time keeping in any way.
I've found it to be accurate to around 1 minute / month when knocked up on vero-board.
 
Top