This program tests every valid 8bit write address connected to the I2C bus.
- Confirms you have your connections correct
- Confirms your pull-ups are correct
- Tells you what your I2C address is.

I hope this is useful to people
Regards
TimC

Code:
' I2C Scanner to find devices on I2C Bus
' If a I2C device is functional it will return it's address 
' Tim 3/29/04 

DEFINE LOADER_USER 1   ' Boot-Loader is being used
DEFINE OSC 20          ' Change to your chip

DEFINE HSER_BAUD	9600	' override the default of 2400

SDA     VAR		portc.4		' change if needed
SCL     VAR		portc.3		' change if needed
LED		VAR		portd.1		' change if needed				
i2c_out VAR		BYTE        ' dummy data to sent over I2C bus
i2c_ack VAR		BIT         'acknowledgement bit


main:

    CMCON = 7   ' disable the analog comparator  your chip may be different
	pause 500	' just because we don't know what we are pinging
    HSEROUT [" *** Start I2C Ping ***",13,10] ' announce
looper:
    for i2c_out = 2 to $fe	step 2	' Remove step to find both reading and writing address.
        gosub I2c_Ping
        if i2c_ack = 0 then
           HSEROUT ["$",hex2 i2c_out, " "] '
           gosub heartbeat	' just in case there is no serial port
        endif
    next i2c_out
    HSEROUT [13,10," *** Fini I2C Ping ***",13,10] ' say we are done
End
'**********************************************************************************
'                           Subs
'**********************************************************************************
I2C_Ping:          'Start Conversion
    GOSUB I2C_START
    'i2c_out = %10010000 'Send Address, (device= %1001, A0= 0, A1= 0, A2= 0, R/W= 0)
    GOSUB I2C_TX
    GOSUB I2C_STOP
    RETURN

I2C_TX:                           'I2C transmit -> send data to the slave
    i2c_ack = 1                   'ACK bit will change to 0 if device is found
    SHIFTOUT SDA,SCL,1,[i2c_out]  'Shift out “i2c_out” MSBfirst
    SHIFTIN SDA,SCL,0,[i2c_ack\1] 'Receive ACK bit
    RETURN

I2C_START:              'I2C start (start communication on I2C bus)
    HIGH SDA
    HIGH SCL
    LOW SDA
    LOW SCL
    RETURN

I2C_STOP:               'I2C stop (terminate communication on I2C bus)
    LOW SDA
    HIGH SCL
    HIGH SDA
    PAUSE 1
    RETURN


' Subroutine to blink a pin for heartbeat
heartbeat:
        high LED        ' turn on led no tris needed
        pause 100       ' for .1 seconds
        low LED         ' turn off led
        pause 500       ' for .5 seconds
        return
Output should look like this:

Code:
 *** Start I2C Ping ***
$78 
 *** Fini I2C Ping ***
If you have more than one device you will see more addresses.

Regards
TimC