Hello, referencing I2C_out() and I2C_in() from Don Bindner's code. I created the function below called pH_info. Notice my last I2C_in() byte read I use an argument of "0" to receive the ACK. If you need an ACK you need to pull down the data line first. Disclaimer: It has been awhile since I used this code, but I remember it working great.
/* Outputs 8-bit command or data via I2C lines. */ void I2C_out(unsigned char d) { int n;
for( n = 0; n < 8; n++ ) {
if( d & 0x80 ) {
data_high();
} else {
data_low();
}
clk_high();
clk_low();
d <<= 1; // Shift next bit into position.
}
data_read(); // Set data line to receive.
clk_high(); // Clock goes high to wait for acknowledge.
// Slave will pull data line low to acknowledge.
while( P1IN & I2C_SDA ) {
// Else toggle the clock line and check again
clk_low();
clk_high();
}
clk_low();
}
/* Inputs 8-bit data from slave, with or without acknowledgement. */ unsigned char I2C_in(int ack) { int n; unsigned char byte = 0;
data_read(); // Float line to read bits.
for( n = 0; n < 8; n++ ) {
byte <<= 1; // Shift bits over to make room for new bit.
clk_high();
if( data_pulled_up()) {
byte |= 1; // Slave sent a 1.
}
clk_low();
}
/* If we need to acknowledge, we'll pull down the data line. */
if( ack ) {
data_low();
}
clk_high();
clk_low();
return byte;
}
/This function sends a request for info to the I2C pH circuit and reads back the information data/ void pH_info(void) { I2C_Start(); I2C_out(0xC6); //Write address of I2C slave I2C_out(0x49); //ASCII 'L' I2C_Stop();
delay(1000);
I2C_Start();
I2C_out(0xC7); //Read address of I2C slave
rxdata[0]=I2C_in(1);
rxdata[1]=I2C_in(1);
rxdata[2]=I2C_in(1);
rxdata[3]=I2C_in(1);
rxdata[4]=I2C_in(1);
rxdata[5]=I2C_in(1);
rxdata[6]=I2C_in(1);
rxdata[7]=I2C_in(1);
rxdata[8]=I2C_in(1);
rxdata[9]=I2C_in(1);
rxdata[10]=I2C_in(0);
}