Displaying time in i2c mode.

cfarr

Member
I am trying to read (from the DS1307) and display the real time on the AXE033 when in i2c. The module is being used in i2c, i.e with J1 shored. The code is shown below. However, the time is not being displayed correctly, just character and numbers, else, ie text is ok. Any help to what I am doing wrong.

pause 500
i2cslave $c6, i2cslow,i2cbyte

main: writei2c 0, (254,128,255)
pause 10
writei2c 0, ("the time is ", 255)

pause 500

i2cslave %11010000, i2cslow, i2cbyte

readi2c 0,(b0,b1,b2)
pause 30


clock:i2cslave $c6, i2cslow,i2cbyte


writei2c 0, (254,192,255)
pause 30
writei2c 0, (b0,b1,b2,255)
goto init
 

BeanieBots

Moderator
There are two issues you need to overcome when trying to display time from a DS1307 on an AXE033 in I2C mode.
The first is that the DS1307 is BCD encoded.
The second is that the display must be sent an ASCII and not just the number.
BCD (binary coded decimal) is a neat way of storing a lot of decimal numbers in a small space.
Each byte value read back contains two digits. One in the top four bits (high nibble) and one in the lower four bits (lower nibble).
To decode BCD, first split the byte into two nibbles.
Lets say that the seconds is 23 and you read the value from the DS1307 into b0.
b0 will contain the binary value %00100011
The first four are the "2" and the second 4 are the "3".
First, we only want the "2". We must mask off the lower nibble. That can be done by ANDing with %11110000.
That will give %00100000.
Then 'shift' it down four places to get the real value. That can be simply done by dividing by 16 to give %00000010.

So, for the tens of seconds.
b1=b0 & %11110000
b1=b0/16
A similar process for the units of seconds.
b2=b0 & %00001111 'no shift required for lower nibble.

Now b1 is tens of seconds, b2 is units of seconds.
But, these still cannot be displayed. They must be converted to ASCII.
To do that, simply add $30.
b1=b1+$30. (or you could do b1=b1 + "0")
b2=b2+$30.

Now, if you send b1 and b2 via I2C, you will get the two digits to show seconds.
Just repeat the process for the other data you wish to display.

Don't be put off by my clumsy explanation. It's quite simple once you get your head around it.

Just realised that those nice people at Rev-Ed have added a set of new commands in the latest editor, one of which is BCDTOASCII.
Never used it but looks simple enough.
BCDTOASCII b0,b1,b2 will do what I decsribed above.

Edited by - beaniebots on 25/03/2007 13:33:39
 

cfarr

Member
Many thanks for yr reply. I have tested the code you sent for the seconds and it worked fine. I'll try to figure out the rest for the min and hrs. According to rev-ed, the BCDTOASCII command is available in version 5.0.8. Is this software available?
Best regards...
 

Mycroft2152

Senior Member
BB, for the record, you were describing "Packed" BCD which combines two 4 bit BCD codes into a single 8 bit byte.

<A href='http://en.wikipedia.org/wiki/Binary-coded_decimal#BCD_in_electronics' Target=_Blank>External Web Link</a>

 

cfarr

Member
Dear Sir,

As I already wrote in my previous reply I managed to implement the code you shared with me regarding seconds.

However, I am finding difficulties trying to implement this code for minutes and hours. Can you please give me some help with regards to setting the minutes so that I can catch up with the method that you are using.

Thank you very much, your help is much appreciated.

Regards,
Carmel
 

BeanieBots

Moderator
It's really just a matter of assigning everything to variables.
eg
if you get the values into b0,b1 and b2 for seconds minutes and hours, then each of those required a further two variables for each digit. 3 + 3 X 2 = 9 variables total.
eg
readi2c 0,(b0,b1,b2)
BCDTOASCII b0,b3,b4
BCDTOASCII b1,b5,b6
BCDTOASCII b2,b7,b8

I can't remember the order the data is stored but if you send b3 to b8 to the display you'll work it out soon enough.
 

cfarr

Member
I cannot use the BCDTOASCII as my compiler does not support this command. I wrote this code for the minutes but it is not working.

b1=variable for minutes read from clock
b3,b4=variables assigned for conversion.

'For minutes

b4=b1 &amp; %00001111

b3=b1 &amp; %11110000
b3=b1/16

b3=b1+$30
b4=b4+$30

writei2c 0, (b3,b4,b1,b2,255)

Thank you very much, your help is much appreciated.

Regards,
Carmel
 
BeanieBots
BINTOASCII and BCDTOASCII

Slightly off topic but in response to your BCDTOASCII solution to cfarr.

BCDTOASCII does not work for me either .... is it running on your system?

See original post &quot;BINTOASCII and BCDTOASCII&quot; in this forum and &quot;BINTOASCII and BCDTOASCII Patch5.0.8&quot; in the software forum.

Handy tool if it worked.

Tried your code snippet in my complier - it failed.

Russ

Edited by - AXE_GRINDER323 on 25/03/2007 17:15:32
 

cfarr

Member
I am not using BCDTOASCII. BeanieBots compiled code for the seconds conversion and it worked fine. However, I am trying with the mins and hrs but to no avail.
Line 4 in my recent code should read
b3=b3+$30 but still no luck.

Thanks
Carmel
 

BeanieBots

Moderator
axe_grinder323, They don't work in the current release of the compiler for me either. Never mind, I'm sure it will be fixed very soon. No problem though, BINTOASCII is just BIN + $30 for a single byte.

cfarr, you've got the variables all mixed up!
You will need NINE different variables.
....
readi2c 0,(b0,b1,b2)
b3=b0 &amp; %11110000
b3=b3/16
b3=b3 + $30
b4=b0 &amp; %00001111
b4=b4+$30

b5=b1 &amp; %11110000
b5=b5/16
b5=b5+$30
b6=b1 &amp; %00001111
b6=b6 + $30

b3 and b4 now hold the two digits from b0
b5 and b6 now hold the two digits from b1

Now you do the code to make b7 and b8 hold the two digits that are contained within b3.


Edited by - beaniebots on 25/03/2007 17:54:33
 

cfarr

Member
Finally, I managed to do the job. I agree with you about the variables in the first place. The code is listed below.
'clock display in i2c mode

init:
pause 500
i2cslave $c6, i2cslow,i2cbyte

main: writei2c 0, (254,128,255)
pause 10
writei2c 0, (&quot; THE TIME IS&quot;, 255)

pause 500



i2cslave %11010000, i2cslow, i2cbyte

readi2c 0,(b0,b1,b2)
pause 30


clock:i2cslave $c6, i2cslow,i2cbyte


writei2c 0, (254,192,255)
pause 30

b4=b0 &amp; %00001111

b3=b0 &amp; %11110000
b3=b0/16

b3=b3+$30' (or you could do b1=b1 + &quot;0&quot;)
b4=b4+$30'



b6=b1 &amp; %00001111

b5=b1 &amp; %11110000
b5=b1/16

b5=b5+$30' (or you could do b1=b1 + &quot;0&quot;)
b6=b6+$30'



b8=b2 &amp; %00001111

b7=b2 &amp; %11110000
b7=b2/16

b7=b7+$30' (or you could do b1=b1 + &quot;0&quot;)
b8=b8+$30'








writei2c 0, (b7,b8,&quot;:&quot;,b5,b6,&quot;:&quot;,b3,b4,255)

sertxd (&quot;THE TIME IS:&quot;,b7,b8,&quot;:&quot;,b5,b6,&quot;:&quot;,b3,b4,13,10)
goto init
Thanks for all your help.
Best regards to you all.

Carmel.
 
Top