Shop OBEX P1 Docs P2 Docs Learn Events
DS1307 interfacing problems — Parallax Forums

DS1307 interfacing problems

John A. ZoidbergJohn A. Zoidberg Posts: 514
edited 2013-04-03 06:40 in Propeller 1
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.
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

  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-10-10 07:38
    Check out Kye's DS1307 driver http://obex.parallax.com/objects/420/
  • John A. ZoidbergJohn A. Zoidberg Posts: 514
    edited 2010-10-10 08:51
    Unfortunately, it didn't work. I do not know whether the chip itself is receiving/transmitting the data from the pins at all.

    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...:confused:
  • JonnyMacJonnyMac Posts: 9,108
    edited 2010-10-10 08:55
    I've found DS1307 interfacing pretty straightforward. Attached is my demo code that may give you another perspective. Note that my I2C driver requires pull-ups on the SCL and SDA pins of the buss (I use the boot EEPROM pins).
  • John A. ZoidbergJohn A. Zoidberg Posts: 514
    edited 2010-10-10 10:44
    Well... I tried the code too. Didn't even work. I begin to suspect that there is no data travelling in/out on these pins.

    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.
  • JonnyMacJonnyMac Posts: 9,108
    edited 2010-10-10 12:11
    I suspect you have a hardware issue -- I've run that code (and derivatives) many times. And, yes, the DS1307 and boot EEPROM can share the same pins as they have a different slave address.
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-10-10 16:04
    I have a modified version of Kye's DS1307 object which lets you set the DS1307 in 12 or 24 hour mode.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2010-10-10 18:00
    You say you hooked up a DS1307 but you didn't say how. Ok, I will take a wild guesss. It may be that you left the battery off and simply connected VBAT to VCC. BAD BAD. Here's why from the datasheet:

    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?)
  • John A. ZoidbergJohn A. Zoidberg Posts: 514
    edited 2010-10-10 22:14
    You say you hooked up a DS1307 but you didn't say how. Ok, I will take a wild guesss. It may be that you left the battery off and simply connected VBAT to VCC. BAD BAD. Here's why from the datasheet:

    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.
  • Mike GreenMike Green Posts: 23,101
    edited 2010-10-10 22:31
    I2C is not very speed dependent other than you can't run it faster than the device can handle (about 400KHz). The Prop uses the RCFAST clock during booting to access the EEPROM and that can vary widely.

    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?
  • John A. ZoidbergJohn A. Zoidberg Posts: 514
    edited 2010-10-10 22:43
    Mike Green wrote: »
    I2C is not very speed dependent other than you can't run it faster than the device can handle (about 400KHz). The Prop uses the RCFAST clock during booting to access the EEPROM and that can vary widely.

    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.
  • Mike GreenMike Green Posts: 23,101
    edited 2010-10-10 23:04
    Make sure you have the current version of Basic_I2C_Driver. It should be 1.3.

    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.
  • John A. ZoidbergJohn A. Zoidberg Posts: 514
    edited 2010-10-10 23:35
    Mike Green wrote: »
    Make sure you have the current version of Basic_I2C_Driver. It should be 1.3.

    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. :)
  • Mike GreenMike Green Posts: 23,101
    edited 2010-10-11 06:26
    I don't know why version 1.3 wasn't in the OBEX. It is now.

    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.
  • RaymanRayman Posts: 14,665
    edited 2010-10-11 06:59
    I also had some DS1307 trouble recently... Turned out I had the backup battery voltage at 4 V and the DS1307 doesn't like that...

    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.
  • John A. ZoidbergJohn A. Zoidberg Posts: 514
    edited 2010-10-11 08:28
    Mike Green wrote: »
    I don't know why version 1.3 wasn't in the OBEX. It is now.

    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.
    Rayman wrote: »
    I also had some DS1307 trouble recently... Turned out I had the backup battery voltage at 4 V and the DS1307 doesn't like that...

    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?
  • JonnyMacJonnyMac Posts: 9,108
    edited 2010-10-11 09:52
    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:
    repeat
        repeat
          getclock(@clock)
        until (clock[RTC_SECS] <> last)
        last := clock[RTC_SECS]
    
        ' display code here
    

    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.
  • John A. ZoidbergJohn A. Zoidberg Posts: 514
    edited 2010-10-11 10:33
    JonnyMac wrote: »
    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:
    repeat
        repeat
          getclock(@clock)
        until (clock[RTC_SECS] <> last)
        last := clock[RTC_SECS]
    
        ' display code here
    

    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? :)
  • JonnyMacJonnyMac Posts: 9,108
    edited 2010-10-11 13:07
    I'm doing a page read of all clock registers so it's clean and faster than reading the clock registers one at a time. Yes, I read the group, and if the seconds register has changed then the code drops through to the display update. It may seem counter-intuitive, but I think this is the most efficient use of code.

    Another way to remove the apparent jitter is to use a fixed loop. Instead of using wait like this:
    repeat
      ' loop code
      waitcnt((clkfreq >> 2) + cnt)
    

    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:
    t := cnt
    repeat
      ' loop code
      waitcnt(t += (clkfreq >> 2))
    

    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.
  • John A. ZoidbergJohn A. Zoidberg Posts: 514
    edited 2010-10-14 18:40
    Hey there,

    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. :)
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2010-10-14 22:37
    Didn't I cover that before in an earlier post? Vbat must be less than VCC and VCC MUST BE +5V, not 3.3V. Check the datasheet but here is the relevant section:
    ----
    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.


    Hey there,

    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. :)
  • John A. ZoidbergJohn A. Zoidberg Posts: 514
    edited 2010-10-14 22:57
    Didn't I cover that before in an earlier post? Vbat must be less than VCC and VCC MUST BE +5V, not 3.3V. Check the datasheet but here is the relevant section:
    ----
    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.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2010-10-14 23:05
    Well it may have been a configuration problem then. You should always make sure that clock halt bit (CH) is cleared. My init routines will read this register and if it is set it is assumed to be a cold start so I write dummy default data into the registers. Of course this bit gets cleared whenever you write the seconds to the RTC anyway.

    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.
  • John A. ZoidbergJohn A. Zoidberg Posts: 514
    edited 2010-10-16 21:47
    Hello,

    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. :D
  • KPRKPR Posts: 189
    edited 2010-11-28 17:54
    If I want to use 5 volts what should my pull up resisters be??

    KPR
  • ShaliniShalini Posts: 59
    edited 2013-04-02 19:01
    I have a modified version of Kye's DS1307 object which lets you set the DS1307 in 12 or 24 hour mode.

    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...
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2013-04-02 20:07
    Shalini wrote: »
    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/
  • ShaliniShalini Posts: 59
    edited 2013-04-03 05: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...
  • ShaliniShalini Posts: 59
    edited 2013-04-03 05:34
    nevermind, i got it.
  • ShaliniShalini Posts: 59
    edited 2013-04-03 06:40

    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
Sign In or Register to comment.