Shop OBEX P1 Docs P2 Docs Learn Events
RTC 1307 code minimized to 1 byte & 1 nib — Parallax Forums

RTC 1307 code minimized to 1 byte & 1 nib

FalconFalcon Posts: 191
edited 2012-04-17 17:37 in BASIC Stamp
I want to use the DS1307 Real Time Clock in a BS2Px project but I only have a few BYTES of variable space left. I started with code I found on this fourm and slowly deleted parts that were not required including the AM-PM and 12-hour clock formatting. I can get by with 24-hour clock. All worked good at that point.

The next step is to try to make use of the Scratchpad RAM to shuffle BYTES of data around instead of having a separate BYTE for year, month, date, hour, minute and seconds. At that point it fails. See code including Get and Put commands below.

The following shows the input and displayed results with the below code:

Input Results
year 12 03:33:00
month 04 33/33/33
date 14
hours 12
mins 33

After the clock is started (with the above inputs) the last number on the second line counts up seconds, and the first number on the second line increments up when the seconds reaches 60 (so it's showing minutes.)

I suspect the error is in the subroutines that include the I2CIN & I2COUT statements.

For now, I left the seconds variable in use but I would like to remove it also if possible.

Is this approach (using only 1 BYTE) even possible?

falcon
' {$STAMP BS2p}
' {$PBASIC 2.5}
' -----[ Program Description ]---------------------------------------------
'
' This program demonstrates the access and control of an external real-
' time-clock chip, the DS1307.
' -----[ I/O Definitions ]-------------------------------------------------
SDA          PIN         0 ' I2C serial data line
SCL          PIN         1 ' I2C serial clock line
LCD          PIN         11
' -----[ Constants ]-------------------------------------------------------
DS1307       CON         %1101 << 4

' -----[ Variables ]-------------------------------------------------------
secs         VAR   Byte ' DS1307 time registers
'mins         VAR   Byte
'hrs          VAR   Byte
'day          VAR   Byte ' weekday
'date         VAR   Byte ' day in month, 1 - 31
'month        VAR   Byte
'year         VAR   Byte
time         VAR   Byte
idx          VAR   Nib
' =========Define names for LCD instructions, bps=======
homeCur      CON   1  'Cursor home cntl-A
bigChar      CON   2  'Begin big characters cntl-B
regChar      CON   3  'End big characters cntl-C
noCurs       CON   4  'Make cursor invisible cntl-D
ulCurs       CON   5  'Show underline cursor cntl-E
blkCurs      CON   6  'Show blinking block cursor
ringBell     CON   7  'Bell output cntl-G
backSp       CON   8  'Backspace cntl-H
hTab         CON   9  'Horizontal tab (4 col) cntl-I
curLF        CON   10 'Smart linefeed cntl-J
vTab         CON   11 'cursor up one line cntl-K
clrLCD       CON   12 'Clear entire LCD screen cntl-L
carRet       CON   13 'Carriage return cntl-M
onBkLight    CON   14 'Backlight on cntl-N
offBkLight   CON   15 'Backlight off cntl-O
posCmd       CON   16 'Position cursor cntl-P
clrCol       CON   17 'Clear column cntl-Q ?
alignRight   CON   18 'Accept right-alignment data cntl-R
Esc          CON   27 'Escape sequences

'TrueBaud mode for non-inverted 9600-N81 (MAX233a line driver)
'InvBaud mode for inverted, 9600-N81    (direct connect e.g. w/22k ohm)
#SELECT $STAMP
  #CASE BS2, BS2E, BS2PE
    TrueBaud CON 84
    InvBaud CON 16468
  #CASE BS2SX, BS2P
    TrueBaud CON 240
    InvBaud CON 16624
  #CASE BS2PX
    TrueBaud CON 396
    InvBaud CON 16780
#ENDSELECT
' -----[ Initialization ]--------------------------------------------------
Reset:
DEBUG CLS, "Enter 'y' to set date"
SERIN 16, TrueBaud, 8000, Skip_set, [WAIT("y")]
DEBUG CLS                             ' Clear The DEBUG Screen

SetClock:
DEBUG CRSRXY, 0, 0, "Enter 2 dig year", CLREOL
DEBUGIN HEX2 time                ' Set Year
PUT 40, time
I2COUT SDA, DS1307, 0, [time]

DEBUG CRSRXY, 12, 0, "mth", CLREOL
DEBUGIN HEX2 time                    ' Set Month
PUT 41, time
I2COUT SDA, DS1307, 1, [time]

DEBUG CRSRXY, 12, 0, "day", CLREOL
DEBUGIN HEX2 time                     ' Set Date
PUT 42, time
I2COUT SDA, DS1307, 2, [time]

'DEBUG CRSRXY, 6, 0, "week day", CLREOL
DEBUG CLS
DEBUG CRSRXY, 0, 1, CLREOL
  DEBUG CRSRXY, 6, 0, "2 dig hour, 00-23", CLREOL
  DEBUGIN HEX2 time                    ' Set Hours (24 Hour Mode)
PUT 43, time
I2COUT SDA, DS1307, 3, [time]

DEBUG CRSRXY, 12, 0, "min, 00-59", CLREOL
DEBUGIN HEX2 time                     ' Set Minutes
PUT 44, time
I2COUT SDA, DS1307, 4, [time]

secs = $00

GOSUB Set_Clock ' block write clock regs

' -----[ Program Code ]----------------------------------------------------
Skip_set:
DEBUG CLS,
Main:
GOSUB Get_Clock              ' read DS1307
'IF secs = 128 THEN GOTO SetClock    'clock not set
GET 43, time
DEBUG CRSRXY, 0, 2, HEX2 time, ":"      'hours
GET 41, time
DEBUG CRSRXY, 3, 2, HEX2 time, ":"      'minutes           correct

DEBUG CRSRXY, 6, 2, HEX2 secs, CR       'seconds

GET 44, time
DEBUG HEX2 time, "/"     'month
GET 42, time
DEBUG HEX2 time, "/"     'date
GET 40, time
DEBUG HEX2 time, CR      'year

PAUSE 100
GOTO Main

' -----[ Sub Routine Code ]----------------------------------------------------

' Do a block write to clock registers
Set_Clock:
FOR idx = 0 TO 4
  I2COUT SDA, DS1307, idx, [time]           ' update clock registers
  NEXT
  RETURN

' Do a block read from clock registers
Get_Clock:
FOR idx = 0 TO 4
  I2CIN SDA, DS1307, idx, [time]            ' retrieve clock registers
  PUT idx + 40, time
  NEXT
  RETURN


Comments

  • Tracy AllenTracy Allen Posts: 6,662
    edited 2012-04-15 11:02
    There is something mixed up in the order of seconds to years. The getClock routine PUTs bytes starting at SPRAM location 40. The '1307 gives back data with seconds first. You have,
    second ' $00 - $59 bcd, high bit set if clock not running
    minute ' $00 - $59 bcd
    hour ' $00 - $23 bcd
    dow ' day of week $00 - $06
    date ' $00 - $31
    but getClock is stopping there at 5 bytes, not reading in the month and year. That is not consistent with the data input and display section, where the year is associated with location 40.

    One option for the I2C command is the SPSTR modifier:

    I2CIN SDA, DS1307, 0, [SPSTR 7]

    Read 7 clock registers from the DS1307 starting with seconds directly into SPRAM starting at location 0.
  • bee_manbee_man Posts: 109
    edited 2012-04-15 16:16
    Depending on your project I would get rid of all the clock setting routines. That would free up alot of space. Once you set the RTC with another stand alone program the RTC just keeps chugging along. I rarely end up setting them again.
  • FalconFalcon Posts: 191
    edited 2012-04-17 17:37
    bee_man,
    I may implement your suggestion. I will have to see if the DS1307 compensates for DST.

    Tracy,

    I finally got it worked out. I checked to see that it increments correctly to the next month and next year.

    Uses only 1 byte and 1 Nib.

    Thanks for your help.

    falcon
    ' {$STAMP BS2p}
    ' {$PBASIC 2.5}
    ' -----[ Program Description ]---------------------------------------------
    '
    ' This program demonstrates the access and control of an external real-
    ' time-clock chip, the DS1307.
    ' -----[ I/O Definitions ]-------------------------------------------------
    SDA          PIN         0 ' I2C serial data line
    SCL          PIN         1 ' I2C serial clock line
    LCD          PIN         11
    ' -----[ Constants ]-------------------------------------------------------
    DS1307       CON         %1101 << 4
    
    ' -----[ Variables ]-------------------------------------------------------
    
    time         VAR   Byte
    idx          VAR   Nib
    ' =========Define names for LCD instructions, bps=======
    
    'TrueBaud mode for non-inverted 9600-N81 (MAX233a line driver)
    'InvBaud mode for inverted, 9600-N81    (direct connect e.g. w/22k ohm)
    #SELECT $STAMP
      #CASE BS2, BS2E, BS2PE
        TrueBaud CON 84
        InvBaud CON 16468
      #CASE BS2SX, BS2P
       TrueBaud CON 240
       InvBaud CON 16624
      #CASE BS2PX
        TrueBaud CON 396
        InvBaud CON 16780
    #ENDSELECT
    ' -----[ Initialization ]--------------------------------------------------
    Reset:
    DEBUG CLS, "Enter 'y' to set date"
    SERIN 16, TrueBaud, 8000, Skip_set, [WAIT("y")]
    DEBUG CLS                             ' Clear The DEBUG Screen
    
    SetClock:
    DEBUG CRSRXY, 0, 0, "Enter 2 dig year", CLREOL
    DEBUGIN HEX2 time                                                     ' Set Year    45
    PUT 46, time
    I2COUT SDA, DS1307, 0, [time]
    
    DEBUG CRSRXY, 12, 0, "mth", CLREOL
    DEBUGIN HEX2 time                                                     ' Set Month   43
    PUT 45, time
    I2COUT SDA, DS1307, 1, [time]
    
    DEBUG CRSRXY, 12, 0, "day", CLREOL
    DEBUGIN HEX2 time                                                     ' Set Date    44
    PUT 44, time
    I2COUT SDA, DS1307, 2, [time]
    
    DEBUG CRSRXY, 6, 0, "2 dig hour, 00-23", CLREOL
    DEBUGIN HEX2 time                                                   ' Set Hours   42
    PUT 42, time
    I2COUT SDA, DS1307, 3, [time]
    
    DEBUG CRSRXY, 12, 0, "min, 00-59", CLREOL
    DEBUGIN HEX2 time                                                     ' Set Minutes 41
    PUT 41, time
    I2COUT SDA, DS1307, 4, [time]
                                                                           ' Set Seconds 40
    time = $00                                                             ' Set Seconds 40
    PUT 40, time
    I2COUT SDA, DS1307, 5, [time]
    
    GOSUB Set_Clock ' block write clock regs
    
    ' -----[ Program Code ]----------------------------------------------------
    Skip_set:
    DEBUG CLS
    
    start:
    GOSUB Get_Clock              ' read DS1307
    
    GET 42, time
    DEBUG CRSRXY, 0, 2, HEX2 time, ":"      'hours
    GET 41, time
    DEBUG CRSRXY, 3, 2, HEX2 time, ":"      'minutes
    GET 40, time
    DEBUG CRSRXY, 6, 2, HEX2 time, CR       'seconds
    
    GET 45, time
    DEBUG HEX2 time, "/"     'month
    GET 44, time
    DEBUG HEX2 time, "/"     'date
    GET 46, time
    DEBUG HEX2 time, CR      'year
    
    PAUSE 100
    GOTO start
    
    ' -----[ Sub Routine Code ]----------------------------------------------------
    
    ' Do a block write to clock registers
    Set_Clock:
    FOR idx = 0 TO 6
    GET idx + 40, time
      I2COUT SDA, DS1307, idx, [time]           ' update clock registers
      NEXT
      RETURN
    
    ' Do a block read from clock registers
    Get_Clock:
    FOR idx = 0 TO 6
      I2CIN SDA, DS1307, idx, [time]            ' retrieve clock registers
    
      PUT idx + 40, time
      NEXT
      RETURN
    
Sign In or Register to comment.