$regfile = "m16def.dat"                                     ' Change for your AVR.
$crystal = 16000000                                         ' 16 MHz Crystal.
$baud = 19200                                               ' Output at 19200 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
Portc = &B0000_0000                                         ' Set All Port Pins Low
Ddrc = &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 = Portc.1                                        ' I2C Data.
Config Scl = Portc.0                                        ' 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 Counters 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
'
Counters = 100                                              ' Initialize loop counter.
I2c_eeprom_address_desired = 0                              ' We start writing at EEPROM address zero.
Do
   Data_work_var = Counters + 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 Counters                                            ' Decrement the loop counter.
Loop Until Counters = 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.
'
Counters = 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: " ; Counters ; "=" ; Data_work_var      ' Display data read from device.
   Incr I2c_eeprom_address_desired                          ' Increment address counter.
   Decr Counters                                            ' Decrement loop counter.
   Waitms 250                                               ' A little delay to watch the numbers go by.
Loop Until Counters = 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