Here is a little program that drives a LCD as a I2C slave


Code:
                                      *
'*  Version : 1.0                                               *
'*  Notes   : PIC 18F4550                                                  *
'*          :                                                   *
'****************************************************************
define LOADER_USED 1
define RESET_ORG 800h
define INTERRUPT_ORG 808h
DEFINE OSC 48          
      


'**** LCD *******************************************************
'Set LCD Data port
DEFINE LCD_DREG PORTA
'Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_DBIT 0
'Set LCD Register Select port
DEFINE LCD_RSREG PORTA
'Set LCD Register Select bit
DEFINE LCD_RSBIT 4
'Set LCD Enable port
DEFINE LCD_EREG PORTA
'Set LCD Enable bit
DEFINE LCD_EBIT 5
'LCD RW Register PORT
'DEFINE LCD_RWREG PORTB
'LCD read/write pin bit
'DEFINE LCD_RWBIT 5
'Set LCD bus size (4 or 8 bits)
DEFINE LCD_BITS 4
'Set number of lines on LCD
DEFINE LCD_LINES 2
'Set command delay time in us
DEFINE LCD_COMMANDUS 2000
'Set data delay time in us
DEFINE LCD_DATAUS 50
 
' Initialize ports and directions
ADCON1 = $F       'port A digital
CMCON = 7         'PortA Digital 
' PicBasic Pro I2C slave program 
' Alias pins
scl     VAR     PORTB.1         ' I2C clock input
sda     VAR     PORTB.0         ' I2C data input

' Define used register flags
SSPIF   VAR     PIR1.3          ' SSP (I2C) interrupt flag
BF      VAR     SSPSTAT.0       ' SSP (I2C) Buffer Full
R_W     VAR     SSPSTAT.2       ' SSP (I2C) Read/Write
D_A     VAR     SSPSTAT.5       ' SSP (I2C) Data/Address
CKP     VAR     SSPCON1.4        ' SSP (I2C) SCK Release Control
SSPEN   VAR     SSPCON1.5        ' SSP (I2C) Enable
SSPOV   VAR     SSPCON1.6        ' SSP (I2C) Receive Overflow Indicator
WCOL    VAR     SSPCON1.7        ' SSP (I2C) Write Collision Detect

' Define constants
I2Caddress CON	$A2				' Make our address 2

' Allocate RAM
result	VAR		BYTE			' ADC result
datain 	VAR     BYTE			' Data in 
dataout	VAR     BYTE[8]			' Data out array
readcnt	VAR     BYTE            ' I2C read count

        readcnt = 0				' Zero counter

pause 500
lcdout $FE,1,"    I2C LCD"
lcdout $FE,$C0,"     Ready"
trisb = %00000000
portb.0 = 0
portb.1 = 0
TRISB = %11111111
'pause 500

' Initialize I2C slave mode
        SSPADD = I2Caddress		' Set our address
        SSPCON2 = $0 			' General call address disabled
        SSPCON1 = $36 			' Set to I2C slave with 7-bit address
GoTo mainloop 			' Skip over subroutines

i2cslave:						     ' I2C slave subroutine
		SSPIF = 0				     ' Clear interrupt flag
        IF R_W = 1 Then goto i2crd   ' Read data from us
        IF BF = 0 Then goto i2cexit  ' Nothing in buffer so exit
        IF D_A = 1 Then goto i2cwr   ' Data for us (not address)
        IF SSPBUF != I2Caddress Then goto i2cexit	' Clear the address from the buffer
        readcnt = 0				' Mark as first read
        GoTo i2cexit

i2cwr:							' I2C write data to us
        datain = SSPBUF			' Put data into array
        lcdout  datain         
        GoTo i2cexit

i2crd:							' I2C read data from us
        IF D_A = 0 Then
                readcnt = 0		' Mark as first read
        EndIF
        SSPBUF = dataout[readcnt]	' Get data from array
        CKP = 1                 	' Release SCL line
        readcnt = readcnt + 1   	' Move along read count
        GoTo i2cexit            	' That's it
i2cexit:
		Return
 
mainloop:						' Main program loop
        IF SSPIF = 1 Then			' Check for I2C interrupt flag
                GoSub  i2cslave

        EndIF
        GoTo mainloop           ' Do it all forever
I think I found this on this forum.