i2c EEPROM addressing

Hey guys,

I'm wanting to use a 4Kbit i2c EEPROM for storage of ASCII art data. Looking at the datasheet (mine is the M24C04 version), the memory addressing seems to work on a 9-bit system, where the LSB of the 7-bit address forms the MSB of the memory address. I'm just wondering about how to implement this on the PICAXE?

Would I have to set the device address in the hi2cin command (X2 part) as 1010aaX, where X represents the MSB of the memory address being read, or would the compiler do this automatically?

If the former is the case, would this sample code work? My "actual" range for memory addresses woud be 0 - 490, giving a little leeway :)

Code:
symbol w0 = startAddress
symbol b2 = deviceAddy
symbol b3 = memoryAddy

symbol defAddy = %10100000                                ;sets constant for the default address

hi2csetup i2cmaster, deviceAddy, i2cslow_16, i2cbyte    ;Configure i2c module in Master Mode, slow transfer speed (fast not required; 16MHz), byte addressing. Default address to read/write from: %10100000
                                                        ;Note - startAddress shall never be above 512
deviceAddy = defAddy | b1                                ;mask device address with MSB of w0
memoryAddy = b3

hi2cin deviceAddy, memoryAddy, (b4, b5, b6, b7, b8)
 

hippy

Technical Support
Staff member
Would I have to set the device address in the hi2cin command (X2 part) as 1010aaX, where X represents the MSB of the memory address being read, or would the compiler do this automatically?
You have to do it manually. The M24C04 is a 4Kb / 512 byte EEPROM, but, because it's byte addressed, it's easier to think of it as two separate EEPROM's with Device Addresses of $A0 and $A2.

Thus, if you want to access the EEPROM contiguously you need to select the EEPROM to use. For example, showing all 512 bytes of data held in the EEPROM, which is pretty similar to what you have -
Code:
Symbol adr       = w1 ; b3:b2
Symbol adr.lsb   = b2
Symbol adr.msb   = b3

Symbol deviceAdr = b4

Symbol dat       = b5

For adr = 0 To 511
  deviceAdr = adr.msb * 2 | $A0
  HI2cSetup I2CMASTER, deviceAdr, I2CSLOW, I2CBYTE
  HI2cIn adr.lsb, ( dat )
  SerTxd( "EEPROM[", #adr, "] = ", #dat, CR, LF )
Next
On the X2 chips there is another way of doing things; where the Device Address can be specified as part of the HI2CIN and HI2COUT commands. I am not sure it really has much advantage over the above -
Code:
HI2cSetup I2CMASTER, $A0, I2CSLOW, I2CBYTE
For adr = 0 To 511
  deviceAdr = adr.msb * 2 | $A0
  HI2cIn [ deviceAdr ], adr.lsb, ( dat )
  SerTxd( "EEPROM[", #adr, "] = ", #dat, CR, LF )
Next
You should be able to avoid defining the .msb and .lsb parts using the following, though I haven't actually tested this -
Code:
Symbol adr       = w1 ; b3:b2
Symbol deviceAdr = b4
Symbol dat       = b5

For adr = 0 To 511
  deviceAdr = adr / $80 & 2 | $A0
  HI2cSetup I2CMASTER, deviceAdr, I2CSLOW, I2CBYTE
  HI2cIn adr, ( dat )
  SerTxd( "EEPROM[", #adr, "] = ", #dat, CR, LF )
Next
 
Last edited:
You have to do it manually. The M24C04 is a 4Kb / 512 byte EEPROM, but, because it's byte addressed, it's easier to think of it as two separate EEPROM's with Device Addresses of $A0 and $A2.

Thus, if you want to access the EEPROM contiguously you need to select the EEPROM to use. For example, showing all 512 bytes of data held in the EEPROM, which is pretty similar to what you have -
Code:
Symbol adr       = w1 ; b3:b2
Symbol adr.lsb   = b2
Symbol adr.msb   = b3

Symbol deviceAdr = b4

Symbol dat       = b5

For adr = 0 To 511
  deviceAdr = adr.msb * 2 | $A0
  HI2cSetup I2CMASTER, deviceAdr, I2CSLOW, I2CBYTE
  HI2cIn adr.lsb, ( dat )
  SerTxd( "EEPROM[", #adr, "] = ", #dat, CR, LF )
Next
On the X2 chips there is another way of doing things; where the Device Address can be specified as part of the HI2CIN and HI2COUT commands. I am not sure it really has much advantage over the above -
Code:
HI2cSetup I2CMASTER, $A0, I2CSLOW, I2CBYTE
For adr = 0 To 511
  deviceAdr = adr.msb * 2 | $A0
  HI2cIn [ deviceAdr ], adr.lsb, ( dat )
  SerTxd( "EEPROM[", #adr, "] = ", #dat, CR, LF )
Next
You should be able to avoid defining the .msb and .lsb parts using the following, though I haven't actually tested this -
Code:
Symbol adr       = w1 ; b3:b2
Symbol deviceAdr = b4
Symbol dat       = b5

For adr = 0 To 511
  deviceAdr = adr / $80 & 2 | $A0
  HI2cSetup I2CMASTER, deviceAdr, I2CSLOW, I2CBYTE
  HI2cIn adr, ( dat )
  SerTxd( "EEPROM[", #adr, "] = ", #dat, CR, LF )
Next
That's perfect - I tested this earlier, and it seems to work :D hurray for | !
 
Top