How do I read two consecutive 8 bit numbers from EEPROM and combine into a 16 b
wmtell1
Posts: 14
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
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
·[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