DS1307 Issues

mproia

Member
Hi,

I am revisiting a problem I had a long time ago with the output of my DS1307. I used code to overcome this problem before but I want to understand why this is happening.

When I ouput to my LCD the hour and minute from my DS1307 board (http://www.futurlec.com/Mini_DS1307.shtml) it work except for 9 PM and 8 PM.
For 8 PM I get the output 0>:00 PM and for 9 PM I get 0?:00 PM.

Can someone please help me with this? I opted for converting 24 hour format to AM PM format through coding instead of reproggramming the DS1307 for AM PM mode. Thhis was frustrating me as well. :mad:

Here is my code.


#picaxe 28x1 'Sets type of picaxe chip for this program

setfreq m8 'You need to set freq. to 8hz to get a 9600 baud

symbol seconds = b0
symbol minutes = b1
symbol hour = b2
symbol day = b3
symbol date = b4
symbol month = b5
symbol year = b6
symbol control = b7
symbol ampm = b10


serout 7,T9600_8,(254, $01) 'Clears Screen

hi2csetup i2cmaster,%11010000,i2cslow_8,i2cbyte


main:

hi2cin 0, (seconds,minutes,hour,day,date,month,year,control)


'Set ampm variable


if hour >= $12 and hour < $24 then let ampm = 1
else let ampm= 0
endif


'12 hour time for LCD display



if hour > $12 and hour < $24 then let hour = hour - $12
elseif hour = $0 then let hour = $12
else let hour = hour
endif
bcdtoascii hour,b8,b9


if ampm =1 then serout 7,T9600_8,(254, 197," ",b8,b9,":"): serout 7, T9600_8, (254, 204, "PM")
else serout 7,T9600_8,(254, 197," ",b8,b9,":"): serout 7, T9600_8, (254, 204, "AM")
endif


bcdtoascii minutes, b8,b9 'Displays minutes
serout 7,T9600_8,(254, 201,b8,b9)

b8 = minutes
minutes = b8 / 16 * 10
minutes = b8 & $F + minutes

goto main



Thanks!!!!
 

hippy

Ex-Staff (retired)
if hour > $12 and hour < $24 then let hour = hour - $12

That will be giving some problems because, for example, $20 - $12 = $0E not $08 you are hoping for.
 

westaust55

Moderator
In the hours register, bit 5 is an AM/PM flag in 12 hr mode.
Rather than subtract, once you have checked the status of the flag ( Am_PM = hours AND $20)
You can then remove the Am/Pm flag and 12/24 hrs flags with
Hours = hours AND $3F


Note also that it is good practice to place you program listing within [code] and [/code] tags so it appears as a s rolling sub window within your post.
 

westaust55

Moderator
@marks,
Your own code example also uses the
Hours = hours -$12
but preempts with a test for $20 and $21 but not $22 or $23?
Consider setting your ds1307 to 12 hr mode then just test the am/pm flag as I have
mentioned above then mask the bits using bitwise AND so you are left with the correct value without then need for IF...THEN tests and subtractions.
 

marks

Senior Member
Thats what's great about Picaxe so many solutions and we can always improve!
actually my code for 12 hr format is
LET hours = hours - $40 :AM_PM = "A"
IF hours > $20 THEN : LET hours = hours - $20 : AM_PM ="P": ENDIF

Like pointed out clever use of the AND function we can use something like this for 12hr format(untested lol)
AM_PM = "A" : IF hours > $60 then AM_PM ="P"
hours=hours AND $1F

When we use 24hr format and convert to 12hrs as the original programmer intended
we can use - $12 however $20 and $21 are incorrect returning $0E and $0F as indicated by Hippy .
all other numbers used are correct!

I myself prefer the 24 hour format
I dont mind when 00.00am is returned as midnight(start of day)
when programming an alarm 12am or 12pm is often confusing
(while not correct i think of these as after midnight and proir to midnight)
programming 1200 is a lot easier for an alarm at midday !
 

hippy

Ex-Staff (retired)
I myself prefer the 24 hour format
Likewise. If one cannot use 24 hour for some reason, converting 12 hour to 24 as soon as possible, processing that, then converting back to 12 hour for display is usually far less error prone. The potential for error is compounded with the DS1307 and similar because it's BCD not pure decimal.

I've seen some horrible mistakes using 12 hour ( not at Rev-Ed I'll add ) where the AM/PM LED goes on and off at 01:00 for example.
 

g6ejd

Senior Member
BTW you could simply your code lines like this one:
if ampm =1 then serout 7,T9600_8,(254, 197," ",b8,b9,":"): serout 7, T9600_8, (254, 204, "PM")
else serout 7,T9600_8,(254, 197," ",b8,b9,":"): serout 7, T9600_8, (254, 204, "AM")
endif

To:

if ampm =1 then serout 7,T9600_8,(254, 197," ",b8,b9,":",254, 204, "PM")
else serout 7,T9600_8,(254, 197," ",b8,b9,":",254, 204, "AM")
endif
 

westaust55

Moderator
or even:
Code:
IF ampm = [COLOR="#FF0000"]0[/COLOR] THEN 
	ampm = "A"
ELSE
	ampm = "P"
ENDIF
	
serout 7,T9600_8,(254, 197," ",b8,b9,":",254, 204, ampm, "M")
 
Last edited:

inglewoodpete

Senior Member
or even:
Code:
IF ampm =1 THEN 
	ampm = "A"
ELSE
	ampm = "P"
ENDIF
	
serout 7,T9600_8,(254, 197," ",b8,b9,":",254, 204, ampm, "M")
For the record, I think that reverses AM and PM. Isn't AM=0 and PM=1?

As an aside and to simplify the code even further, replace
Code:
IF ampm =1 THEN 
	ampm = "A"
ELSE
	ampm = "P"
ENDIF
with
Code:
ampm = ampm * 15 + "A"
 

westaust55

Moderator
For the record, I think that reverses AM and PM. Isn't AM=0 and PM=1?

As an aside and to simplify the code even further, replace
Code:
IF ampm =1 THEN 
	ampm = "A"
ELSE
	ampm = "P"
ENDIF
with
Code:
ampm = ampm * 15 + "A"
Well spotted IWP.
And the alternate method to determine AM or PM saves another 8 bytes.
 
Top