Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Tcn75a i2c

Status
Not open for further replies.

ARandomOWl

New Member
Hi Guys

I have a TCN75A temperature sensor interfaced to a PIC 18F2458. I am using C18 and it's software I2C library. I can successfully read the MSB of the temperature but the LSB always returns 255. Can anyone see anything wrong with my code?

Link to Pastbin

Thanks.
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
When you read / write I2C the Device sends the ack not you...

Here's My code

Code:
char ReadByte(int Address)
	{
	char Byte;
	SendID(0b10100000);
	if(SendByte(Address>>8)==0)
		return(0);
	if(SendByte(Address&0xff)==0)
		return(0);
	SendRestart();
	if(SendByte(0b10100001)==0)
		return(0);
	Byte=ReceiveByte();
	SendNack();
	SendStop();
	return(Byte);
	}

char SendByte(char Byte)
	{
	SSPBUF=Byte;
	WaitSSP();
	return(!SSPCON2bits.ACKSTAT);
	}

note... send byte returns the recived ack status

This code is for eeprom.... If you want my library you can try it..
 
Last edited:

ARandomOWl

New Member
Thanks, I will look at the function in that code. There is an example in the C18 libraries PDF but I don't understand how it works.

This is it:
Code:
void ack_poll( void )
{
  SWStartI2C();
  var = SWPutcI2C( 0xA0 ); // control byte
  while( SWAckI2C() )
  {
    SWRestartI2C();
    var = SWPutcI2C(0xA0); // data
  }
  SWStopI2C();
}
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
Sorry! Hectic week... SwackI2C() does return the acknowledgement... So the code was correct... Have you tried to read just one byte and then the other in a new read?

Where about's in Manchester are you...
 

ARandomOWl

New Member
Oh, ok. How would I go about doing that? The temperature register is 16 bits long and the pointer register only gives the option to point to that register and not a specific byte.

(Not far from Oldham ;))
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
Reading the data sheet... SEND START (wait for ack).... PUT ADDRESS (wait for ack )...PUT POINTER (wait for ack )...... SEND RESTART (wait for ack).....PUT ADDRESS (w.f.a.)....
READ MSB (YOU send ack).... READ LSB (YOU send ack ) ...... SEND STOP .....

You haven't got a send ack in software.. you'll have to make it... Have a look how Mike Pierce did it....

I live in Oldham....

C:
void i2csendack(void)
{
 //--- Send Ack to slave except for last time ---
 SDA=0;
 SDA_TRIS=I2CLOW;              //-- Send ACK
 i2cdelay(I2CDATASETTLE);      //-- Give it time to settle
 i2cclock();                   //-- Pulse the clock
 SDA_TRIS=I2CHIGH;             //-- Release ACK
 i2cdelay(I2CDATASETTLE);      //-- Gap between next byte
}
//************** END OF i2csendack
 
Last edited:

ARandomOWl

New Member
Ignore the above post. I am back to the original code. I have added in the function in post 8 along with the corresponding "i2cclock" function and called i2csendack after I receive the first byte. I am still receiving 255 for the second byte.
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
Reading the data sheet... SEND START (wait for ack).... PUT ADDRESS (wait for ack )...PUT POINTER (wait for ack )...... SEND RESTART (wait for ack).....PUT ADDRESS (w.f.a.)....
READ MSB (YOU send ack).... READ LSB (YOU send ack ) ...... SEND STOP .....

The read is still not complete... you have to put address then pointer.......RESTART then address then read msb... lsb

I didn't get home until really late last night I'll try and analyse tonight...
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
Right.... The SWgetsI2C(); function gets several bytes in succession.. It generates the required NACK for the transfer..

C:
 unsigned int read_Temp()
 {
     unsigned char data[2];

    SWStartI2C();
    SWWriteI2C(0x90);
    SWAckI2C();
    SWWriteI2C(0);
    SWAckI2C();
    SWRestartI2C();
    SWWriteI2C(0x91);
    SWAckI2C();
    SWGetsI2C(data,2);
    SWStopI2C(); 
    return(data[0] * 256 + data[1]); 
 }

It needs to be something like this
 
Last edited:

ARandomOWl

New Member
Why did I not even consider using that! Thanks! Now I have a meaningful LSB. Although it's only changing between 0 and 128 which maybe means I am not successfully putting it into 12bit mode?
 

ARandomOWl

New Member
Any idea why I have to call the init routine twice for it to work? It's the same even if I leave a large power on delay.
 
Status
Not open for further replies.

EE World Online Articles

Loading
Top