B4R Tutorial Setting and Reading date and time of a DS1302 (RTC) without a library

Johan Schoeman

Expert
Licensed User
I have one of the "MH-REAL-TIME CLOCK MODULES - 2" with a DS1302 chip. I thought it would be interesting to see if I could read the seconds, minutes, hours, year, month, day of month, and day of week from the module without making use of a library i.e hard coding the data extraction as a learning exercise.

Found the attached PDF document that explains the command / address details of how to read and write to the module. Have used a Nano and assigned pins 10, 11, and 12 to serve as the CLK, DAT, and RST lines respectively that are connected to the RTC module.

Attached is my B4R sample project - by no means whatsoever optimised at all. Just wanted to see if I could extract the data from the module. So, in the B4R project I control the RST (or CE) line and the CLK line via simple B4R code and clock in the commands / addresses via the DAT (I/O) line (pin 11 in output mode) and then switch pin 11 to input mode to read the response from the module while controlling the CLK line.

I guess writing / setting the module with new date / time info will be much a similar exercise - for whoever might be interested to do so.

Extract from the code:

B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 300
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
    
    Dim pclk, pdat, prst As Pin          'clock, I/O, CE
    Dim seconds10, seconds1, seconds As Byte = 0
    Dim minutes10, minutes1, minutes As Byte = 0
    Dim hours10, hours1, hours As Byte = 0
    Dim years10, years1, years As Byte = 0
    Dim months10, months1, months As Byte = 0
    Dim days10, days1, days As Byte = 0
    Dim weekdays10, weekdays1, weekdays As Byte = 0
    
    Dim data As Byte
    
    Dim t As Timer
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    
    t.Initialize("t_tick", 1000)
    data = 0
    
    pclk.Initialize(10, pclk.MODE_OUTPUT)
    pdat.Initialize(11, pdat.MODE_OUTPUT)
    prst.Initialize(12, prst.MODE_OUTPUT)
    
    t.Enabled = True
    
    pclk.DigitalWrite(False)
    pdat.DigitalWrite(False)
    prst.digitalwrite(False)
    
'    AddLooper("myLooper")
    
    
    
End Sub

Sub t_tick
    
    getSeconds
    getMinutes
    getHours
    getYear
    getMonth
    getDayOfMonth
    getDayOfWeek
    Log(" ")
    
    
End Sub

Sub getSeconds
    
    '81h = read Seconds (1000 0001) -> need to clock in 81h via the I/O line with the I/O line set to mode output (in this example I/O line = pin 11)
    
    prst.Digitalwrite(True)                      'pull CE high                  '
    DelayMicroseconds(4)
    
    pdat.DigitalWrite(True)            '1               LSB
    DelayMicroseconds(4)
    pclk.DigitalWrite(True)
    DelayMicroseconds(4)
    pclk.DigitalWrite(False)
    DelayMicroseconds(4)
    
    pdat.DigitalWrite(False)           '0
    DelayMicroseconds(4)
    pclk.DigitalWrite(True)
    DelayMicroseconds(4)
    pclk.DigitalWrite(False)
    DelayMicroseconds(4)
    
    pdat.DigitalWrite(False)            '0
    DelayMicroseconds(4)
    pclk.DigitalWrite(True)
    DelayMicroseconds(4)
    pclk.DigitalWrite(False)
    DelayMicroseconds(4)
    
    pdat.DigitalWrite(False)            '0
    DelayMicroseconds(4)
    pclk.DigitalWrite(True)
    DelayMicroseconds(4)
    pclk.DigitalWrite(False)
    DelayMicroseconds(4)
    
    
    
    
    pdat.DigitalWrite(False)           '0
    DelayMicroseconds(4)
    pclk.DigitalWrite(True)
    DelayMicroseconds(4)
    pclk.DigitalWrite(False)
    DelayMicroseconds(4)
    
    
    pdat.DigitalWrite(False)           '0
    DelayMicroseconds(4)
    pclk.DigitalWrite(True)
    DelayMicroseconds(4)
    pclk.DigitalWrite(False)
    DelayMicroseconds(4)
    
    pdat.DigitalWrite(False)           '0
    DelayMicroseconds(4)
    pclk.DigitalWrite(True)
    DelayMicroseconds(4)
    pclk.DigitalWrite(False)
    DelayMicroseconds(4)
    
    pdat.DigitalWrite(True)            '1         MSB
    DelayMicroseconds(4)
    pclk.DigitalWrite(True)
    DelayMicroseconds(4)
    pclk.DigitalWrite(False)
    DelayMicroseconds(4)
    
    data = 0
    
    pdat.Initialize(11, pdat.MODE_INPUT)                  'set the I/O line to mode input to read the response from the RTC (DS1302) module
    If pdat.DigitalRead = True Then data = Bit.Or(data, 1)
    
    pclk.DigitalWrite(True)
    DelayMicroseconds(4)
    pclk.DigitalWrite(False)
    DelayMicroseconds(4)
    If pdat.DigitalRead = True Then data = Bit.Or(data, 2)
    DelayMicroseconds(4)
    
    pclk.DigitalWrite(True)
    DelayMicroseconds(4)
    pclk.DigitalWrite(False)
    DelayMicroseconds(4)
    If pdat.DigitalRead = True Then data = Bit.Or(data, 4)
    DelayMicroseconds(4)
    
    pclk.DigitalWrite(True)
    DelayMicroseconds(4)
    pclk.DigitalWrite(False)
    DelayMicroseconds(4)
    If pdat.DigitalRead = True Then data = Bit.Or(data, 8)
    DelayMicroseconds(4)
    
    pclk.DigitalWrite(True)
    DelayMicroseconds(4)
    pclk.DigitalWrite(False)
    DelayMicroseconds(4)
    If pdat.DigitalRead = True Then data = Bit.Or(data, 16)
    DelayMicroseconds(4)
    
    pclk.DigitalWrite(True)
    DelayMicroseconds(4)
    pclk.DigitalWrite(False)
    DelayMicroseconds(4)
    If pdat.DigitalRead = True Then data = Bit.Or(data, 32)
    DelayMicroseconds(4)
    
    pclk.DigitalWrite(True)
    DelayMicroseconds(4)
    pclk.DigitalWrite(False)
    DelayMicroseconds(4)
    If pdat.DigitalRead = True Then data = Bit.Or(data, 64)
    DelayMicroseconds(4)
    
    pclk.DigitalWrite(True)
    DelayMicroseconds(4)
    pclk.DigitalWrite(False)
    DelayMicroseconds(4)
    If pdat.DigitalRead = True Then data = Bit.Or(data, 128)
    DelayMicroseconds(4)
    
    prst.DigitalWrite(False)                 'pull CE low
    
    seconds10 = 0
    seconds1 = 0
    seconds1 = Bit.And(data, 0x0f)
    seconds10 = Bit.And(data, 0xf0)
    seconds10 = Bit.ShiftRight(seconds10,4)
    seconds = (seconds10 * 10) + seconds1
    Log("SECONDS = ", seconds)

End Sub
20191226_090908.jpg



log.png
 

Attachments

Johan Schoeman

Expert
Licensed User
Much reduced code to read seconds, minutes, hours, year, month, day of month, day No of the week without using a library - project attached


B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 300
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
    
    Dim pclk, pdat, prst As Pin          'clock, I/O, CE
    Dim data As Byte
    
    Dim t As Timer
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    
    t.Initialize("t_tick", 1000)             'set the timer to tick every 1000ms (1 sec)
    data = 0                                 'byte to hold data returned
    
    pclk.Initialize(10, pclk.MODE_OUTPUT)    'Use pin 10 as the CLK pin and make it an Output pin
    pdat.Initialize(11, pdat.MODE_OUTPUT)    'Use pin 11 as the DAT (or I/O) pin and make it an Output pin for now (going to later switch mode to Input to read from the RTC module)
    prst.Initialize(12, prst.MODE_OUTPUT)    'Use pin 12 as the RST (or CE) pin and make it an Output pin
    
    t.Enabled = True
    
    pclk.DigitalWrite(False)
    pdat.DigitalWrite(False)
    prst.digitalwrite(False)
    
End Sub

Sub t_tick
    
    Dim retVal As Byte = 0
    
    retVal = getdata(0x81)      'get the seconds - clock in 81h from LSB to MSB (1000 0001)
    Log("SECONDS = ", retVal)
    
    retVal = getdata(0x83)      'get the minutes - clock in 83h from LSB to MSB (1000 0011)
    Log("MINUTES = ", retVal)
    
    retVal = getdata(0x85)      'get the hours - clock in 85h from LSB to MSB (1000 0101)
    Log("HOURS = ", retVal)
    
    retVal = getdata(0x8D)      'get the year - clock in 8Dh from LSB to MSB (1000 1101)
    Log("YEAR = ", retVal)
    
    retVal = getdata(0x89)      'get the month - clock in 89h from LSB to MSB (1000 1001)
    Log("MONTH = ", retVal)
    
    retVal = getdata(0x87)      'get the day of the month - clock in 87h from LSB to MSB (1000 0111)
    Log("DAY OF MONTH = ", retVal)
    
    retVal = getdata(0x8B)      'get the day number of the week - clock in 8Bh from LSB to MSB (1000 1011)
    Log("DAY NO OF WEEK = ", retVal)

    Log(" ")

End Sub

Sub getdata (command As Byte) As Byte

    prst.Digitalwrite(True)                      'pull CE line high                  '
    DelayMicroseconds(4)
    
    Dim mask As Byte = 1                         'set the mask to AND the command with
    For i = 0 To 7                               'cycle through the 8 bits of the command
        If Bit.And(command, mask) = 1 Then
            pdat.DigitalWrite(True)              'take the DAT line high
        Else
            pdat.DigitalWrite(False)             'take the DAT line low
        End If
        DelayMicroseconds(4)
        pclk.DigitalWrite(True)                  'take the CLK line high
        DelayMicroseconds(4)
        pclk.DigitalWrite(False)                 'take the CLK line low
        DelayMicroseconds(4)
        command = Bit.ShiftRight(command,1)      'shift the command bits 1 bit to the right for the next AND instruction
    Next
    
    data = 0
    
    pdat.Initialize(11, pdat.MODE_INPUT)         'set the I/O line to mode input to read the response from the RTC (DS1302) module

    Dim mask As Byte = 1

    For i = 0 To 7                                                 'cycle through the response from the RTC module
        If pdat.DigitalRead = True Then data = Bit.Or(data, mask)  'check if the DAT pin (response) is HIGH/LOW and set byte "data" accordingly
        DelayMicroseconds(4)
        pclk.DigitalWrite(True)                                    'take the CLK pin high
        DelayMicroseconds(4)
        pclk.DigitalWrite(False)                                   'take the CLK pin LOW
        DelayMicroseconds(4)
        mask = mask * 2                                            'double "mask" to check the next bit read from the RTC module
    Next
    
    prst.DigitalWrite(False)                     'pull CE line low
    
    Dim val10, val1, val As Byte = 0
    
    val10 = 0
    val1 = 0
    val1 = Bit.And(data, 0x0f)                   'get the ONE's value of the lower 4 bits in data
    val10 = Bit.And(data, 0xf0)                  'get the TEN's value of the lower 4 bits in data
    val10 = Bit.ShiftRight(val10,4)              'shift the TENS nibble 4 bits to the right
    val = (val10 * 10) + val1                    'the final value to be returned
    Return val                                   'return the calculated value

End Sub
 

Attachments

Johan Schoeman

Expert
Licensed User
I am really chuffed with the attached project. Managed to do a B4R project that can write (to) and read (from) the date/time of a DS1302 (MH-REAL-TIME CLOCK MODULES - 2) by making use of the B4R core library only. All commands to set/read the date and time are hard coded as per my understanding of the DS1302 spec sheet (see PDF in post #1 above). Have a main module and a code module - the latter does all the hard lifting.

It is sometimes more educational to do it this way rather than using a library - it makes the "grey matter between the ears" tick over.... ;)

Main module code:
B4X:
'DS1320    -    Arduino Nano
'VCC    ->    3.3V
'GND    ->    GND
'CLK    ->    Pin 10
'DAT    ->    Pin 11
'RST    ->    Pin 12

#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 300
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
 
    Dim p4, p5 As Pin
 
    Dim t As Timer
    Dim whatDay() As String = Array As String("Sunday", "Monday", " Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
    Dim whatMonth() As String = Array As String("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December")
 
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
 
    t.Initialize("t_tick", 1000)             'set the timer to tick every 1000ms (1 sec)
 
    p4.Initialize(4, p4.MODE_OUTPUT)         'only using this to light up a LED connected to pin 4 every alternate second - not needed!
    p5.Initialize(5, p5.MODE_OUTPUT)         'only using this to light up a LED connected to pin 5 every alternate second - not needed!
 
    p4.DigitalWrite(False)                   'only using this to light up a LED connected to pin 4 every alternate second - not needed!
    p5.DigitalWrite(False)                   'only using this to light up a LED connected to pin 5 every alternate second - not needed!
 
    timeAndDateDS1302.Initialize(10, 11, 12)        'initialize the code module with the Arduino pins used for CLK, DAT, and RST
 
    'You can use any of the below commented methods to set the hour, minute, month, day of week, day of month, and year of the DS1302 ONLY - not the seconds. See method timeAndDateDS1302.setRTCTime(....) to set the seconds too
    Log(" ")
    timeAndDateDS1302.setHours(15)                  'set the hour only
    timeAndDateDS1302.setMinutes(2)                 'set the minute only
    timeAndDateDS1302.setMonth(1)                   'set the month only (1 = January, 12 = December) - see array whatDay() above
    timeAndDateDS1302.setDayOfWeek(7)               'set the day of the week only (1 = Sunday, 2 = Monday, ......, 7 = Saturday) - see array whatMonth() above
    timeAndDateDS1302.setDayOfMonth(4)              'set the day of the month only (1.....31 -> make sure it ties up i.e dont for eg set February 31!)
    timeAndDateDS1302.setYear(20)                   'set the year only -> 20 = the year 2020 (the DS1302 allows for years from 2000 to 2099)
    logData
    Log("***********************************************")
    Log(" ")
 
    'This method can set the seconds too - if you set the seconds then the other date/time registers need to be set within 60 seconds or
    'else the seconds setting and all subsequent date/time settings will not be executed (i.e time/date will stay as what it was prior to the attempt to set it)
    timeAndDateDS1302.setRTCTime(20, 1, 4, 7, 17, 35, 0)    'set the year, month, day of month, day of week, hour, minute, AND second
 
    t.Enabled = True
 
End Sub

Sub t_tick
 
    logData

End Sub

Sub logData
 
    Dim retVal As Byte = 0
 
    retVal = timeAndDateDS1302.getSeconds
    Log("SECONDS = ", retVal)
    If retVal Mod 2 = 1 Then
        p4.DigitalWrite(True)
        p5.DigitalWrite(False)
    Else
        p4.DigitalWrite(False)
        p5.DigitalWrite(True)
    End If
 
    retVal = timeAndDateDS1302.getMinutes
    Log("MINUTES = ", retVal)
 
    retVal = timeAndDateDS1302.getHours
    Log("HOURS = ", retVal)
 
    retVal = timeAndDateDS1302.getYear
    Log("YEAR = 20", retVal)
 
    retVal = timeAndDateDS1302.getMonth
    Log("MONTH = ", whatMonth(retVal - 1))
 
    retVal = timeAndDateDS1302.getDayOfMonth
    Log("DAY OF MONTH = ", retVal)
 
    retVal = timeAndDateDS1302.getDayOfWeek
    Log("DAY NO OF WEEK = ", retVal)
 
    Log("DAY NAME = ", whatDay(retVal - 1))

    Log(" ")
 
End Sub
Code module code (timeAndDateDS1302):
B4X:
Private Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
 
    Private pclk, pdat, prst As Pin          'clock, I/O, CE
    Dim data As Byte = 0
 
End Sub

'Initialize the timer with the required pins
'clk = pin number of arduino that the DS1302 CLK pin in connected to (serial Clock)
'dat = pin number of arduino that the DS1302 DAT pin in connected to (I/O or Data)
'rst = pin number of arduino that the DS1302 RST pin in connected to (Reset or Chip Enable)
'Note - The pins on the DS1302 might be labelled as CE or RST, I/O or DAT(data line), and SCLK or CLK (serial clock).
'CE = RST
'I/O = DAT
'SCLK = CLK
Public Sub Initialize (clk As Byte, dat As Byte, rst As Byte)
 
    pclk.Initialize(clk, pclk.MODE_OUTPUT)
    pdat.Initialize(dat, pdat.MODE_OUTPUT)
    prst.Initialize(rst, prst.MODE_OUTPUT)
 
    pclk.DigitalWrite(False)
    pdat.DigitalWrite(False)
    prst.digitalwrite(False)
 
End Sub

'Set the Minute of the DS1302
'The method will automatically clock in 0x82 (BCD) as a command to set the Minutes
Public Sub setMinutes (minutes As Byte)

    Dim command As Byte = 0x82                   'command to set the minutes = 0x82h (BCD)
    sendCommand(command)
    setValue(minutes)
 
End Sub

'Set the Hour of the DS1302
'The method will automatically clock in 0x84 (BCD) as a command to set the Hours
Public Sub setHours(hours As Byte)
 
    Dim command As Byte = 0x84                   'command to set the Hours = 0x84h (BCD)
    sendCommand(command)
    setValue(hours)
 
End Sub

'Set the Month of the DS1302
'The method will automatically clock in 0x88 (BCD) as a command to set the Month
'January = 1, February = 2, ........, December = 12
Public Sub setMonth(month As Byte)
 
    Dim command As Byte = 0x88                   'command to set the Month = 0x88h (BCD)
    sendCommand(command)
    setValue(month)
 
End Sub

'Set the DayOfWeek of the DS1302
'The method will automatically clock in 0x8A (BCD) as a command to set the Day Of Week
'Sunday = 1, Monday = 2, ........, Saturday = 7
Public Sub setDayOfWeek(dow As Byte)
 
    Dim command As Byte = 0x8A                   'command to set the Month = 0x8Ah (BCD)
    sendCommand(command)
    setValue(dow)
 
End Sub

'Set the DayOfMonth of the DS1302
'The method will automatically clock in 0x86 (BCD) as a command to set the Day Of Month
'Day Of Month = 1...31
Public Sub setDayOfMonth(dom As Byte)
 
    Dim command As Byte = 0x86                   'command to set the Day Of Month = 0x86h (BCD)
    sendCommand(command)
    setValue(dom)
 
End Sub

'Set the Year of the DS1302
'The method will automatically clock in 0x8C (BCD) as a command to set the Year
'Year = 2000...2099
'The DS1302 only allows for years from 2000 to 2099 so no need to send the century - only send the Year of the century.
'eg: setTimeAndDate1302.setYear(20)
Public Sub setYear(year As Byte)
 
    Dim command As Byte = 0x8C                   'command to set the Year = 0x8Ch (BCD)
    sendCommand(command)
    setValue(year)
 
End Sub

'Set the Seconds of the DS1302
'The method will automatically clock in 0x80 (BCD) as a command to set the Seconds
'Seconds = 0...59
Private Sub setSeconds(seconds As Byte)
 
    Dim command As Byte = 0x80                   'command to set the Year = 0x80h (BCD)
    sendCommand(command)
    setValue(seconds)
 
End Sub

'set the RTC date and time in one GO
'Year = 0 - 99 (which represents 2000 to 2099 - the DS1302 only allows for these years)
'month = 1 - 12 (1 = January,......,12 = December)
'dayOfMonth = 0 - 31 (take care of what you do if the month is for eg February and it is/is not a leap year)
'dayOfWeek = 1 - 7 (Sunday = 1, Monday = 2, ......, Saturday = 7)
'hour = 0 - 23
'minute = 0 - 59
Public Sub setRTCTime(year As Byte, month As Byte, dayOfMonth As Byte, dayOfWeek As Byte, hour As Byte, minute As Byte, second As Byte)
 
    setSeconds(second)
    setMinutes(minute)
    setHours(hour)
    setDayOfMonth(dayOfMonth)
    setMonth(month)
    setDayOfWeek(dayOfWeek)
    setYear(year)
 
End Sub

'Common Private Sub to send the necessary command to the DS1302 before setting the applicable RTC register
Private Sub sendCommand (command As Byte)
 
    prst.Digitalwrite(True)                      'pull CE line high                  '
    DelayMicroseconds(4)
 
    Dim mask As Byte = 1                         'set the mask to AND the command with
    For i = 0 To 7                               'cycle through the 8 bits of the command
        If Bit.And(command, mask) = 1 Then
            pdat.DigitalWrite(True)              'take the DAT line high
        Else
            pdat.DigitalWrite(False)             'take the DAT line low
        End If
        DelayMicroseconds(2)
        pclk.DigitalWrite(True)                  'take the CLK line high
        DelayMicroseconds(2)
        pclk.DigitalWrite(False)                 'take the CLK line low
        DelayMicroseconds(2)
        command = Bit.ShiftRight(command,1)      'shift the command bits 1 bit to the right for the next AND instruction
    Next
 
End Sub

'Common Private Sub to send the necessary data to the DS1302 to set the applicable RTC register
private Sub setValue(value As Byte)
 
    Dim highnibble As Byte = value/10
    highnibble = Bit.ShiftLeft(highnibble,4)
    Dim lownibble As Byte = value Mod 10
    value = Bit.Or(highnibble,lownibble)
 
    For i = 0 To 7
        If Bit.And(value, 1) = 1 Then
            pdat.DigitalWrite(True)              'take the DAT line high
        Else
            pdat.DigitalWrite(False)             'take the DAT line low
        End If
        DelayMicroseconds(2)
        pclk.DigitalWrite(True)                  'take the CLK line high
        DelayMicroseconds(2)
        pclk.DigitalWrite(False)                 'take the CLK line low
        DelayMicroseconds(2)
        value = Bit.ShiftRight(value,1)          'shift the command bits 1 bit to the right for the next AND instruction
    Next
    prst.DigitalWrite(False)                     'pull CE line low
 
End Sub

'Common Private Sub to get Time/Date data from the DS1302
Private Sub getdata (command As Byte) As Byte

    prst.Digitalwrite(True)                      'pull CE line high                  '
    DelayMicroseconds(4)
 
    Dim mask As Byte = 1                         'set the mask to AND the command with
    For i = 0 To 7                               'cycle through the 8 bits of the command
        If Bit.And(command, mask) = 1 Then
            pdat.DigitalWrite(True)              'take the DAT line high
        Else
            pdat.DigitalWrite(False)             'take the DAT line low
        End If
        DelayMicroseconds(2)
        pclk.DigitalWrite(True)                  'take the CLK line high
        DelayMicroseconds(2)
        pclk.DigitalWrite(False)                 'take the CLK line low
        DelayMicroseconds(2)
        command = Bit.ShiftRight(command,1)      'shift the command bits 1 bit to the right for the next AND instruction
    Next
 
    data = 0
 
    pdat.Initialize(11, pdat.MODE_INPUT)         'set the I/O line to mode input to read the response from the RTC (DS1302) module

    Dim mask As Byte = 1

    For i = 0 To 7                                                 'cycle through the response from the RTC module
        If pdat.DigitalRead = True Then data = Bit.Or(data, mask)  'check if the DAT pin (response) is HIGH/LOW and set byte "data" accordingly
        DelayMicroseconds(2)
        pclk.DigitalWrite(True)                                    'take the CLK pin high
        DelayMicroseconds(2)
        pclk.DigitalWrite(False)                                   'take the CLK pin LOW
        DelayMicroseconds(2)
        mask = mask * 2                                            'double "mask" to check the next bit read from the RTC module
    Next
 
    prst.DigitalWrite(False)                     'pull CE line low
 
    Dim val10, val1, val As Byte = 0
    val10 = 0
    val1 = 0
    val1 = Bit.And(data, 0x0f)                   'get the ONE's value of the lower 4 bits in data
    val10 = Bit.And(data, 0xf0)                  'get the TEN's value of the lower 4 bits in data
    val10 = Bit.ShiftRight(val10,4)              'shift the TENS nibble 4 bits to the right
    val = (val10 * 10) + val1                    'the final value to be returned
    Return val                                   'return the calculated value

End Sub

'get the seconds - the metod will automatically clock in 81h from LSB to MSB (1000 0001) as a command to get the seconds (0...59)
Public Sub getSeconds() As Byte
    Return getdata(0x81)      'get the seconds - clock in 81h from LSB to MSB (1000 0001)
End Sub

'get the minutes - the metod will automatically clock in 83h from LSB to MSB (1000 0011) as a command to get the minutes (0...59)
Public Sub getMinutes() As Byte
    Return getdata(0x83)      'get the minutes - clock in 83h from LSB to MSB (1000 0011)
End Sub

'get the hours - the metod will automatically clock in 85h from LSB to MSB (1000 0101) as a command to get the hours (0...23)
Public Sub getHours() As Byte
    Return getdata(0x85)      'get the hours - clock in 85h from LSB to MSB (1000 0101)
End Sub

'get the year - the metod will automatically clock in 8Dh from LSB to MSB (1000 1101) as a command to get the year (0...99)
Public Sub getYear() As Byte
    Return getdata(0x8D)      'get the year - clock in 8Dh from LSB to MSB (1000 1101)
End Sub

'get the month - the metod will automatically clock in 89h from LSB to MSB (1000 1001) as a command to get the month (1...12)
Public Sub getMonth() As Byte
    Return getdata(0x89)      'get the month - clock in 89h from LSB to MSB (1000 1001)
End Sub

'get the day of the month - the metod will automatically clock in 87h from LSB to MSB (1000 0111) as a command to get the day of month (0...31)
Public Sub getDayOfMonth() As Byte
    Return getdata(0x87)      'get the day of the month - clock in 87h from LSB to MSB (1000 0111)
End Sub

'get the day number of the week - the metod will automatically clock in 8Bh from LSB to MSB (1000 1011) as a command to get the day of week (1...7)
Public Sub getDayOfWeek() As Byte
    Return getdata(0x8B)      'get the day number of the week - clock in 8Bh from LSB to MSB (1000 1011)
End Sub
Sample project attached.


1578153818661.png
 

Attachments

Last edited:

tigrot

Well-Known Member
Licensed User
Well done. That's what I did in most of my Assembly pjts for one wire devices. And since it's well organised it's reausable!
 

Johan Schoeman

Expert
Licensed User
Just for fun and as a learning exercise by making use of the B4A core library only.....

It can now set the time to 12HR and 24HR format (including AM/PM)
It can write/store a byte value in any of the 31 available RAM locations
It can read the byte value stored in any of the 31 available RAM locations

Main module Code:
B4X:
'DS1320    -    Arduino Nano
'VCC    ->    3.3V
'GND    ->    GND
'CLK    ->    Pin 10 - see timeAndDateDS1302.Initialize(7, 8, 9) further down in the code below (you can use any digital pin as long as what you define it correctly)
'DAT    ->    Pin 11 - see timeAndDateDS1302.Initialize(7, 8, 9) further down in the code below (you can use any digital pin as long as what you define it correctly)
'RST    ->    Pin 12 - see timeAndDateDS1302.Initialize(7, 8, 9) further down in the code below (you can use any digital pin as long as what you define it correctly)

#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 300
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial

    Dim p4, p5 As Pin

    Dim t As Timer
    Dim whatDay() As String = Array As String("Sunday", "Monday", " Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
    Dim whatMonth() As String = Array As String("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December")

End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")

    t.Initialize("t_tick", 1000)             'set the timer to tick every 1000ms (1 sec)

    p4.Initialize(4, p4.MODE_OUTPUT)         'only using this to light up a LED connected to pin 4 every alternate second - not needed!
    p5.Initialize(5, p5.MODE_OUTPUT)         'only using this to light up a LED connected to pin 5 every alternate second - not needed!

    p4.DigitalWrite(False)                   'only using this to light up a LED connected to pin 4 every alternate second - not needed!
    p5.DigitalWrite(False)                   'only using this to light up a LED connected to pin 5 every alternate second - not needed!

'   timeAndDateDS1302.Initialize(10, 11, 12)        'initialize the code module with the Arduino pins used for CLK, DAT, and RST
    timeAndDateDS1302.Initialize(7, 8, 9)

    'You can use any of the below commented methods to set the hour, minute, month, day of week, day of month, and year of the DS1302 ONLY - not the seconds. See method timeAndDateDS1302.setRTCTime(....) to set the seconds too
    Log(" ")
'    timeAndDateDS1302.setHours12(8, True)
'    timeAndDateDS1302.setHours24(23)                      'set the hour only
'    timeAndDateDS1302.setMinutes(39)                      'set the minute only
    timeAndDateDS1302.setMonth(1)                         'set the month only (1 = January, 12 = December) - see array whatDay() above
    timeAndDateDS1302.setDayOfWeek(1)                     'set the day of the week only (1 = Sunday, 2 = Monday, ......, 7 = Saturday) - see array whatMonth() above
    timeAndDateDS1302.setDayOfMonth(12)                   'set the day of the month only (1.....31 -> make sure it ties up i.e dont for eg set February 31!)
    timeAndDateDS1302.setYear(20)                         'set the year only -> 20 = the year 2020 (the DS1302 allows for years from 2000 to 2099)
    logData
    Log("***********************************************")
    Log(" ")

    'This method can set the seconds too - if you set the seconds then the other date/time registers need to be set within 60 seconds or
    'else the seconds setting and all subsequent date/time settings will not be executed (i.e time/date will stay as what it was prior to the attempt to set it)
'    timeAndDateDS1302.setRTCTime(20, 1, 11, 7, 17, 13, 55)    'set the year, month, day of month, day of week, hour, minute, AND second

    Dim cnt As Byte = 0
    For i = 0xC0 To 0xFC Step 2                                   'the commands/addresses to write values to each of the 31 RAM locations
        Dim randomNumb As Byte = cnt * 7
        Log("Value written to RAM location ", cnt, " = ", randomNumb)
        timeAndDateDS1302.writeValueToRamAddress(i, randomNumb)   'store random number in each of the 31 RAM spaces/addresses
        cnt = cnt + 1
    Next
    Log(" ")

    t.Enabled = True
   
End Sub

Sub t_tick

    logData

End Sub

Sub logData

    Dim retVal As Byte = 0

    retVal = timeAndDateDS1302.getSeconds
   
    If retVal Mod 2 = 1 Then
        p4.DigitalWrite(True)
        p5.DigitalWrite(False)
    Else
        p4.DigitalWrite(False)
        p5.DigitalWrite(True)
    End If

    Dim hourMode As Boolean = timeAndDateDS1302.getHourMode        'check if the DS1302 is in 12HR or 24HR mode
    If hourMode = False Then
        Log("DS1302 Time: ", _
        "20", NumberFormat(timeAndDateDS1302.getYear,2,0), "-", NumberFormat(timeAndDateDS1302.getMonth,2,0), "-", NumberFormat(timeAndDateDS1302.getDayOfMonth,2,0), _
        "   ", _
        NumberFormat(timeAndDateDS1302.getHours,2,0), ":", NumberFormat(timeAndDateDS1302.getMinutes,2,0), ":", NumberFormat(timeAndDateDS1302.getSeconds,2,0), _
        " ", _
        whatDay(timeAndDateDS1302.getDayOfWeek - 1))
       
    Else if hourMode = True And timeAndDateDS1302.getAmPmMode = True Then
        Log("DS1302 Time: ", _
        "20", NumberFormat(timeAndDateDS1302.getYear,2,0), "-", NumberFormat(timeAndDateDS1302.getMonth,2,0), "-", NumberFormat(timeAndDateDS1302.getDayOfMonth,2,0), _
        "   ", _
        NumberFormat(timeAndDateDS1302.getHours,2,0), ":", NumberFormat(timeAndDateDS1302.getMinutes,2,0), ":", NumberFormat(timeAndDateDS1302.getSeconds,2,0), _
        " ", _
        whatDay(timeAndDateDS1302.getDayOfWeek - 1), " AM")
    Else if hourMode = True And timeAndDateDS1302.getAmPmMode = False Then
        Log("DS1302 Time: ", _
        "20", NumberFormat(timeAndDateDS1302.getYear,2,0), "-", NumberFormat(timeAndDateDS1302.getMonth,2,0), "-", NumberFormat(timeAndDateDS1302.getDayOfMonth,2,0), _
        "   ", _
        NumberFormat(timeAndDateDS1302.getHours,2,0), ":", NumberFormat(timeAndDateDS1302.getMinutes,2,0), ":", NumberFormat(timeAndDateDS1302.getSeconds,2,0), _
        " ", _
        whatDay(timeAndDateDS1302.getDayOfWeek - 1), " PM")  
        Log(" ")  
    End If
   
    Log(" ")
    Dim cnt As Byte = 0
    For i = 0xC1 To 0xFD Step 2                         'the commands/addresses to read the 31 RAM location values
        Log("Value read from RAM location ", cnt, " = ", timeAndDateDS1302.readValueFromRamAddress(i))
        cnt = cnt + 1
    Next
    Log(" ")

    toggleHour12Hr24HR

End Sub

Sub toggleHour12Hr24HR
   
    Dim hourMode As Boolean = timeAndDateDS1302.getHourMode        'check if the DS1302 is in 12HR or 24HR mode - True if 24HR mode
    Dim ampm As Boolean = timeAndDateDS1302.getAmPmMode            'check if DS1302 time is currently AM or PM - True if AM
    Dim hour As Byte = timeAndDateDS1302.getHours
    If hourMode = True And hour > 12 Then
        hour = hour - 12
        timeAndDateDS1302.setHours12(hour, False)
    else if hourMode = True And hour  > 0 And hour < 12 Then
        timeAndDateDS1302.setHours12(hour, True)
    else if hourMode = True And hour = 12 Then
        timeAndDateDS1302.setHours12(12, False)
    else if hourMode = True And hour = 0 Then
        timeAndDateDS1302.setHours12(12, True)
    else if hourMode = False And ampm = True And hour = 12 Then
        timeAndDateDS1302.setHours24(0)
    else if hourMode = False And ampm = True And hour < 12 Then
        timeAndDateDS1302.setHours24(hour)
    else if hourMode = False And ampm = False And hour = 12 Then
        timeAndDateDS1302.setHours24(12)
    else if hourMode = False And ampm = False And hour >= 1 And hour < 12 Then
        hour = hour + 12
        timeAndDateDS1302.setHours24(hour)  
    End If
   
   
End Sub
Code of Code Module timeAndDateDS1302:
B4X:
Private Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.

    Private pclk, pdat, prst As Pin          'clock, I/O, CE
    Private data As Byte = 0
    Private thisDAT As Byte = 0
   
    Private originalCommand As Byte = 0
    Private morning As Boolean = False
    Private mode24 As Boolean = True

End Sub

'Initialize the timer with the required pins
'clk = pin number of arduino that the DS1302 CLK pin in connected to (serial Clock)
'dat = pin number of arduino that the DS1302 DAT pin in connected to (I/O or Data)
'rst = pin number of arduino that the DS1302 RST pin in connected to (Reset or Chip Enable)
'Note - The pins on the DS1302 might be labelled as CE or RST, I/O or DAT(data line), and SCLK or CLK (serial clock).
'CE = RST
'I/O = DAT
'SCLK = CLK
Public Sub Initialize (clk As Byte, dat As Byte, rst As Byte)

    pclk.Initialize(clk, pclk.MODE_OUTPUT)
    pdat.Initialize(dat, pdat.MODE_OUTPUT)
    prst.Initialize(rst, prst.MODE_OUTPUT)
    thisDAT = dat

    pclk.DigitalWrite(False)
    pdat.DigitalWrite(False)
    prst.digitalwrite(False)

End Sub

'Set the Minute of the DS1302
'The method will automatically clock in 0x82 (BCD) as a command to set the Minutes
Public Sub setMinutes (minutes As Byte)

    Dim command As Byte = 0x82                   'command to set the minutes = 0x82h (BCD)
    sendCommand(command)
    setValue(minutes)

End Sub

'Set the Hour of the DS1302
'The method will automatically clock in 0x84 (BCD) as a command to set the Hours
Public Sub setHours24(hours As Byte)

    Dim command As Byte = 0x84                   'command to set the Hours = 0x84h (BCD)
    sendCommand(command)
    setValue(hours)

End Sub


'Set the Hour of the DS1302 (12hr format)
'The method will automatically clock in 0x84 (BCD) as a command to set the Hours
'Set AM = True if hours is AM
'Set AM = False if hours is PM
Public Sub setHours12(hours As Byte, AM As Boolean)

    Dim command As Byte = 0x84                   'command to set the Hours = 0x84h (BCD)
    sendCommand(command)                         'send command to the DS1302 to set the hours

    Dim hour10 As Byte = hours/10                'get the 10's of the hours
    Dim hour1 As Byte = hours Mod 10             'get the 1's of the hours
    morning = AM                                 'set the global boolean variable - we will need it later
    If morning = False Then                      'we are setting time as PM
        Dim mask As Byte = 10                    'mask to set the 12HR/24HR bit HIGH and also set the AM/PM bit HIGH
        hour10 = Bit.Or(hour10, mask)
        hours = hour10 * 10 + hour1
    Else                                         'we are setting time as AM
        Dim mask As Byte = 8                     'we need to set the 12HR/24HR bit to HIGH so that time will be in 12HR format. It also sets the AM/PM bit LOW for AM
        hour10 = Bit.Or(hour10, mask)            'set the bit
        hours = hour10 * 10 + hour1              'calculate the decimal value for "hours" that we need to pass to Sub setValue
    End If  
   
    setValue(hours)                               'call Sub setValue and pass the decimal value.

End Sub

'Set the Month of the DS1302
'The method will automatically clock in 0x88 (BCD) as a command to set the Month
'January = 1, February = 2, ........, December = 12
Public Sub setMonth(month As Byte)

    Dim command As Byte = 0x88                   'command to set the Month = 0x88h (BCD)
    sendCommand(command)
    setValue(month)

End Sub

'Set the DayOfWeek of the DS1302
'The method will automatically clock in 0x8A (BCD) as a command to set the Day Of Week
'Sunday = 1, Monday = 2, ........, Saturday = 7
Public Sub setDayOfWeek(dow As Byte)

    Dim command As Byte = 0x8A                   'command to set the Month = 0x8Ah (BCD)
    sendCommand(command)
    setValue(dow)

End Sub

'Set the DayOfMonth of the DS1302
'The method will automatically clock in 0x86 (BCD) as a command to set the Day Of Month
'Day Of Month = 1...31
Public Sub setDayOfMonth(dom As Byte)

    Dim command As Byte = 0x86                   'command to set the Day Of Month = 0x86h (BCD)
    sendCommand(command)
    setValue(dom)

End Sub

'Set the Year of the DS1302
'The method will automatically clock in 0x8C (BCD) as a command to set the Year
'Year = 2000...2099
'The DS1302 only allows for years from 2000 to 2099 so no need to send the century - only send the Year of the century.
'eg: setTimeAndDate1302.setYear(20)
Public Sub setYear(year As Byte)

    Dim command As Byte = 0x8C                   'command to set the Year = 0x8Ch (BCD)
    sendCommand(command)
    setValue(year)

End Sub

'Set the Seconds of the DS1302
'The method will automatically clock in 0x80 (BCD) as a command to set the Seconds
'Seconds = 0...59
Private Sub setSeconds(seconds As Byte)

    Dim command As Byte = 0x80                   'command to set the Year = 0x80h (BCD)
    sendCommand(command)
    setValue(seconds)

End Sub

'set the RTC date and time in one GO - it will be set to 24HR format
'Year = 0 - 99 (which represents 2000 to 2099 - the DS1302 only allows for these years)
'month = 1 - 12 (1 = January,......,12 = December)
'dayOfMonth = 0 - 31 (take care of what you do if the month is for eg February and it is/is not a leap year)
'dayOfWeek = 1 - 7 (Sunday = 1, Monday = 2, ......, Saturday = 7)
'hour = 0 - 23
'minute = 0 - 59
Public Sub setRTCTime(year As Byte, month As Byte, dayOfMonth As Byte, dayOfWeek As Byte, hour As Byte, minute As Byte, second As Byte)

    setSeconds(second)
    setMinutes(minute)
    setHours24(hour)
    setDayOfMonth(dayOfMonth)
    setMonth(month)
    setDayOfWeek(dayOfWeek)
    setYear(year)

End Sub

'Common Private Sub to send the necessary command to the DS1302 before setting the applicable RTC register
Private Sub sendCommand (command As Byte)

    originalCommand = command

    prst.Digitalwrite(True)                      'pull CE line high                  '
    DelayMicroseconds(2)

    Dim mask As Byte = 1                         'set the mask to AND the command with
    For i = 0 To 7                               'cycle through the 8 bits of the command
        If Bit.And(command, mask) = 1 Then
            pdat.DigitalWrite(True)              'take the DAT line high
        Else
            pdat.DigitalWrite(False)             'take the DAT line low
        End If
        DelayMicroseconds(1)
        pclk.DigitalWrite(True)                  'take the CLK line high
        DelayMicroseconds(1)
        pclk.DigitalWrite(False)                 'take the CLK line low
        DelayMicroseconds(1)
        command = Bit.ShiftRight(command,1)      'shift the command bits 1 bit to the right for the next AND instruction
    Next

End Sub

'Common Private Sub to send the necessary data to the DS1302 to set the applicable RTC register
private Sub setValue(value As Byte)

    If originalCommand < 0xC0 Then               'i.e not writing to one of the RAM locations but to a time register
        Dim highnibble As Byte = value/10
        highnibble = Bit.ShiftLeft(highnibble,4)
        Dim lownibble As Byte = value Mod 10
        value = Bit.Or(highnibble,lownibble)
    End If
    For i = 0 To 7
        If Bit.And(value, 1) = 1 Then
            pdat.DigitalWrite(True)              'take the DAT line high
        Else
            pdat.DigitalWrite(False)             'take the DAT line low
        End If
        DelayMicroseconds(1)
        pclk.DigitalWrite(True)                  'take the CLK line high
        DelayMicroseconds(1)
        pclk.DigitalWrite(False)                 'take the CLK line low
        DelayMicroseconds(1)
        value = Bit.ShiftRight(value,1)          'shift the command bits 1 bit to the right for the next AND instruction
    Next
    prst.DigitalWrite(False)                     'pull CE line low

End Sub

'Common Private Sub to get Time/Date data from the DS1302
Private Sub getdata (command As Byte) As Byte

    originalCommand = command
   
    prst.Digitalwrite(True)                      'pull CE line high                  '
    DelayMicroseconds(2)

    Dim mask As Byte = 1                         'set the mask to AND the command with
    For i = 0 To 7                               'cycle through the 8 bits of the command
        If Bit.And(command, mask) = 1 Then
            pdat.DigitalWrite(True)              'take the DAT line high
        Else
            pdat.DigitalWrite(False)             'take the DAT line low
        End If
        DelayMicroseconds(1)
        pclk.DigitalWrite(True)                  'take the CLK line high
        DelayMicroseconds(1)
        pclk.DigitalWrite(False)                 'take the CLK line low
        DelayMicroseconds(1)
        command = Bit.ShiftRight(command,1)      'shift the command bits 1 bit to the right for the next AND instruction
    Next

    data = 0

    pdat.Initialize(thisDAT, pdat.MODE_INPUT)    'set the I/O line to mode input to read the response from the RTC (DS1302) module

    mask = 1

    For i = 0 To 7                                                 'cycle through the response from the RTC module
        If pdat.DigitalRead = True Then data = Bit.Or(data, mask)  'check if the DAT pin (response) is HIGH/LOW and set byte "data" accordingly
        DelayMicroseconds(1)
        pclk.DigitalWrite(True)                                    'take the CLK pin high
        DelayMicroseconds(1)
        pclk.DigitalWrite(False)                                   'take the CLK pin LOW
        DelayMicroseconds(1)
        mask = mask * 2                                            'double "mask" to check the next bit read from the RTC module
    Next

    prst.DigitalWrite(False)                     'pull CE line low

    If originalCommand = 0x85 Then               'if we have requested to read the byte that contains HOUR information from the DS1302 -> we have sent 0x85 as a command
        check24HR12HRAmPm
    End If
   
    Dim val10, val1, val As Byte = 0
    If originalCommand < 0xc0 Then               'i.e not reading a value from one of the RAM locations but from a time register
        val10 = 0
        val1 = 0
        val1 = Bit.And(data, 0x0f)               'get the ONE's value of the lower 4 bits in data
        val10 = Bit.And(data, 0xf0)              'get the TEN's value of the lower 4 bits in data
        val10 = Bit.ShiftRight(val10,4)          'shift the TENS nibble 4 bits to the right
        val = (val10 * 10) + val1                'the final value to be returned
    Else
        val = data
    End If
    pdat.Initialize(thisDAT, pdat.MODE_OUTPUT)   'take the I/O line back to output mode so that we can write a new/next command to it
    Return val                                   'return the calculated value

End Sub


Private Sub check24HR12HRAmPm
   
    Dim mask As Byte
'    If originalCommand = 0x85 Then               'we have requested to read the byte that contains HOUR information from the DS1302 -> we have sent 0x85 as a command
        mask = 128                               'mask to check if hours is set to 12HR or 24HR mode
        If Bit.And(data, mask) = 0 Then          'if the bit = 0 then we are in 24HR mode
            mode24 = True
        End If
        If Bit.And(data, mask) = mask Then
            mode24 = False                       'if the bit != 0 then we are in 12HR mode
        End If
        mask = 32                                'mask to check if hours is AM or PM at present
        If Bit.And(data, mask) = 0 And mode24 = False Then
            morning = True                       'if the bit = 0 and we are in 12HR mode then it is AM i.e morning = True
        End If
        If Bit.And(data, mask) = mask And mode24 = False Then
            morning = False                      'if the bit != 0 and we are in 12HR mode then it is PM i.e morning = False
        End If
       
        If mode24 = True Then
            mask = 63                            'mask to filter out AM/PM and 12HR/24HR bits so that we can get the correct hour value
            data = Bit.And(data, mask)
        Else
            mask = 31                            'mask to filter out AM/PM and 12HR/24HR bits so that we can get the correct hour value
            data = Bit.And(data, mask)
        End If      


'    End If
   
End Sub

'get the seconds - the metod will automatically clock in 81h from LSB to MSB (1000 0001) as a command to get the seconds (0...59)
Public Sub getSeconds() As Byte
    Return getdata(0x81)      'get the seconds - clock in 81h from LSB to MSB (1000 0001)
End Sub

'get the minutes - the metod will automatically clock in 83h from LSB to MSB (1000 0011) as a command to get the minutes (0...59)
Public Sub getMinutes() As Byte
    Return getdata(0x83)      'get the minutes - clock in 83h from LSB to MSB (1000 0011)
End Sub

'get the hours - the metod will automatically clock in 85h from LSB to MSB (1000 0101) as a command to get the hours (0...23)
Public Sub getHours() As Byte
    Return getdata(0x85)      'get the hours - clock in 85h from LSB to MSB (1000 0101)
End Sub

'get the year - the metod will automatically clock in 8Dh from LSB to MSB (1000 1101) as a command to get the year (0...99)
Public Sub getYear() As Byte
    Return getdata(0x8D)      'get the year - clock in 8Dh from LSB to MSB (1000 1101)
End Sub

'get the month - the metod will automatically clock in 89h from LSB to MSB (1000 1001) as a command to get the month (1...12)
Public Sub getMonth() As Byte
    Return getdata(0x89)      'get the month - clock in 89h from LSB to MSB (1000 1001)
End Sub

'get the day of the month - the metod will automatically clock in 87h from LSB to MSB (1000 0111) as a command to get the day of month (0...31)
Public Sub getDayOfMonth() As Byte
    Return getdata(0x87)      'get the day of the month - clock in 87h from LSB to MSB (1000 0111)
End Sub

'get the day number of the week - the metod will automatically clock in 8Bh from LSB to MSB (1000 1011) as a command to get the day of week (1...7)
Public Sub getDayOfWeek() As Byte
    Return getdata(0x8B)      'get the day number of the week - clock in 8Bh from LSB to MSB (1000 1011)
End Sub

'Get the DS1302 12HR/24HR clock setting
'return True if 24HR mode
'return False if 12HR mode
Public Sub getHourMode() As Boolean
    Return mode24  
End Sub

'Get the DS1302 AM/PM clock setting
'return True if it is AM
'return False if it is PM
'it only returns a useful value (True / False) if the 12HR/24HR mode is set to 12HR
Public Sub getAmPmMode() As Boolean
    Return morning  
End Sub

'The static RAM is 31 x 8 bytes addressed consecutively in the RAM address space.
'value is a byte (0 to 255) to be stored is the "address" RAM location
'write addresses/commands are from 0xC0 to 0xFC in steps of 2 i.e 0xC2, 0xC2, 0xC4, ......, 0xFC (for write)
'store a byte value in the specified RAM address
Public Sub writeValueToRamAddress (address As Byte, value As Byte)
   
    sendCommand(address)
    setValue(value)
   
End Sub

'The static RAM is 31 x 8 bytes addressed consecutively in the RAM address space.
'read addresses/commands are from 0xC1 to 0xFD in steps of 2 i.e 0xC1, 0xC3, 0xC5, ......, 0xFD (for read)
'returns the value store in the specified address
Public Sub readValueFromRamAddress (address As Byte) As Byte
   
    Return getdata(address)
   
End Sub

That is where I will leave this exercise for now....;)🇿🇦
 

Attachments

Last edited:
Top