Shop OBEX P1 Docs P2 Docs Learn Events
Stampworks Experiment #33 — Parallax Forums

Stampworks Experiment #33

BullwinkleBullwinkle Posts: 101
edited 2006-09-29 15:14 in BASIC Stamp
I've been playing with experiment #33, trying to extend the functionality to display ( and modify ) the date, month and year. To do this I had to expand the number of inputs to 8 ( well 6 ) so I shifted SDA to 9 and SCL to 10.

Suddenly I get squat. I think the program is looping, waiting for response the DS1307 chip that it never gets. I've examined the code carefully and the only bit that seems a mystery is the declaration of DS1307 as %1101 << 4. This equates to 11010000 but what does it relate to? These are no meaningful comments in the code and nothing in the doco explains it.

Am I on the right track, or have I screwed up somewhere else? I have included my code below. The only hardware changes I have made above #33 are to add 4 wires from the momentary contact switches 4-7 to the inputs 4-7 on the stamp. Also the original 4 input buttons were moved to 0-3. And, as I said, SDA was moved from 0 to 9 and SCL from 1 to 10.

Is my problem related to the Slave ID (write and read) mentioned in the comments? Should I dig up the datasheet for the DS1307 for more info?

Steve

' =========================================================================

'

' File....... SW20-EX33-DS1307.BS2

' Purpose.... Real-time-clock interfacing

' Author..... (C) 2000 - 2005, Parallax, Inc.

' E-mail..... support@parallax.com

' Started....

' Updated.... 01 SEP 2005

'

' {$STAMP BS2}

' {$PBASIC 2.5}

'

' =========================================================================





'
[noparse][[/noparse] Program Description ]

'

' This program demonstrates the access and control of an external real-

' time-clock chip, the DS1307.





'
[noparse][[/noparse] I/O Definitions ]



SDA PIN 9 ' I2C serial data line

SCL PIN 10 ' I2C serial clock line



BtnBus VAR INL ' eight inputs, pins 0 - 7





'
[noparse][[/noparse] Constants ]



Ack CON 0 ' acknowledge bit

Nak CON 1 ' no ack bit



DS1307 CON %1101 << 4



'
[noparse][[/noparse] Variables ]



slvAddr VAR Byte ' I2C slave address

devNum VAR Nib ' device number (0 - 7)

addrLen VAR Nib ' bytes in word addr (0 - 2)

wrdAddr VAR Word ' word address



i2cData VAR Byte ' data to/from device

i2cWork VAR Byte ' work byte for TX routine

i2cAck VAR Bit ' Ack bit from device



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

control VAR Byte ' SQW I/O control



btns VAR Byte ' debounced button inputs

btnBack VAR btns.BIT5 ' roll back
btnYear VAR btns.BIT4 ' +/- month
btnMonth VAR btns.BIT3 ' +/- month

btnDate VAR btns.BIT2 ' +/- date

btnHr VAR btns.BIT1 ' +/- hours

btnMn VAR btns.BIT0 ' +/- minutes



idx VAR Nib ' loop control

pntr VAR Byte ' ee pointer

char VAR Byte ' character for display





'
[noparse][[/noparse] EEPROM Data ]



DayNames DATA "SunMonTueWedThuFriSat"
MonthNames DATA "JanFebMarAprMayJunJulAugSepOctNovDec"





'
[noparse][[/noparse] Initialization ]



Reset:

#IF ($STAMP >= BS2P) #THEN

#ERROR "Please use BS2p version: SW20-EX33-DS1307.BSP"

#ENDIF



Setup:

slvAddr = DS1307 ' 1 byte in word address

addrLen = 1





DEBUG LF,"DS1307 Demo", LF,

"
",LF,LF



Reset_Clock:

GOSUB Get_Buttons ' scan buttons

idx = btns & %0011 ' isolate hrs & mins

IF (idx = %11) THEN ' if both pressed, reset

secs = $00

mins = $00

hrs = $06 ' 6:00 AM

day = $07 ' Saturday

date = $01 ' 1st

month = $01 ' January

year = $05 ' 2005

control = 0 ' disable SQW output

' GOSUB Set_Clock ' block write clock regs

ENDIF





'
[noparse][[/noparse] Program Code ]



Main:

GOSUB Get_Clock ' read DS1307

hrs = hrs & $3F



GOSUB Print_Day
DEBUG " ",HEX2 date
GOSUB Print_Month
DEBUG " ",HEX2 year
DEBUG " ",HEX2 hrs, ":", HEX2 mins, ":", HEX2 secs,CR

PAUSE 100



GOSUB Get_Buttons

IF (btns > %0000) THEN ' button pressed?

IF (btns <> %1000) THEN ' ignore back only

hrs = hrs.NIB1 * 10 + hrs.NIB0 ' BCD to decimal

mins = mins.NIB1 * 10 + mins.NIB0



IF (btnBack = 0) THEN ' increment values
year = ((year - 1) + btnYear // 99) + 1 ' keep 1 - 99
month = ((month - 1) + btnMonth // 12) + 1 ' keep 1 - 12

date = ((date - 1) + btnDate // 31) + 1 ' keep 1 - 31

hrs = hrs + btnHr // 24 ' keep 0 - 23

mins = mins + btnMn // 60 ' keep 0 - 59

ELSE
year = ((year - 1) + (btnYear * 98) // 99) + 1
month = ((date - 1) + (btnMonth * 11) // 12) + 1

date = ((date - 1) + (btnDate * 30) // 31) + 1

hrs = hrs + (btnHr * 23) // 24

mins = mins + (btnMn * 59) // 60

ENDIF



hrs = (hrs / 10 << 4) + (hrs // 10) ' decimal to BCD

mins = (mins / 10 << 4) + (mins // 10)

secs = $00

GOSUB Set_Clock ' update DS1307

ENDIF

ENDIF



GOTO Main





'
[noparse][[/noparse] Subroutines ]



Get_Buttons:

btns = %1111 ' enable all four inputs

FOR idx = 1 TO 5

btns = btns & ~BtnBus ' test inputs

PAUSE 5 ' delay between tests

NEXT

RETURN





Print_Day:

pntr = DayNames + ((day - 1) * 3) ' point to 1st char

FOR idx = 0 TO 2 ' print 3 letters

READ (pntr + idx), char ' read letter

DEBUG char ' print it

NEXT

RETURN


Print_Month:

pntr = MonthNames + ((month - 1) * 3) ' point to 1st char

FOR idx = 0 TO 2 ' print 3 letters

READ (pntr + idx), char ' read letter

DEBUG char ' print it

NEXT

RETURN



' Do a block write to clock registers



Set_Clock:

GOSUB I2C_Start ' send Start

i2cWork = slvAddr & %11111110 ' send slave ID (write)

GOSUB I2C_TX_Byte

IF (i2cAck = Nak) THEN Set_Clock ' wait until not busy

i2cWork = 0 ' point at secs register

GOSUB I2C_TX_Byte

FOR idx = 0 TO 7 ' write secs to control

i2cWork = secs(idx)

GOSUB I2C_TX_Byte

NEXT

GOSUB I2C_Stop

RETURN





' Do a block read from clock registers



Get_Clock:

GOSUB I2C_Start ' send Start

i2cWork = slvAddr & %11111110 ' send slave ID (write)

GOSUB I2C_TX_Byte

IF (i2cAck = Nak) THEN Get_Clock ' wait until not busy

i2cWork = 0 ' point at secs register

GOSUB I2C_TX_Byte

GOSUB I2C_Start

i2cWork = slvAddr | %00000001 ' send slave ID (read)

GOSUB I2C_TX_Byte

FOR idx = 0 TO 6 ' read secs to year

GOSUB I2C_RX_Byte

secs(idx) = i2cWork

NEXT

GOSUB I2C_RX_Byte_Nak ' read control

control = i2cWork

GOSUB I2C_Stop

RETURN





' =====[noparse][[/noparse] High Level I2C Subroutines]=======================================



' Random location write

' -- pass device slave address in "slvAddr"

' -- pass bytes in word address (0, 1 or 2) in "addrLen"

' -- word address to write passed in "wrdAddr"

' -- data byte to be written is passed in "i2cData"



Write_Byte:

GOSUB I2C_Start ' send Start

i2cWork = slvAddr & %11111110 ' send slave ID (write)

GOSUB I2C_TX_Byte

IF (i2cAck = Nak) THEN Write_Byte ' wait until not busy

IF (addrLen > 0) THEN

IF (addrLen = 2) THEN

i2cWork = wrdAddr.BYTE1 ' send word address (1)

GOSUB I2C_TX_Byte

ENDIF

i2cWork = wrdAddr.BYTE0 ' send word address (0)

GOSUB I2C_TX_Byte

ENDIF

i2cWork = i2cData ' send data

GOSUB I2C_TX_Byte

GOSUB I2C_Stop

RETURN





' Random location read

' -- pass device slave address in "slvAddr"

' -- pass bytes in word address (0, 1 or 2) in "addrLen"

' -- word address to write passed in "wrdAddr"

' -- data byte read is returned in "i2cData"



Read_Byte:

GOSUB I2C_Start ' send Start

IF (addrLen > 0) THEN

i2cWork = slvAddr & %11111110 ' send slave ID (write)

GOSUB I2C_TX_Byte

IF (i2cAck = Nak) THEN Read_Byte ' wait until not busy

IF (addrLen = 2) THEN

i2cWork = wrdAddr.BYTE1 ' send word address (1)

GOSUB I2C_TX_Byte

ENDIF

i2cWork = wrdAddr.BYTE0 ' send word address (0)

GOSUB I2C_TX_Byte

GOSUB I2C_Start

ENDIF

i2cWork = slvAddr | %00000001 ' send slave ID (read)

GOSUB I2C_TX_Byte

GOSUB I2C_RX_Byte_Nak

GOSUB I2C_Stop

i2cData = i2cWork

RETURN





'
[noparse][[/noparse] Low Level I2C Subroutines]



' *** Start Sequence ***



I2C_Start: ' I2C start bit sequence

INPUT SDA

INPUT SCL

LOW SDA



Clock_Hold:

DO : LOOP UNTIL (SCL = 1) ' wait for clock release

RETURN





' *** Transmit Byte ***



I2C_TX_Byte:

SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork\8] ' send byte to device

SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cAck\1] ' get acknowledge bit

RETURN





' *** Receive Byte ***



I2C_RX_Byte_Nak:

i2cAck = Nak ' no Ack = high

GOTO I2C_RX



I2C_RX_Byte:

i2cAck = Ack ' Ack = low



I2C_RX:

SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cWork\8] ' get byte from device

SHIFTOUT SDA, SCL, LSBFIRST, [noparse][[/noparse]i2cAck\1] ' send ack or nak

RETURN





' *** Stop Sequence ***



I2C_Stop: ' I2C stop bit sequence

LOW SDA

INPUT SCL

INPUT SDA

RETURN

Comments

  • BullwinkleBullwinkle Posts: 101
    edited 2006-02-01 11:07
    I am going to get a reputation on this forum ( if it's not too late already smile.gif ).

    Having posted my question I suddenly see the obvious mistake. Pins 0-7 and the input pins and pins 8 and 9 are now the SDA and SCL pins. Not 9 and 10! D'Oh!!!!

    And I call myself a C programmer.

    I must now go to the punishement room..... wink.gif
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-02-01 16:35
    In the future it would be easier for forum members if you attach the program rather than paste it unformatted into the body of the message like that as well.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • BullwinkleBullwinkle Posts: 101
    edited 2006-02-01 22:57
    Sorry about that Chris, it did look pretty ordinary, didn't it... :-(

    I still have a question about this experiment, even though I now have it working. What is the DS1307 declaration for? Why is it set to 11010000 ?

    DS1307 CON %1101 << 4

    Steve
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2006-02-01 23:26
    Steve,

    All I2C communications begin with the Slave ID (see page 185 of StampWorks 2)·and the upper four bits of that byte determine the device type.· Bits 1..3 of the Slave ID are almost always used for the device address, and bit0 determines read or write.·If you look in the DS1307 docs (hint, hint... tongue.gif) you'll see that the device type for the DS1307 is %1101 -- Figure 6 shows a typical communication burst.· Since the DS1307 is not addressable, bits 1..3 are always zero.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • BullwinkleBullwinkle Posts: 101
    edited 2006-02-02 00:58
    Thanks Jon,

    I will stop being lazy now and actually read the 3107 doco.... wink.gif
  • BullwinkleBullwinkle Posts: 101
    edited 2006-02-02 00:59
    And the 1307 doco too! B-)
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2006-02-02 01:05
    While you're at it, give StampWorks a read -- I'm told it's pretty good!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • BullwinkleBullwinkle Posts: 101
    edited 2006-02-02 02:36
    Thanks Jon!

    Stampworks is an excellent, well written book, thank you. I'm kinda jumping around doing experiments that grab my interest then extending them, rather than reading the book cover-to-cover. I figure the best way to learn this stuff is to just jump in. And reading the device datasheets could be a good idea too.

    Tonight I plan to add the LCD display to the extended experiment #33. More fun! smile.gif

    Steve
  • NAVEENNAVEEN Posts: 2
    edited 2006-08-29 19:35
    I am trying to interface DS1307 with BS2p.I couldn't find SW20-EX33-DS1307.BSP file. Any body could please post the same. Thanks a lot.
  • Kevin WoodKevin Wood Posts: 1,266
    edited 2006-08-29 20:32
    There's a link to the StampWorks source code at the bottom of the following page:

    www.parallax.com/detail.asp?product_id=27297
  • Steve AndruesSteve Andrues Posts: 29
    edited 2006-09-25 03:29
    I am batting 0-6 for getting any DS1307 sample code to work! Is it possible that my PDB had died?
  • PARPAR Posts: 285
    edited 2006-09-25 07:02
    Steve Andrues said...
    I am batting 0-6 for getting any DS1307 sample code to work! Is it possible that my PDB had died?
    Anything's possible. Did you strike out all six times, or did you pop flies for outs, or did you put out at first? Or, what?

    PAR
  • Steve AndruesSteve Andrues Posts: 29
    edited 2006-09-29 04:52
    The only code for the DS1307 that almost worked was for the NX1000 development board. It would display 65:65:65 as the time. The switches are unresponsive. There are two subroutines at the end of the code which are never called. They are either left over from some other project, or the overall code is incomplete.
  • Bruce BatesBruce Bates Posts: 3,045
    edited 2006-09-29 05:11
    Steve -

    I have a ZIP file with a number of different DS-130X files in it which you are welcome to have if you'd like it. Send me your email address at the address below, and I'll send it along.

    Regards,

    Bruce Bates
    bvbates @ comcast.net
    ·
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-09-29 15:14
    Steve,

    ·· Are you adding 4.7K pull-up resistors to the SDA/SCL lines?· If so that could be causing your problems.· It would help to know exactly what was connected where on the board.· I have attached known working code.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
Sign In or Register to comment.