Shop OBEX P1 Docs P2 Docs Learn Events
Interfacing Stamp with External Memory — Parallax Forums

Interfacing Stamp with External Memory

TrangTrang Posts: 9
edited 2009-07-02 00:26 in BASIC Stamp
Hello experts,

I'm working on a project in which I collect data from an accelerometer for around 10 minutes to capture motion of my board. Therefore, I needed external EEPROM to store that data. I chose the 24LC256 memory chip and now I'm trying to interface it with the Stamp. (I'm using BS2e)

So I was wondering if anyone here has tried that kind of combination -- Stamp + an external memory chip -- and could possibly tell me if it's possible. I'm thinking about using the shiftin and shiftout commands as I did with a 12-bit AD converter. But what I was concerned about is that Stamp generates its own clock implicitly in those commands and whether it's gonna cause any incompatibility with the memory chip...

Has anyone done this before? Any feedback will be very much appreciated!

Comments

  • achilles03achilles03 Posts: 247
    edited 2009-06-30 15:14
    It'll work fine with that chip. Interfacing the stamp with eeproms is common practice. Eeproms require an external clock source just like ADCs, so there's no "incompatibility" there.

    However, with that chip, you'll probably need to use the I2C commands instead of the shiftin/out commands. The 2 main protocols to communicate with eeproms are SPI (shiftin and shiftout, like the ADCs you're familiar with) and I2C. It looks like the chip you chose uses I2C. You can make it easier on yourself and get an SPI eeprom, or stick with the 24LC256 and use the I2C commands. Your pick.

    Hope that helps...
    Dave
  • Mike GreenMike Green Posts: 23,101
    edited 2009-06-30 15:46
    There's a Nuts and Volts Column on interfacing with I2C EEPROMs (and other I2C devices) with Stamps that don't have the built-in I2C commands. The Column includes the subroutines you need. I don't remember which one, but browse the index ... it's something like "I2C for Everyone".
  • TrangTrang Posts: 9
    edited 2009-06-30 16:02
    Thank you so much Dave! That was really helpful. I think I'll go with SPI memory chips, since my BS2e doesn't have the I2Cin/out commands.
    One more question since this was brought up: I'm really a newbie in this field, so could you also explain to me which between SPI and I2C is better to use? And if it were you, which direction would you go with? I know I picked SPI because of my Stamp chip, but if I can choose without constraints, what should I go with? --- just curious.

    Thanks a lot for your help!
  • TrangTrang Posts: 9
    edited 2009-06-30 16:02
    Oh I just read your post after I replied. Thank you so much Mike!!
  • Mike GreenMike Green Posts: 23,101
    edited 2009-06-30 16:07
    I2C is a standardized protocol that requires only two I/O lines and allows multiple addressed devices on the same two lines. It's relatively slow with supported clock speeds of 100KHz, 400KHz, and 1MHz.

    SPI is a not very standardized at all protocol that requires three or four I/O lines. Some of these lines can be shared among devices, but you always need a select line that's unique to each device. There are all sorts of variations on this protocol with minimal commonality among devices. It's very fast though, often with devices that can accept up to a 20MHz clock (although the Stamps are much slower than that).
  • TrangTrang Posts: 9
    edited 2009-06-30 16:12
    Thank you very much! I just found the Nuts and Volts column too, very helpful...
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2009-07-02 00:26
    Here is a little program I wrote to dump memory contents in ascii and hex. You might find it useful. It will work with basic stamps that support I2C and those that don't...
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    SDA            PIN      0              ' I2C Serial Data Line
    SCL            PIN      1              ' I2C Serial Clock Line
    ChipAddr       CON      $A0            ' 24LC128 chip address
    EpromSize      CON      16             ' e.g. 16K or 32K
    Ack            CON      0              ' Acknowledge Bit
    temp           VAR      Byte           ' Variable Used For Work
    i2cWork        VAR      Word           ' Work Byte For I2C I/O
    i2cAck         VAR      Bit            ' Ack Bit From Device
    start          VAR      Word
    leng           VAR      Word           '# bytes to dump
    incr           VAR      Nib
    MemAddr        VAR      Word           ' EEPROM memory address 0 to 16383 (16k)
    
    '  MemAddr = 16383
    '  temp = 254
    '  GOSUB Write_byte
    ' GOSUB Pippin
    leng =256
    DO
      DEBUG CR, "Enter ChipAddr to dump, 0 to ", DEC (1024 * EpromSize) - leng + 15, ": "
      DEBUGIN DEC5 start
      start = (start/16)*16
      MemAddr = start
      DEBUG CR
      DO
        DEBUG DEC5 MemAddr, " "
        FOR incr = 0 TO 15
      ' Reading Section
          GOSUB Read_Byte
          DEBUG CRSRX, (incr * 3) + 7, HEX2 temp
          SELECT temp
            CASE < 32
              DEBUG CRSRX, (incr * 2) + 60, "."
            CASE > 128
              DEBUG CRSRX, (incr * 2) + 60, "."
            CASE 32 TO 127
              DEBUG CRSRX, (incr * 2) + 60, temp
          ENDSELECT
          MemAddr = MemAddr + 1
        NEXT
        DEBUG CR
      LOOP UNTIL (MemAddr >= (start + leng))
    LOOP
    END
    Pippin:
    '  start=01023
      start=02048
      MemAddr = start
      temp = "P"
      GOSUB Write_byte
      MemAddr = MemAddr + 1
      temp = "I"
      GOSUB Write_byte
      MemAddr = MemAddr + 1
      temp = "P"
      GOSUB Write_byte
      MemAddr = MemAddr + 1
      temp = "P"
      GOSUB Write_byte
      MemAddr = MemAddr + 1
      temp = "I"
      GOSUB Write_byte
      MemAddr = MemAddr + 1
      temp = "N"
      GOSUB Write_byte
      MemAddr = MemAddr + 1
      MemAddr = start
    RETURN
    Clear:
      MemAddr = start
      temp = 0
    Init:
      FOR incr = 0 TO 15
        GOSUB Write_byte
        MemAddr = MemAddr + 1
      NEXT
      IF MemAddr < start + 128 THEN
        GOTO Init
      ENDIF
    RETURN
    '------- I/O routines based on microcontroller type -----------
    #SELECT $STAMP
    ' -----[noparse][[/noparse] BS2 Subroutines ]-------------------------------------
      #CASE BS2, BS2E, BS2SX
    Write_Byte:
    'write byte in temp to MemAddr
        GOSUB I2C_Start
        GOSUB Control_Byte_Write
        GOSUB Addrs
        GOSUB Write_Data
        GOSUB I2C_Stop
        PAUSE 10
    RETURN
    Read_Byte:
    'read byte from MemAddr into temp
        GOSUB I2C_Start
    '    PAUSE 10
        GOSUB Control_Byte_Write
        GOSUB Addrs
        GOSUB I2C_Start
        GOSUB Control_Byte_Read
    '    SHIFTIN SDA, SCL, LSBFIRST, [noparse][[/noparse]i2cwork\8] ' Send Byte To Device
        SHIFTIN SDA, SCL, LSBFIRST, [noparse][[/noparse]temp\8] ' Send Byte To Device
        GOSUB I2C_Stop
    RETURN
    I2C_Start:                             ' I2C Start Bit Sequence
      INPUT SDA
      INPUT SCL
      LOW SDA                              ' SDA --> Low While SCL High
    RETURN
    I2C_Stop:                              ' I2C Stop Bit Sequence
      LOW SDA
      INPUT SCL
      INPUT SDA                            ' SDA --> High While SCL High
    RETURN
    Addrs:                                 ' I2C ChipAddr Byte Sequence
      i2cWork = MemAddr
      SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork.HIGHBYTE\8] ' Send Byte To Device
      SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cAck\1] ' Get Acknowledge Bit
      SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork.LOWBYTE\8] ' Send Byte To Device
      SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cAck\1] ' Get Acknowledge Bit
    RETURN
    Control_Byte_Write:                    ' I2C Control Write Byte Sequence
      i2cWork = ChipAddr
      i2cWork.BIT0 = 0                     ' Sets Unit To Write
      SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork\8] ' Send Byte To Device
      SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cAck\1] ' Get Acknowledge Bit
    RETURN
    Control_Byte_Read:                     ' I2C Control Read Byte Sequence
      i2cWork = ChipAddr
      i2cWork.BIT0 = 1                     ' Sets Device To Read
      SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork\8] ' Send Byte To Device
      SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cAck\1] ' Get Acknowledge Bit
    RETURN
    Write_Data:                            ' I2C Write Byte Sequence
      i2cWork = temp
      SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork\8] 'Send Byte To Device
      SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cAck\1] ' Get Acknowledge Bit
    RETURN
    ' -----[noparse][[/noparse] BS2P Subroutines ]------------------------------------
      #CASE BS2P, BS2PE, BS2PX
    Write_Byte:
        I2COUT SDA, ChipAddr, MemAddr.HIGHBYTE\MemAddr.LOWBYTE, [noparse][[/noparse]temp]
    RETURN
    Read_Byte:
        I2CIN SDA, ChipAddr+1,MemAddr.HIGHBYTE\MemAddr.LOWBYTE, [noparse][[/noparse]temp]
    RETURN
    #ENDSELECT
    
Sign In or Register to comment.