I2C EEPROM Example and Test Program by Victoria Welch.

This application note was written by Victoria Welch from code supplied by Brent Nelson.

Download the zipped file or copy / paste from below.

The zip file contains the following code and a schematic which may be useful to assemble a test circuit for this program.

'**********************************************************************
' Application Note: 16 Bit Addressing on the I2C Bus.
' (8 bit data transfers one byte at a time)
'-----------------------------------------------------
'
' Program-ID.:  I2C_EEPROM.bas.
' Date...... :  04 / 04 / 2002
' Description:  Example program for I2c EEprom write and read routines
'
' Author :  Victoria Welch (vikki@oz.net).
'    This program finally helped me get my 24LC64 EEPROM working.
'    Many thanks Brent!  I Converted the original program into an
'    application note in the hope it helps others new to these devices.
'
' Brent Nelson (spock50@gte.net).
'    Brent provided the orginal form of this program to the BASCOM list.
'
' Remarks:
' Setup for the AT90S2313 using portb.0 for SDA and Portb.1 for SCL.
'
' Uses onboard serial port.
'
' This program provides an example for writing to and reading from
' an I2C EEPROM device wired for device 0 (AO,A1 and A2 all pulled
' to Gnd).
'
' This has been tested with a Microchip 24LC65.
'
'**********************************************************************
$regfile = "2313def.dat"                                    ' Change for your AVR.
$crystal = 4000000                                          ' 4 MHz Crystal.
$baud = 9600                                                ' Output at 9600 baud.

'**********************************************************************
'** Set up Data Direction Registers and ports - Do this before defining I2C pins!
'** Read up on this in the data sheet, understanding is important!
'**********************************************************************
' Port B
Portb = &B0000_0000                                         ' Set All Port Pins Low
Ddrb = &B1111_1100                                          ' Set Unused Pins As Outputs. Set I2C pins as inputs (tri-state- floating)
' Port D
Portd = &B0000_0000                                         ' All low - with push-pull output
Ddrd = &B1111_1111                                          ' with internal pullups.

'**********************************************************************
'** Define and initialize I2C pins                                   **
'**********************************************************************
Config Sda = Portb.0                                        ' I2C Data.
Config Scl = Portb.1                                        ' I2C Clock.

'**********************************************************************
'** Declate subroutines                                              **
'**********************************************************************
'
' This subroutine writes data to the I2C EEPROM.
'
Declare Sub I2c_ram_write(address_desired As Word , Content As Byte)
'
' This subroutine reads data from the I2C EEPROM.
'
Declare Sub I2c_ram_read(address_desired As Word)

'**********************************************************************
'** Define working variables and constants                           **
'**********************************************************************
Dim I2c_eeprom_address_desired As Word                      ' I2C EEPROM address counter (provides for 65536 locations).
Dim I2c_eeprom_address_high_byte As Byte                    ' High byte of EEPROM address.
Dim I2c_eeprom_address_low_byte As Byte                     ' Low byte of EEPROM address.
Dim Data_work_var As Byte                                   ' Working variables.
Dim Counter As Byte
'
' Change the 3 "AD" bits to reflect the I2C address of the device
' (corresponding to A0,A1 and A2)..
'                                    FAM AD M
Const Eeprom_chip_write_command = &B10100000                ' Family "A", Device/unit 1, write.
Const Eeprom_chip_read_command = &B10100001                 ' Family "A", Device/unit 1, Read.

'**********************************************************************
'** Actual work starts here.                                         **
'**********************************************************************
Main:
Print "I2C EEPROM Test Program."                            ' Just a header for separation.
'
' First we write data to the EEPROM: 150 to 51
'
Counter = 100                                               ' Initialize loop counter.
I2c_eeprom_address_desired = 0                              ' We start writing at EEPROM address zero.
Do
   Data_work_var = Counter + 50                             ' Generate test data (=0<256).
   Call I2c_ram_write(i2c_eeprom_address_desired , Data_work_var)       ' Write it to the EEPROM.
   Incr I2c_eeprom_address_desired                          ' Increment EEPROM address location desired.
   Decr Counter                                             ' Decrement the loop counter.
Loop Until Counter = 0
Print "All locations written to."                           ' Tell what is going on.
'
' Now we read that data back.  If returned data is all 255s check your circuit.
'
Counter = 100                                               ' initialize loop counter.
I2c_eeprom_address_desired = 0                              ' We start reading at EEPROM address zero.
Do
   Call I2c_ram_read(i2c_eeprom_address_desired)            ' Call sub to read from device.
   Print "Location: " ; Counter ; "=" ; Data_work_var       ' Display data read from device.
   Incr I2c_eeprom_address_desired                          ' Increment address counter.
   Decr Counter                                             ' Decrement loop counter.
   Waitms 250                                               ' A little delay to watch the numbers go by.
Loop Until Counter = 0
Print "All locations read back, program ends."              ' Tell what is going on.
End                                                         ' Program ends.
'**********************************************************************
'**                        Define Subroutines                        **
'**********************************************************************
Sub I2c_ram_write(address_desired As Word , Content As Byte)       ' Writes data to the I2C EEPROM.
   I2c_eeprom_address_low_byte = Low(address_desired)       ' Extract low byte of address to be written.
   I2c_eeprom_address_high_byte = High(address_desired)     ' Extract high byte of addesss to be written.
   I2cstart                                                 ' Send I2C Start.
   I2cwbyte Eeprom_chip_write_command                       ' Select MicroChip EEPROM device type, address and write bit.
   I2cwbyte I2c_eeprom_address_high_byte                    ' Send high address to write to.
   I2cwbyte I2c_eeprom_address_low_byte                     ' Send low address to write to.
   I2cwbyte Content                                         ' Send the data to be written.
   If Err = 0 Then                                          ' check status of operation.
      Print "Write is good: Location: " ; Address_desired   ' Report success.
   Else                                                     ' or
      Print "Write failed: Location: " ; Address_desired    ' Report failure.
   End If
   I2cstop                                                  ' All we want to do is done.
   Waitms 10                                                ' Wait for write to finish up.
End Sub

Sub I2c_ram_read(address_desired As Word)                   ' Reads data from the I2C EEPROM.
   I2c_eeprom_address_low_byte = Low(address_desired)       ' Extract low byte of address to be read.
   I2c_eeprom_address_high_byte = High(address_desired)     ' Extract high byte of address to be read.
   I2cstart                                                 ' Send I2C Start..
   I2cwbyte Eeprom_chip_write_command                       ' Select MicroChip EEPROM device type, address and write bit
   I2cwbyte I2c_eeprom_address_high_byte                    ' Send high byte of address to read from.
   I2cwbyte I2c_eeprom_address_low_byte                     ' Send low byte of address to read from.
   I2cstart                                                 ' Issue another start sequence.
   I2cwbyte Eeprom_chip_read_command                        ' Select MicroChip EEPROM device type, address and read bit
   I2crbyte Data_work_var , Nack                            ' Read data from desired location in chip.
   If Err = 0 Then                                          ' Check status of operation.
      Print "Read is good: " ;                              ' Report success.
   Else                                                     ' or
      Print "Read failed: " ;                               ' Reeort failure.0
   End If
   I2cstop                                                  ' All we want to do is done.
End Sub
Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: March 31, 2002