DS1307 interfacing problems
John A. Zoidberg
Posts: 514
Hello there,
I've just connected a DS1307+ on the Propeller, and I found some issues with it.
I tried to set the time first to 30 seconds and see whether it worked or not by putting the BCDs into the respective registers inside, and then get the data out.
In the end, all I got to see for the 3 in the 30 seconds in the Parallax Serial Terminal is a "?" (which means in binary 00111111, and not an ASCII "3").
Enclosed here is the code. I used the James Burrows' I2C drivers.
And also the circuit diagram - I've omitted the other +3.3V wirings and crystal inside the Propeller chip because it is already understood.
I've just connected a DS1307+ on the Propeller, and I found some issues with it.
I tried to set the time first to 30 seconds and see whether it worked or not by putting the BCDs into the respective registers inside, and then get the data out.
In the end, all I got to see for the 3 in the 30 seconds in the Parallax Serial Terminal is a "?" (which means in binary 00111111, and not an ASCII "3").
Enclosed here is the code. I used the James Burrows' I2C drivers.
OBJ i2c : "Basic_I2C_Driver" serialT : "Parallax Serial Terminal" CON _clkmode = xtal1 + pll2x _xinfreq = 10_000_000 i2cSCL = 22 ds1307_addr = %1101_0000 DAT sevenSegment byte %0000001, %1001111, %0010010, %0000110 ' zero, one, two, three byte %1001100, %0100100, %0100000, %0001111 ' four, five, six, seven byte %0000000, %0000100 ' eight, nine VAR byte sevenSegAddr byte digit_cnt byte digit0 byte digit1 long stack1[10] byte value1 long blink_cnt byte blink_status byte is_blink byte ds1307_seconds byte secs_ones byte secs_tens PUB Main sevenSegAddr := 0 digit_cnt := 0 blink_cnt := 0 digit0 := 2 digit1 := 5 value1 := 0 blink_status := 1 is_blink := 0 cognew(Multiplex, @stack1) serialT.Start(9600) {{repeat value1++ IF (value1 > 99) value1 := 0 digit0 := value1 / 10 digit1 := value1 // 10 waitcnt(6_000_000 + cnt) }} i2c.Initialize(i2cSCL) i2c.Start(i2cSCL) i2c.Write(i2cSCL, ds1307_addr | 0) i2c.Write(i2cSCL, 0) i2c.Write(i2cSCL, %0100_0000) i2c.Stop(i2cSCL) i2c.Start(i2cSCL) i2c.Write(i2cSCL, ds1307_addr | 0) i2c.Write(i2cSCL,0) i2c.Start(i2cSCL) i2c.Write(i2cSCL, ds1307_addr | 1) ds1307_seconds := i2c.Read(i2cSCL, i2c#ACK) i2c.Stop(i2cSCL) secs_ones := ds1307_seconds | %0000_1111 secs_tens := ( ds1307_seconds | %1111_0000 ) >> 4 repeat serialT.Char(secs_tens | %0011_0000) waitcnt(10_000_000 + cnt) PUB Multiplex dira[8..14]~~ dira[16..17]~~ repeat digit_cnt++ blink_cnt++ IF digit_cnt == 1 outa[17] := 0 outa[16] := blink_status outa[8..14] := sevenSegment[digit0] IF digit_cnt == 2 outa[17] := blink_status outa[16] := 0 outa[8..14] := sevenSegment[digit1] IF digit_cnt == 3 digit_cnt := 0 IF blink_cnt == 63 IF is_blink == 1 !blink_status blink_cnt := 0 waitcnt(120_000 + cnt)
And also the circuit diagram - I've omitted the other +3.3V wirings and crystal inside the Propeller chip because it is already understood.
Comments
How am I going to check whether the connections are working? I have 4.7K pull-ups to 3.3V, and even 10K, but doesn't even do much at all...
By the way is it okay to set the I2Cs as pins other than the reserved EEPROMs?
And what is the minimum clock-speed for these software-based I2C? I tested it at 20 and 80MHz unsuccessfully.
VBAT – Battery input for any standard 3V lithium cell or other energy source. Battery voltage must be
held between 2.0V and 3.5V for proper operation. The nominal write protect trip point voltage at which
access to the RTC and user RAM is denied is set by the internal circuitry as 1.25 x VBAT nominal.
So if you did a Q&D it will have backfired as the DS1307 then thinks that VCC has dropped too low and so it goes into standby and refuses to communicate.
EDIT: simply leaving the battery off is fine but don't connect VBAT to VCC. If you use a supercap for VBAT then charge it via a red LED which will drop the voltage sufficiently from +5V (you are using 5V aren't you?)
Apologies. I forgot to ground the VBAT previously. Right now I've connected it to a battery.
But the thing is, it's still not receiving/transmitting data. The pin-outs and the respective pull-ups are all correct. I begin to suspect that it might be the 10MHz crystal, or the speed, or the program code.
Also, I need to double-check the I2C routines first, by sending the data, receiving it back and then display it into the Parallax Serial Terminal.
The I2C drivers work for others. Start with an unmodified version of something known to work. Double and triple check your hookup. Make sure it's a circuit known to work. Does the Prop work with other things?
Hello,
I'm now trying an unmodified version of your I2C drivers at 80MHz (v1.1).
To test the functionality of the I2C and the DS1307, I'll first write some stuff ( like number one (1) ) into the empty NVRAM area, starting from 08H:
I2C.Initialize(SCL)
I2C.Start(SCL)
I2C.Write(SCL, ds1307_addr)
I2C.Write(SCL, 0)
I2C.Write(SCL, $08)
I2C.Write(SCL, 1)
and finally... I2C.Stop(SCL)
I don't know whether is it correct or not and I don't have a logic analyzer tool here.
Meanwhile, the prop works on blinking LEDs and even multiplexing two seven-segs in a typical test.
Also, this is my first time incorporating drivers into the Prop, so I bound to stumble on it.
Look at the DS1307 datasheet. It shows the order for writing is
<start>
ds1307_addr
8 ' register address
1 ' value to write
<stop>
To read, you have to write a new register address, then switch to read mode
<start>
ds1307_addr
8 ' register address
<start>
ds1307_addr + 1
... ' read a byte
<stop>
Note that you have to present an ACK value for each received byte, 1 if you expect another byte, 0 if there are no more bytes to read.
I see. But how am I going to present the ACK once the byte has been received?
Also, I can't seem to find the Basic_I2C_Driver version 1.3 in the OBEX. Any links for that library?
P.S: By the way I temporarily used the writelocation and readlocation to test the I2C - apparently it worked. I'll do some more further testing on it.
The Read method takes an Ack parameter. See the comments in Basic I2C Driver for details.
With Version 1.3, you should be able to use ReadByte and WriteByte to read and write to the DS1307 and supply a register address. There's a very simple example near the end of the initial comment block.
Anyway, if you're not connecting VBatt to ground, then make sure the battery voltage is between 2 and 3.5 Volts. Do not leave it floating or strange things could happen.
Some other notes:
Make sure it's powered by 5 Volts (won't work at 3.3 volts).
Make sure the I2C lines have 10k pullup resistors to 3.3 volts.
Mike Green - Thanks for the upload. The software works now. I had connected the DS1307 to a battery and it works wonders. However, the temporary system won't ever work on a weak 9V battery - it jitters badly. I'll use a AC adapter as a substitute later, with the heatsinked versions of the voltage regulators.
Rayman - Yes, me too previously. Thanks for the heads-up also.
Also - one more thing - in designing microcontroller-based digital clocks, how frequently does the system draws out the time, date and the stuff and display it on a screen? At first it was 1/2 seconds for the taking out the raw data, decoding it to BCD, but then it looks like this :
[attn: the display shows minutes and seconds]
10:21... (a second later) 10.22... (a second later) 10.23..10.24 (notice that the second incremented quickly) 10.25... (a second later) and so on. The short jitter is evident.
I cranked up the drawing of the data from 1/2 second to 1/4 second, and it seems to amolirate the problem, but not totally eliminate it. Could it be the delay for the extracting DS1307's data and the conversion from the raw results to BCD?
If you have any kind of delay (e.g. a waitcnt) in your display loop you will see what looks like jitter -- it's not, it's simply the clock not in sync with your hard delay. You can get rid of the delay and look for a change in the clock data. This is the top of my demo display loop:
As you can see, the program is sitting in a tight loop waiting for the seconds register to change. The display only gets updated when that change is detected, and the update takes less than 1ms.
Thanks for the code. However, is it only shown for the seconds? So the DS1307's data is sampled maximally without waiting, and then detect for the seconds to change?
Another way to remove the apparent jitter is to use a fixed loop. Instead of using wait like this:
You can synchronize it so the loop runs on the same interval -- the only caveat is that all your code has to be done in less than the number of tics you specify. To create a fixed loop delay you can do this:
The second version runs every 1/4 second while the first runs 1/4s plus the time required by the code in your loop. See the waitcnt section of the manual for details. By using a synchronized delay the relationship between your display updates and the internal clock changes remains (relatively) fixed.
An update - the I2C drivers are working good in the system. However, another issue comes up - when I connect the 3.3V coin battery (CR2032) at the Vbat pin, and start the system, the RTC stopped.
But when I ground the Vbat, all is okay, but it is not backup by the battery.
Any ideas on that problem? Thanks.
----
VBAT Battery input for any standard 3V lithium cell or other energy source. Battery voltage must be held between 2.0V and 3.5V for proper operation. The nominal write protect trip point voltage at which access to the RTC and user RAM is denied is set by the internal circuitry as 1.25 x VBAT nominal.
----
This is assuming of course assuming that VCC is +5V which it needs to be.
Yes I know - I connected the 3.3V coin battery at the Vbat which is supposed to be intended in the data sheet, and the Vcc is +5V.
The strange thing is, I had to pull out the battery, and then reinsert again when the system starts up so that it doesn't have a weird output. I'll double check the connections now.
Datasheet:
Please note that the initial power-on state of all registers is not defined. Therefore, it is important to enable the oscillator (CH bit = 0) during initial configuration.
I've just found out that I should have pulled out the PropPlug when I program the Propeller with the DS1307 connected.
Without pulling out that thing first, the DS1307 still retains the data... erratically because there is a small voltage to the supply pins of the DS1307 when the PropPlug is connected. That explains why when I connect the battery, the display and the clock stopped working.
Thanks for the help anyway. Note to self: Pull out the PropPlug or pull out the DS1307 Vcc during programming or to test the RTC.
KPR
Ur codes are really helpful, thank you so much!! I was wondering where can I find Extended FD Serial. spin program for Debug object?? because the LCD RTC Demo.spin program is associated with LCD, RTC, and Debug programs...
Here is the OBEX link http://obex.parallax.com/objects/31/
thanks, but this is again associated with another program called FullDuplexSerial...i searched in obex.parallax but i'm not sure which one to download...
Could you help me out on the code...I'm having some trouble fixing the error....I've explained it in the below link..please take a look at it and guide me. I'm new to spin language!
http://forums.parallax.com/showthread.php/147154-DS1307-Initialization-and-Demo