The following is pseudo-code for an I2C driver. It acts only as master, which is probably okay because that's what most people are interested in anyway. I2C uses two bidirectional (OC) lines: clock and data. The maximum bit rate is 100,000 bits/sec but there is no special reason that requires it to be that fast. The master contols the clock line, so processor speed should not be a problem. Devices are accessed using two functions: send_data and read_data. Each device has an 8 bit address, the lowest bit of which is a read/write bit. send_data(address, num_bytes, byte0, byte1, byte2, byte3): // num_bytes = # bytes to transfer // byte0=low order byte // byte3=high order byte Data = Data << (32 - NumBits) make clock and data high wait for clock hi // wait for bus free wait for data hi // generate a 'start' condition // this involves making data go from high to low while // clock is high. Then make clock low to begin transfer. make data low wait make clock low // Send address // the low address bit is read/write, so make it low // for writing byte_out(address & $FE) get_ack // Send and ack each byte if num_bytes > 3 byte_out(byte3) get_ack if num_bytes > 2 byte_out(byte2) get_ack if num_bytes > 1 byte_out(byte1) get_ack byte_out(byte0) get_ack // generate stop condition // this involves making data go from low to high while // clock is high wait make data and clock low wait make clock high wait make data high // that's all return read_data(address,num_bytes, byte0, byte1, byte2, byte3): // num_bytes is a parameter going _in_ to this routine // bytes are same as send_data // make clock and data high wait for clock high wait for data high // generate start condition make data low wait make clock low // send address // this time, make the low order bit '1' to signify read byte_out (address | 1) get_ack if num_bytes>3 byte_in(byte3) do_ack(0) if num_bytes>2 byte_in(byte2) do_ack(0) if num_bytes>1 byte_in(byte1) do_ack(0) byte_in(byte0) do_ack(1) // generate stop condition wait make clock high wait make data high // done return byte_out(byte) // output 'byte' the the I2C bus // this is a primitive routine called by send_data and read_data count=0 loop: wait make clock low make data equal to high bit of 'byte' wait make clock high // device may be holding clock low, so wait here for // clock to actually go high wait for clock to go high shift byte left one bit count++ if count <8 then go to loop make clock and data low return byte_in(byte) // input 'byte' from I2C bus //this is a primitive routine used by send_data and read_data count=0 make data high loop: wait make clock low wait make clock high wait for clock to go high shift byte left one bit and shift in data bit count++ if count < 8 then go to loop get_ack wait make data hi make clock lo wait make data and clock hi wait for clock hi if data is hi then ack failed make clock lo do_ack(bit) make clock low wait make data equal to bit make clock high wait