Shop OBEX P1 Docs P2 Docs Learn Events
How do I read two consecutive 8 bit numbers from EEPROM and combine into a 16 b — Parallax Forums

How do I read two consecutive 8 bit numbers from EEPROM and combine into a 16 b

wmtell1wmtell1 Posts: 14
edited 2009-03-03 22:19 in BASIC Stamp
I attempted to write 12 bit data to a 24LC128 EEPROM A a· few days ago and posted the code with a request for assistance. Mike Green was helpful and informed me that it can't be done. What I would like to do now is
read back the 12 bit number that has been saved to EEPROM as two consecutive 8 bit numers. How do I combine the two 8 bit words to get the origianl vlaue back?

' {$STAMP BS2sx}
' {$PBASIC 2.5}
' {$PORT COM5}
' Purpose...Write a 16 bit word to a 24LC128 EEPROM
'
' =========================================================================
'
'
' Program Description
'
'
'WRITE a 16 bit word via a subroutine to a 24LC128 EEPROM address,
'starting at 1, incrementing by 2 and ending at address 4095.
'Flash an LED ON/OFF to confirm each WRITE cycle.
'
'
'
'
[noparse][[/noparse] I/O Definitions ]
LED PIN 4
SDA PIN 5 ' I2C Serial Data Line
SCL PIN 6 ' I2C Serial Clock Line
'
[noparse][[/noparse] Constants ]
Address CON $A0 ' Address Of 24LC128
Ack CON 0 ' Acknowledge Bit
'
[noparse][[/noparse] Variables ]
temp VAR Word ' Variable Used For Work
i2cWork VAR Word ' Work Byte For I2C I/O
i2cWork1 VAR Word ' Work Byte For I2C I/O
i2cWork2 VAR Word ' Work Byte For I2C I/O
i2cAck VAR Bit ' Ack Bit From Device
eeprom_add VAR Word ' EEPROM Address
J···· VAR········ Nib
'
[noparse][[/noparse] Main Routine ]
FOR temp = 1 TO 4095 STEP 2
· eeprom_add = temp
· GOSUB WriteEE
NEXT 'temp
END
'
[noparse][[/noparse] Subroutines ]
· ' Writing Section
WriteEE:
FOR J = 1 TO 2
· GOSUB I2C_Start
· GOSUB Control_Byte_Write
· GOSUB Addrs
· GOSUB I2C_Write
· GOSUB I2C_Stop
· PAUSE 100
NEXT 'J
RETURN
I2C_Stop: ' I2C Stop Bit Sequence
LOW SDA
INPUT SCL
INPUT SDA ' SDA --> High While SCL High
RETURN
I2C_Start: ' I2C Start Bit Sequence
INPUT SDA
INPUT SCL
LOW SDA ' SDA --> Low While SCL High
RETURN
Control_Byte_Write: ' I2C Control Write Byte Sequence
i2cWork = Address
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
Addrs: ' I2C Address Byte Sequence
i2cWork = eeprom_add· + J - 1
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
I2C_Write: ' I2C Write 2 Byte Sequence
IF J =1 THEN
· i2cWork = temp.LOWBYTE
· HIGH LED
SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork\8] 'Send 8 bits (1 byte) To Device
ELSE
· i2cWork = temp.HIGHBYTE
· LOW LED
SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork\8] 'Send 8 bits To Device
ENDIF
SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cAck\1] ' Get Acknowledge Bit
RETURN
Control_Byte_Read: ' I2C Control Read Byte Sequence
i2cWork = Address
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

Comments

  • Craig EidCraig Eid Posts: 106
    edited 2009-03-03 22:19
    Congratulation on your progress - you are close to getting your answer and need a few modifications to achieve your results. The value saved in EEPROM is an 8 bit word but the Stamp supports 16 bit words and can display the value that you read from EEPROM as a 16 bit word. In your program you would use
    ·[noparse][[/noparse]DEBUG "The 16 bit value of the lower byte of data = ",BIN16 i2cwork1,CR] to display the lower number as a 16 bit binary number and
    ·[noparse][[/noparse]DEBUG "The 16 bit value of the upper byte of data = ",BIN16 i2cwork2,CR] to display the upper number as a 16 bit binary number.

    From the Parallax help file, you can use the [noparse][[/noparse]Shift Left operator (<<)] that shifts the bits of a value to the left a specified number of places. Shift the upper byte of the value by 8 places to the left, add the two 16 bit words and you will recover the original· value

    I have made the modifications listed above to your posted code and kept the displayed range at 1 to 4095 but it can access locations from 0 to 15999 in the 24LC128.

    Craig



    ' {$STAMP BS2sx}
    ' {$PBASIC 2.5}
    ' {$PORT COM5}
    ' Purpose...Read a 16 bit word from a 24LC128 EEPROM
    '
    ' =========================================================================
    '
    '
    ' Program Description
    '
    '
    'Prompt the user to enter an EEPROM address, ranging from 1 to 4095.
    'The upper byte of data is shifted 8 bits to the left, followed
    'by the [noparse][[/noparse]16 bit] addition of the lower byte and the upper byte.
    'The resulting sum and the lower and upper bytes are displayd to
    'the PC via DEBUG in 16 bit binary [noparse][[/noparse]BIN16] format.
    '
    '
    '
    '
    [noparse][[/noparse] I/O Definitions ]
    LED PIN 4
    SDA PIN 5 ' I2C Serial Data Line
    SCL PIN 6 ' I2C Serial Clock Line
    '
    [noparse][[/noparse] Constants ]
    Address··· CON $A0 ' Address Of 24LC128
    Ack······· CON 0 ' Acknowledge Bit
    '
    [noparse][[/noparse] Variables ]
    temp······ VAR Word ' Variable Used For Work
    i2cWork··· VAR Word ' Work Byte For I2C I/O
    i2cWork1·· VAR Word ' Work Byte For I2C I/O
    i2cWork2·· VAR Word ' Work Byte For I2C I/O
    i2cAck···· VAR Bit ' Ack Bit From Device
    eeprom_add VAR Word ' EEPROM Address
    J········· VAR Nib
    '
    [noparse][[/noparse] Main Routine ]
    DO
    · DEBUG "Enter address to read from 1 to 4095: "
    · DEBUGIN DEC5 eeprom_add
    · GOSUB ReadData
    · i2cwork2 = i2cwork2 << 8
    · i2cwork = i2cwork1 + i2cwork2
    · DEBUG "The 16 bit value of the lower byte of data = ",BIN16 i2cwork1,CR
    · DEBUG "The 16 bit value of the upper byte of data = ",BIN16 i2cwork2,CR
    · DEBUG "The 16 bit value of the combined number =··· ",BIN16 i2cwork,CR
    · DEBUG "The decimal value of the combined number =·· ",DEC i2cwork,CR,CR,CR
    LOOP
    'FOR temp = 1 TO 4095 STEP 2
    '· eeprom_add = temp
    '· GOSUB WriteEE
    'NEXT 'temp
    END
    '
    [noparse][[/noparse] Subroutines ]
    · ' Writing Section
    WriteEE:
    FOR J = 1 TO 2
    · GOSUB I2C_Start
    · GOSUB Control_Byte_Write
    · GOSUB Addrs
    · GOSUB I2C_Write
    · GOSUB I2C_Stop
    · PAUSE 100
    NEXT 'J
    RETURN

    I2C_Stop: ' I2C Stop Bit Sequence
    LOW SDA
    INPUT SCL
    INPUT SDA ' SDA --> High While SCL High
    RETURN

    I2C_Start: ' I2C Start Bit Sequence
    INPUT SDA
    INPUT SCL
    LOW SDA ' SDA --> Low While SCL High
    RETURN

    Control_Byte_Write: ' I2C Control Write Byte Sequence
    i2cWork = Address
    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

    Addrs: ' I2C Address Byte Sequence
    i2cWork = eeprom_add· + J - 1
    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

    I2C_Write: ' I2C Write 2 Byte Sequence
    IF J =1 THEN
    · i2cWork = temp.LOWBYTE
    · HIGH LED
    SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork\8] 'Send 8 bits (1 byte) To Device
    ELSE
    · i2cWork = temp.NIB2
    · LOW LED
    DEBUG "temp.NIB2= ",temp.NIB2,CR
    SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork\4] 'Send 4 bits To Device
    ENDIF
    SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cAck\1] ' Get Acknowledge Bit
    RETURN

    Control_Byte_Read: ' I2C Control Read Byte Sequence
    i2cWork = Address
    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

    ReadData:
    ··· 'Reading Section
    FOR J = 1 TO 2
    · GOSUB I2C_Start
    · GOSUB Control_Byte_Write
    · GOSUB Addrs
    · GOSUB I2C_Start
    · GOSUB Control_Byte_Read
    · SHIFTIN SDA, SCL, LSBFIRST, [noparse][[/noparse]i2cwork(J)\8] ' Send Byte To Device
    · GOSUB I2C_Stop
    NEXT 'J
    DEBUG CR, "The low byte stored at location ", DEC eeprom_add,
    " is ", DEC i2cwork1.LOWBYTE," and the high byte stored at location ", DEC (eeprom_add+1),
    " is ", DEC i2cwork2.LOWBYTE, CR
    RETURN

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Craig Eid

    www.TriadRD.com
Sign In or Register to comment.