Menu

Ηandling ds1307

2013-06-05
2013-06-08
  • Dimitris Katsaounis

    The following are some routines to write and read from the DS1307 RTC.
    First must be changed in the library i2c.h
    # define I2C_BIT_DELAY 20 us
    # define I2C_CLOCK_DELAY 10 us
    # define I2C_END_DELAY 10 us
    This is because the DS1307 can not operate at timings below 4.7 us

    The code:

    ' Write Address According to manual 1101000+0= Decimal 208
    ' Read Address According to manual 1101000+1= Decimal 209

    'Clear Bit 7 of 00h register. Oscillator is enabled, clock start
    'On first application of power to the device the time and date registers
    'are typically reset to 01/01/00 01 00:00:00 (MM/DD/YY DOW HH:MM:SS).
    'The CH bit in the seconds register will be set to a 1
    Sub Enab_Osc
    I2CStart
    I2CSend 208 , True
    I2CSend 0 , True
    I2CStart
    I2CSend 209 , True
    I2CReceive Sec , False
    I2CStop
    Sec=Sec&127
    I2CStart
    I2CSend 208 , True
    I2CSend 0 , True
    I2CSend Sec , True
    I2CStop
    end sub

    'Set Bit 7 of 00h register. Oscillator is disabled, clock stop
    Sub Dis_Osc
    I2CStart
    I2CSend 208 , True
    I2CSend 0 , True
    I2CStart
    I2CSend 209 , True
    I2CReceive Sec , False
    I2CStop
    Sec=Sec|128
    I2CStart
    I2CSend 208 , True
    I2CSend 0 , True
    I2CSend Sec , True
    I2CStop
    End sub

    ' Resets the clock to 00:00:00 01 01/01/00
    Sub ResetClock
    I2CStart
    I2CSend 208, True
    I2CSend 0, True
    I2CSend 0, True
    I2CSend 0, True
    I2CSend 0, True
    I2CSend 1, True
    I2CSend 1, True
    I2CSend 1, True
    I2CSend 0, True
    I2CStop
    end sub

    'Self explained
    Sub SetClock (In Hour , In Min , In Sec , In DayOfWeak , In CDate , in CMonth , in CYear)
    DS1307WriteReg(0,DecToBcd(Sec))
    DS1307WriteReg(1,DecToBcd(Min))
    DS1307WriteReg(2,DecToBcd(Hour))
    DS1307WriteReg(3,DecToBcd(DayOfWeak))
    DS1307WriteReg(4,DecToBcd(CDate))
    DS1307WriteReg(5,DecToBcd(CMonth))
    DS1307WriteReg(6,DecToBcd(CYear))
    End sub

    'Self explained
    Sub SetTime (in Hour , in Min , in Sec)
    DS1307WriteReg(0,DecToBcd(Sec))
    DS1307WriteReg(1,DecToBcd(Min))
    DS1307WriteReg(2,DecToBcd(Hour))
    End Sub

    'Self explained
    Sub SetDate (In CDate , in CMonth , in CYear)
    DS1307WriteReg(4,DecToBcd(CDate))
    DS1307WriteReg(5,DecToBcd(CMonth))
    DS1307WriteReg(6,DecToBcd(CYear))
    End Sub

    'Self explained
    Sub ReadClock (out Hour , out Min , out Sec , out DayOfWeak , out CDate , out CMonth , out CYear)
    I2CStart
    I2CSend 208 , True
    I2CSend 0 , True
    I2CStop
    I2CStart
    I2CSend 209 , True
    I2CReceive Sec , True
    Sec=BcdToDec(Sec & 127)
    I2CReceive Min , True
    Min=BcdToDec(Min & 127)
    I2CReceive Hour , True
    if Hour.6 then
    Hour=BcdToDec(Hour &31)
    Else
    Hour=BcdToDec(Hour & 63)
    End if
    I2CReceive DayOfWeak , True
    DayOfWeak=BcdToDec(DayOfWeak & 7)
    I2CReceive CDate , True
    CDate=BcdToDec(CDate & 63)
    I2CReceive CMonth , True
    CMonth=BcdToDec(CMonth & 31)
    I2CReceive CYear , False
    CYear=BcdToDec(CYear)
    I2CStop
    End Sub

    'Self explained
    Sub ReadTime (Out Hour , Out Min , Out Sec)
    I2CStart
    I2CSend 208 , True
    I2CSend 0 , True
    I2CStart
    I2CSend 209 , True
    I2CReceive Sec , True
    Sec=BcdToDec(Sec & 127)
    I2CReceive Min , True
    Min=BcdToDec(Min & 127)
    I2CReceive Hour , False
    I2CStop
    if Hour.6 then
    Hour=BcdToDec(Hour & 31)
    Else
    Hour=BcdToDec(Hour & 63)
    End if
    End sub

    'Self explained
    Sub ReadDate ( out CDate , out CMonth , out CYear)
    I2CStart
    I2CSend 208 , True
    I2CSend 4 , True
    I2CStart
    I2CSend 209 , True
    I2CReceive CDate , True
    CDate=BcdToDec(CDate & 63)
    I2CReceive CMonth , True
    CMonth=BcdToDec(CMonth & 31)
    I2CReceive CYear , False
    CYear=BcdToDec(CYear)
    I2CStop
    end sub

    'Set Bit 6 of 02h register. The DS1307 run in 12-hour mode
    'The hours value must be re-entered whenever the 12/24-hour mode bit is changed.
    Sub Set12HourMode
    I2CStart
    I2CSend 208 , True
    I2CSend 2 , True
    I2CStart
    I2CSend 209 , True
    I2CReceive Hour , False
    I2CStop
    Hour.6=1
    I2CStart
    I2CSend 208 , True
    I2CSend 2 , True
    I2CSend Hour , True
    I2CStop
    End sub

    'Clear Bit 6 of 02h register. The DS1307 run in 24-hour mode
    'The hours value must be re-entered whenever the 12/24-hour mode bit is changed.
    Sub Set24HourMode
    I2CStart
    I2CSend 208 , True
    I2CSend 2 , True
    I2CStart
    I2CSend 209, True
    I2CReceive Hour , False
    I2CStop
    Hour.6=0
    I2CStart
    I2CSend 208 , True
    I2CSend 2 , True
    I2CSend Hour , True
    I2CStop
    End sub

    ' Enables The SQW/OUT pin of chip
    ' If RateSelect=1 then the outpout Frequency is 1Hz
    ' If RateSelect=4 then the outpout Frequency is 4.096KHz
    ' If RateSelect=8 then the outpout Frequency is 8.192KHz
    ' If RateSelect=32 then the outpout Frequency is 32.768KHz
    Sub SQWEnable (RateSelect)
    Select case RateSelect
    Case 1 : DS1307WriteReg(7,16)
    Case 4 : DS1307WriteReg(7,17)
    Case 8 : DS1307WriteReg(7,18)
    Case 32: DS1307WriteReg(7,19)
    End Select
    End sub

    'Disable the SQW/OUT pin of chip (pin=off)
    Sub SQDisable
    DS1307WriteReg(7,0)
    End Sub

    'The contents of the time and calendar registers are in the BCD format.
    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

    Sub DS1307WriteReg (DS1307Reg, DS1307Value)
    I2CStart
    I2CSend 208 , True
    I2CSend DS1307Reg , True
    I2CSend DS1307Value , True
    I2CStop
    End Sub

    The code of the program that made tests are

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

     #include "DS1307.h"
    

    ;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
    #define DS1307_AddrWrite=208 ' According to manual 1101000+0
    #define DS1307_AddrRead=209 ' According to manual 1101000+1

    ;Variables
    Dim Sec As byte
    Dim Min As byte
    Dim Hour As byte
    Dim DayOfWeak as byte
    Dim CDate as byte
    Dim CMonth as byte
    Dim CYear as Byte
    Dim va as byte
    va=0
    cls
    InitI2C
    Main:
    Sec=0
    Min=0
    Hour=0
    CDate=0
    CMonth=0
    CYear=0
    Call ReadTime( Hour , Min , Sec)
    locate 0,0
    print Hour
    print ":"
    print Min
    Print ":"
    Print Sec
    Call ReadDate(CDate , CMonth , CYear)
    locate 1,0
    print CDate
    print "/"
    print CMonth
    print "/"
    print CYear
    wait 1 s
    locate 0,0
    print " "
    locate 1,0
    print " "
    InitI2C
    goto Main

    Sorry for my poor English

     
  • Anobium

    Anobium - 2013-06-07

    Great piece of work. Well done. I want to use the code. Thank you.

    A few questions.

    The timing changes to 12c.h makes sense.

    Your example code which commences as the line 'The code of the program that made tests are' calls the function ReadDate. But where does your example code call the routines you defined?

     
  • Dimitris Katsaounis

    According to datasheet (page 3) in AC ELECTRICAL CHARACTERISTICS the minimum time of SCL Clock is 4.7 us for LOW end 4 us for HiGH Period. In i2c.h this periods is 1 us. The Controler is 10 times faster than DS1307 end communication its not established.

    All these routines, i have put them into a library name DS1307.h and i use any routine i want from it.

     
  • Anobium

    Anobium - 2013-06-08

    Thank you. All make sense now and it compiles.

    :-)

     

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.