understanding EEPROM Addressing
I am using A 24C02 EEPROM with a SX28
the A2,A1,A0 pins are hard wired to VCC
I used the I2C help and examples to come up with this code. and all is fine, I can write and read to and from the EEPROM.
My example writes the value 25 to memory locarion 256. and then reades it back
( I am also using a LCD display but omitted that code to make the post shorter)
My question is?
When I write to the EEPROM I have to use an Address (Addr) of 256 or larger. WHY? Is this because I have A2,A1,A0 hard wired to VCC or have I done something else wrong and missed it
Thanks
Mike
'
DEVICE SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
FREQ 4_000_000
'
' IO Pins
'
Serial_Data PIN RA.0 INPUT ' SDA
Serial_Clock PIN RA.1 INPUT ' SCL
'
' Constants
'
SlaveID CON %10101110 ' for 24C02 A0,A1,A2 hard wired high (174 $AE)
Ack CON 0 ' Control Protocol to acknowledge receipt
Nak CON 1 ' negative acknowledgment or not acknowledged
Addr CON $100 ' Word Address in 24C02 256 or larger
'
' Variables
'
flags VAR Byte ' flag for read or write eight bit
ackVal VAR flags.0 ' ackVal bit.0, (0 = write 1 = read)
tmpB1 VAR BYTE ' work vars
tmpB2 VAR BYTE '
tmpB3 VAR BYTE '
tmpW1 VAR WORD '
' =========================================================================
PROGRAM Start
' =========================================================================
'
' Subroutine Declarations
'
DEVICE_WRITE SUB 3 ' write value to memory
DEVICE_READ FUNC 1, 2 ' read byte from memory
I2C_IN FUNC 1, 1 ' read byte from Serial_Data
I2C_START SUB 0 ' generate I2C Start
I2C_STOP SUB 0 ' generate I2C Stop
I2C_OUT SUB 1, 1 ' write byte to Serial_Data
'
' Program Code
'
Start:
Main:
tmpB2 = 25
Device_Write Addr, tmpB2 write 25 to address 256
(more code Here)
tmpB2 = Device_Read Addr ' read from 24C02
END
'
' Subroutines Code
'
'
SUB DEVICE_WRITE
tmpW1 = __WPARAM12 ' copy Address
tmpB1 = __PARAM3 ' copy value
I2C_START
tmpW1_MSB = tmpW1_MSB & $03 ' get block value
tmpW1_MSB = tmpW1_MSB << 1
tmpW1_MSB = tmpW1_MSB | SlaveID ' create control byte
tmpW1_MSB.0 = 0 ' set RW bit for write
I2C_OUT tmpW1_MSB ' send slave ID
I2C_OUT tmpW1_LSB ' send word Address
I2C_OUT tmpB1 ' send data byte
I2C_STOP ' finish
DO ' let write cycle finish
I2C_START
I2C_OUT tmpW1_MSB ' resend slave ID
LOOP UNTIL ackVal = Ack
ENDSUB
'
FUNC DEVICE_READ
tmpW1 = __WPARAM12 ' copy Address
I2C_START
tmpW1_MSB = tmpW1_MSB & $03 ' get block value
tmpW1_MSB = tmpW1_MSB << 1
tmpW1_MSB = tmpW1_MSB | SlaveID ' create control byte
tmpW1_MSB.0 = 0 ' set RW bit for write
I2C_OUT tmpW1_MSB ' send slave ID
I2C_OUT tmpW1_LSB ' send word Address
I2C_START ' restart for read
tmpW1_MSB.0 = 1 ' set RW bit for Read
I2C_OUT tmpW1_MSB '
tmpB1 = I2C_IN Nak '
I2C_STOP '
RETURN tmpB1
ENDFUNC
'
SUB I2C_START '
I2CSTART Serial_Data '
ENDSUB
'
SUB I2C_STOP '
I2CSTOP Serial_Data '
ENDSUB
'
SUB I2C_OUT '
I2CSEND Serial_Data, __PARAM1, ackVal '
ENDSUB
'
FUNC I2C_IN '
ackVal = __PARAM1.0 '
I2CRECV Serial_Data, tmpB3, ackVal '
RETURN tmpB3 '
ENDFUNC
'
Comments
You're making it too hard. You just just need to send the ID, then the address. The example used an EEPROM that had an odd addressing scheme.
Bean.
Post Edited By Moderator (Chris Savage (Parallax)) : 11/2/2007 3:41:11 PM GMT