DS1307,help on explanation of the code
I experimented with the I2C,Im still a newbie about this particular area and I messed with the code from this article in this link
www.parallax.com/dl/docs/books/sw/Web-SW-v2.1.pdf
I was able to manage already to write some default values to the DS1307 but the problem is I cant display it in my own code. I think If I understood this part here I could find the solution to my code,
refer to the link I placed above and turn to page 198,you can see this variables below
==========================================================
secs VAR Byte ' DS1307 time registers
mins VAR Byte
hrs VAR Byte
day VAR Byte ' weekday
date VAR Byte ' day in month, 1 - 31
month VAR Byte
year VAR Byte
control VAR Byte
===========================================================
I want to know how was it possible,that this block:
===========================================================
Get_Clock:
GOSUB I2C_Start ' send Start
i2cWork = slvAddr & %11111110 ' send slave ID (write)
GOSUB I2C_TX_Byte
IF (i2cAck = Nak) THEN Get_Clock ' wait until not busy
i2cWork = 0 ' point at secs register
GOSUB I2C_TX_Byte
GOSUB I2C_Start
i2cWork = slvAddr | %00000001 ' send slave ID (read)
GOSUB I2C_TX_Byte
FOR idx = 0 TO 6 ' read secs to year
GOSUB I2C_RX_Byte
secs(idx) = i2cWork
NEXT
GOSUB I2C_RX_Byte_Nak ' read control
control = i2cWork
GOSUB I2C_Stop
RETURN
===========================================================
was able to assign values to the variables I mentioned above?
I am pretty sure it is the secs(idx) in the FOR LOOP that is assigning values to it.
I want to know in detail how was it able to access the ram and was able to assigned to the variables.
THANKS
www.parallax.com/dl/docs/books/sw/Web-SW-v2.1.pdf
I was able to manage already to write some default values to the DS1307 but the problem is I cant display it in my own code. I think If I understood this part here I could find the solution to my code,
refer to the link I placed above and turn to page 198,you can see this variables below
==========================================================
secs VAR Byte ' DS1307 time registers
mins VAR Byte
hrs VAR Byte
day VAR Byte ' weekday
date VAR Byte ' day in month, 1 - 31
month VAR Byte
year VAR Byte
control VAR Byte
===========================================================
I want to know how was it possible,that this block:
===========================================================
Get_Clock:
GOSUB I2C_Start ' send Start
i2cWork = slvAddr & %11111110 ' send slave ID (write)
GOSUB I2C_TX_Byte
IF (i2cAck = Nak) THEN Get_Clock ' wait until not busy
i2cWork = 0 ' point at secs register
GOSUB I2C_TX_Byte
GOSUB I2C_Start
i2cWork = slvAddr | %00000001 ' send slave ID (read)
GOSUB I2C_TX_Byte
FOR idx = 0 TO 6 ' read secs to year
GOSUB I2C_RX_Byte
secs(idx) = i2cWork
NEXT
GOSUB I2C_RX_Byte_Nak ' read control
control = i2cWork
GOSUB I2C_Stop
RETURN
===========================================================
was able to assign values to the variables I mentioned above?
I am pretty sure it is the secs(idx) in the FOR LOOP that is assigning values to it.
I want to know in detail how was it able to access the ram and was able to assigned to the variables.
THANKS
Comments
For example:
someData VAR Byte
would let me access someData(0) -- the same as someData
someData(1) -- the next byte after someData
someData(2) -- etc
So in the DS1307 examples:
secs VAR Byte 'same as secs(0)
mins VAR Byte 'same as secs(1)
hrs VAR Byte 'same as secs(2)
day VAR Byte ' same as secs(3)
date VAR Byte ' same as secs(4)
month VAR Byte ' same as secs(5)
year VAR Byte 'same as secs(6)
control VAR Byte 'same as secs(7) -- so always be careful w/implied arrays -- it's easy to overwrite data that should be for something else
Since you can use expressions, vars, etc. for the index of an array, the I2C routines use this "trick" with implied arrays to read bytes into
secs(0)..secs(6) using
FOR idx = 0 TO 6
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
BIT6 = 1 = 12 hour mode
BIT5 = 0 = AM
BIT4 = 0 = tens hours
BIT3..BIT0 = unit hours
Yeah, that's right.
Can you post your full code? Maybe the register is not being written properly. Is the clock keeping correct time even if it's in 24 hour mode? Remember that BIT7 of register 0 must be set to 0 at least once to "enable" the oscillator (e.g. start the clock running).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
Default_HOUR CON $52
I think without initializing BIT7 to 0 of register 0 will not make the clock run,am I right?I already made this initialization I just cant figure out why I still get 24 hour mode in hour.
Next, and here I didn't quite have the time yet to look at the BS2 I2C routines, as I pretty much just use BSPs if I need I2C, but this doesn't seem quite right, so I made some changes:
I took out the rest of the set "hours" code before the I2C_STOP above, because I *think* that the setup of the subroutine Initialize_Clock_Defaults led you to skip some steps above. With *most* I2C devices, the register you are reading or writing from is "auto-incremented" if you don't stop. So the Initialize_Clock_Defaults routine takes advantage of this fact by writing a "write" bit to the device followed by the register number for SECONDS. The seconds register is conveniently numbered 0. Then the routine PRESUMES that after reads the byte from register 0, the next byte it asks for will come from register 1, and so on.
If you want to "skip around" to different registers, you have to specifiy each register in turn. It looks like this as an outline:
- start I2C, wait for control of I2C bus
- send device address with write bit = 1
- send the register address byte you want to read from
- read the byte of data
- (optionally) keep reading bytes IN ORDER
- stop I2C
Lastly, and here I offer my apologies again, because I didn't have the time to look over the I2C routines in detail till this evening. Is that your code? I looked at the code from page 179 in the StampWorks PDF, and your I2C routines are substantially different. I don't think you're handling the ACK NACK properly.
You might try using the code as is from the tuturials, swapping in the address of your DS1307 and cutting/pasting the start/write/send/stop code with your registers, e.g.:
It's not as efficient as reading/writing all the bytes in one shot, and you're wasting byte on the word address, but it shows the steps really clearly and might help you understand what's going on when you read from I2C registers.
Does this help?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
HIGHNIB = 10s
LOWNIB = 1s
So HEX $10 does not equal the decimal number 10
To get the DECIMAL number you'd need to do:
HIGHNIB * 10 + LOWNIB
HEX $11 = "11" but decimal number would be:
HIGHNIB * 10 + LOWNIB = 10 + 1 = 11
Remember that a nib can count to 16 -- so the number
13
if converted to hex would not be $13 but would be
$0D
If you want a concise tutorial, I'm not sure... check the Stamp manual, or maybe the explanation at Wikipedia: en.wikipedia.org/wiki/Binary-coded_decimal
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST