Menu

No Read from DS1307 RTC

Help
2013-06-01
2013-09-30
  • Dimitris Katsaounis

    Help!!!
    I try to read (or write) from DS1307 RTC with software I2C but i got 0:0:0 (sametimes i got 45:85:85 !!!). The circuit is ok (double checket pull up resistors 4.7KOhm). What is wrong? I try to read without the fuctions BcdToDec (convert Bcd to decimal) same results. I try to read with Hardware I2C same results. I try to increace the I2C_BIT_DELAY , I2C_CLOCK_DELAY , I2C_END_DELAY in i2c.h same results :(
    My code

    ;Chip Settings
    #chip 16F88,4
    #config OSC=INTRC_IO, WDT=OFF

    ;Defines (Constants)
    #define LCD_IO 4
    #define LCD_RW PORTA.1
    #define LCD_RS PORTA.0
    #define LCD_Enable PORTA.2
    #define LCD_DB4 PORTB.3
    #define LCD_DB5 PORTB.5
    #define LCD_DB6 PORTB.6
    #define LCD_DB7 PORTB.7
    #define I2C_MODE Master
    #define I2C_DATA PORTB.1
    #define I2C_CLOCK PORTB.4

    ;Variables
    Dim sec As byte
    Dim min As byte
    Dim hour As byte
    Dim va as byte
    cls
    Main:
    I2CStart ; Send I2C start condition
    I2CSend 208, True ; The Address of DS1307 for Write
    I2CSend 0, True ; Set register pointer to zero
    I2CStart ; Repeated Start
    I2CSend 209, True ; The Address of DS1307 for Read
    I2CReceive sec , True ; Read the 00h register (sec)
    I2CReceive min , True ; Read the 01h register (min)
    I2CReceive hour , False ; Read the 02h register (hour) and transmit no act
    I2CStop ; Send I2C stop condition
    sec=BcdToDec(sec & 127)
    min=BcdToDec(min & 127)
    hour=BcdToDec(hour & 63)
    locate 0,0
    print hour
    print ":"
    print min
    Print ":"
    Print sec
    wait 500 ms

    goto Main

    Function DecToBcd(va) as Byte
    DecToBcd=(va/10)*16+va%10
    End Function

    Function BcdToDec(va) as byte
    BcdToDec=(va/16)*10+va%16
    End Function

     

    Last edit: Dimitris Katsaounis 2013-06-01
  • Chuck Hellebuyck

    I haven't used the DS1307 but looking at the data sheet it seems like you have to send a I2CStop before sending the repeated start.
    I would think it has to complete the address set before starting the next section of sending data.

    I really like your DECtoBCD and BCDtoDEC functions. Those should be put in the GCB library somewhere as new commands.

     
  • Dimitris Katsaounis

    Thanks Chuck for reply.
    I try to I2CStop before the repeated start but same results :(

     
  • kent_twt4

    kent_twt4 - 2013-06-02

    The DS1307 needs to kick off the oscillator, with the seconds register set to zero. All data sent to the registers need to be in BCD form. Here is an initialization routine from a long time ago. Non standard GCB syntax :-).

    ;**RTC INITIALIZE******
    ' Set initial DS1307 time / Date
    ampm = 96 '12 hour clock (64) + pm bit (32)
    'ampm = 64 '12 hour clock (64) + am bit (0)
    Secs = 0 'Set seconds to zero in order to get osc going
    Mins = 57
    Hrs = 10
    Day = 4 'Set day of week value
    Date = 1 'Day of month value
    Month = 5 'Month value
    Year = 8 ' Year value
    Ctrl = 0 '0x50 Set the SQW pin to 1Hz output

    BIN = Secs 'Make sure the Osc is enabled
    BINtoBCD BIN 'BIN_TO_BCD
    Secs=BCD

    BIN = Mins
    BINtoBCD BIN 'BIN_TO_BCD
    Mins = BCD

    BIN = Hrs
    BINtoBCD BIN
    Hrs = BCD
    Hrs = Hrs + ampm 'Need to change Hr = RTC_receive if doing 12 hr. clock

    BIN = Day
    BINtoBCD(BIN)
    Day=BCD

    BIN = Date
    BINtoBCD BIN
    Date = BCD

    BIN = Month
    BINtoBCD BIN
    Month=BCD

    BIN = Year
    BINtoBCD BIN
    Year=BCD

    BIN = Ctrl
    BINtoBCD BIN
    Ctrl=BCD

    strtaddr = 0
    write8bit (DS1307write,strtaddr,Secs)

    strtaddr = 1
    write8bit(DS1307write,strtaddr,Mins)

    strtaddr = 2
    write8bit(DS1307write,strtaddr,Hrs)

    strtaddr = 3
    write8bit(DS1307write,strtaddr,Day)

    strtaddr = 4
    write8bit(DS1307write,strtaddr,Date)

    strtaddr = 5
    write8bit(DS1307write,strtaddr,Month)

    strtaddr = 6
    write8bit(DS1307write,strtaddr,Year)

    strtaddr = 7
    write8bit(DS1307write,strtaddr,Ctrl)

     
  • Dimitris Katsaounis

    Finally worked!
    Thanks guys!!!
    The problem was in bit7 of 00h register.
    I changed in i2c.h library the constants:
    #define I2C_BIT_DELAY 20 us ;Default 2 us
    #define I2C_CLOCK_DELAY 10 us ;Default 1 us
    #define I2C_END_DELAY 10 us ; Default 1 us

    The new code is now:

    ;Chip Settings
    #chip 16F88,4
    #config OSC=INTRC_IO, WDT=OFF

    ;Defines (Constants)
    #define LCD_IO 4
    #define LCD_RW PORTA.1
    #define LCD_RS PORTA.0
    #define LCD_Enable PORTA.2
    #define LCD_DB4 PORTB.3
    #define LCD_DB5 PORTB.5
    #define LCD_DB6 PORTB.6
    #define LCD_DB7 PORTB.7
    #define I2C_MODE Master
    #define I2C_DATA PORTB.1
    #define I2C_CLOCK PORTB.4

    ;Variables
    Dim sec As byte
    Dim min As byte
    Dim hour As byte
    Dim va as byte
    dim DS_AddrWrite as Byte
    Dim DS_AddrRead as byte
    va=0
    cls
    DS_AddrWrite=208 ; According to manual 1101000+0
    DS_AddrRead=209 ; According to manual 1101000+1
    ' Set bit 7 of 00h register to 0
    I2CStart
    I2CSend DS_AddrWrite , True
    I2CSend 0, True
    I2CSend 0, True
    I2CStop

    Main:
    I2CStart ; Send I2C start condition
    I2CSend DS_AddrWrite, True ; The Address of DS1307 for Write
    I2CSend 0, True ; Set register pointer to zero
    I2CStart ; Repeated Start
    I2CSend DS_AddrRead, True ; The Address of DS1307 for Read
    I2CReceive sec , True ; Read the 00h register (sec)
    I2CReceive min , True ; Read the 01h register (min)
    I2CReceive hour , False ; Read the 02h register (hour) and transmit no act
    I2CStop ; Send I2C stop condition
    sec=BcdToDec(sec & 127)
    min=BcdToDec(min & 127)
    hour=BcdToDec(hour & 63)
    locate 0,0
    print hour
    print ":"
    print min
    Print ":"
    Print sec
    wait 500 ms
    locate 0,0
    print " "
    goto Main

    Function DecToBcd(va) as Byte
    DecToBcd=(va/10)*16+va%10
    End Function

    Function BcdToDec(va) as byte
    BcdToDec=(va/16)*10+va%16
    End Function

     
  • Keith

    Keith - 2013-06-17

    Hi, This is absolutely great, especially as I am working on a project which needs to incorporate an RTC.

    I have duplicated your code into my project, changed the data in the i2c.h file, it compiles okay but when I run it on my PIC Simulator it only displays 45:85:85

    Any ideas or suggestions ?
    Regards
    Keith

     
  • Keith

    Keith - 2013-06-18

    I have soldiered on since daybreak on this. I have double checked everything. I can see that I have a clock on RC3 and data on RC4 with the scope but still only 45:85:85 on the display.

    My grey area's are in the chip config and Port Dir.

    I would really appreciate if one of the forum Guru's could check my code over.

    my code is;

    ;Chip Settings
    #chip 16F887,20

    #config OSC=XT_IO, WDT=OFF

    ;Defines (Constants)
    #define LCD_IO 8
    #define LCD_DATA_PORT PORTB
    #define LCD_RS PORTD.5
    #define LCD_RW PORTD.6
    #define LCD_Enable PORTD.7

    #define I2C_MODE Master
    #define I2C_DATA PORTC.4 'I2C SD1/SDA
    #define I2C_CLOCK PORTC.3 'I2C SCK/SCL

    DIR PORTA b'11000000'
    ' All Port C Outputs except RA6 & RA7 Inputs

    DIR PORTB b'00000000'
    ' All Port B Outputs

    DIR PORTC b'11111111'
    ' All Inputs Port C

    DIR PORTD b'00001111'
    ' All Outputs Port A except RD0 to RD3 Inputs

    DIR PORTE b'0000'
    ' All Outputs Port E

    ;Variables
    Dim sec As byte
    Dim min As byte
    Dim hour As byte
    Dim va as byte
    dim DS_AddrWrite as Byte
    Dim DS_AddrRead as byte
    va=0
    cls
    DS_AddrWrite=208 ; According to manual 1101000+0
    DS_AddrRead=209 ; According to manual 1101000+1
    ' Set bit 7 of 00h register to 0
    I2CStart
    I2CSend DS_AddrWrite , True
    I2CSend 0, True
    I2CSend 0, True
    I2CStop

    'Main loop
    Main:
    I2CStart 'Send I2C start condition
    I2CSend DS_AddrWrite, True 'The Address of DS1307 for Write
    I2CSend 0, True 'Set register pointer to zero
    I2CStart 'Repeated Start
    I2CSend DS_AddrRead, True 'The Address of DS1307 for Read
    I2CReceive sec , True 'Read the 00h register (sec)
    I2CReceive min , True 'Read the 01h register (min)
    I2CReceive hour , False 'Read the 02h register (hour) and transmit no act
    I2CStop 'Send I2C stop condition
    sec = BcdToDec(sec & 127)
    min = BcdToDec(min & 127)
    hour = BcdToDec(hour & 63)
    locate 3,12
    print hour
    print ":"
    print min
    Print ":"
    Print sec
    wait 500 ms
    locate 3,12
    print " "
    goto Main

    Function DecToBcd(va) as Byte
    DecToBcd = (va/10)*16+va%10
    End Function

    Function BcdToDec(va) as byte
    BcdToDec = (va/16)*10+va%16
    End Function

     

    Last edit: Keith 2013-06-20
  • Keith

    Keith - 2013-06-18

    Does anyone have a quick fix as to when I post code the definition pound is stripped off and the text is is posted in huge charactors... (looks really messy!)

     
    • ofuzzy1

      ofuzzy1 - 2013-09-30

      put "4 ~'s" just before your code and just after to stop all sourceforge formatting.
      that is:

      ~ ~ ~ ~             <-- with NO spcaes
       code
      ~ ~ ~ ~             <-- with NO spcaes
      
       

      Last edit: ofuzzy1 2013-09-30
      • Anobium

        Anobium - 2013-09-30

        ....

         

        Last edit: Anobium 2013-09-30
  • Anobium

    Anobium - 2013-06-18

    This code worked for me.

    I believe, however, I may be incorrect, that you need to 'set' the clock prior to the read operation (the code above).

    Are you able to write 'set' the clock code?

     
  • Keith

    Keith - 2013-06-18

    Hi and thank you kindly for your reply. To be perfectly honest with you, I am batting way above my height with this one. With that in mind could you please elaborate a little when you write, ''set' the clock prior to the read' and, ''set' the clock code'

    Many thanks

    Keith

     
  • Jim giordano

    Jim giordano - 2013-06-18

    this is a test of lines starting with a #

    no leading spaces

    #one leading space
    #two leading spaces
    #three leading spaces

     
    • Keith

      Keith - 2013-06-20

      Greg replied on a previous post:

      Put a Space before the # (pound symbol) kills the ugly text...

      Thanks Greg....

       
  • Keith

    Keith - 2013-06-19

    Hi Dimitris, and thank you for your reply (as shown below)

    I think the portC especially the Portc.4 is input and output port (send the data tou DS1307 and Read data from it).Correct this and find out more here https://sourceforge.net/p/gcbasic/discussion/629990/thread/5b8b6ec1/

    I have had similar thoughts about the Data Port, and in times past while making vague attempts with MPLAB IDE I would have been looking for an istruction which would allow RC4.C to enter into Tri-State Mode od Bi-Di Mode.

    I have been over GCB like a nasty rash but I cannot find any such instruction which will make RC4 Tri-State or Bi-Directional

    I have tried TRISC.4 = 1 and TRISC.4 = 0 as I'm led to believe that any istruction which the GCB Compiler does not make sense of, it passes to the .asm, but that still gives me the dreaded, '45:85:85' which incidentally is what you got when you first identified the problems with the I2C.h file timing parameters.

     
  • Dimitris Katsaounis

    The 45:85:85 means that reads from the port 255:255:255
    Try
    Dir portc.3 out
    Dir portc.4 out

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.