EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

I2C problem

Started by allanbr08 September 16, 2011
I'm doing a program to ready a temperature from a LM75A temp. sensor IC using I2C protocol but I'm having some problems. The device don't send the acknowledge flag and I don't know what I'm doing wrong. There is my functions to control the I2C bus. I hope someone can help me. I'm using Keil Compiler and my microcontroller is the LPC2138. Thanks

void start(void)
{
I2C0CONCLR = 0x28;
I2C0CONSET = 0x20;
while(I2C0STAT != 0x08);
}

void escreve_end(unsigned int end, unsigned char a)
{
I2C0CONCLR = 0xFF;
I2C0CONSET = 0x40;

if(a == 'w')
{
I2C0DAT = (end << 1);
start();
I2C0CONCLR = 0x28;
while(I2C0STAT!=0x18); //normal 0x18
}

else
{
I2C0DAT = (((end << 1)+1));
start();
I2C0CONCLR = 0x28;
while (I2C0STAT!=0x40); //normal 0x40
}
}

void escreve_pointer(unsigned int point)
{
I2C0CONCLR = 0xFF;
I2C0CONSET = 0x40;
I2C0DAT = point;
start();
I2C0CONCLR = 0x28;
while(I2C0STAT!=0x20);
}

unsigned int read_MSB(void)
{
unsigned int data;

data = I2C0DAT;

while(I2C0STAT!=0x58); //normal 0x50

return data;
}

unsigned int read_LSB(void)
{
unsigned int data;

data = I2C0DAT;

while(I2C0STAT!=0x58);

return data;
}

void stop(void)
{
I2C0CONSET = 0x10;
while(I2C0CONSET!=0x10);
}

An Engineer's Guide to the LPC2100 Series

The one important value you didn't provide is the value of 'end'; a device that isn't properly addressed won't send ACK. As you are shifting it left and appending the R/W bit, the value should be in the range of 0x48..0x4F depending on how the low 3 address bits are strapped. Guessing that they are grounded, 'end' should be 0x48.

You can find sample code at www.jcwren.com/arm and there is also code specific to the LM75. The code is for the LPC2148 and should work perfectly on the LPC2138.

Don't underestimate the value of this code. Every single device within the LPC2148 is coded and the FFS (FAT File System) is implemented on an SD/MMC card. This is GREAT code!

I would probably use pull-up resistors in the range of 2.2k for the clock and data lines.

Richard
--- In l..., "allanbr08" wrote:
>
> I'm doing a program to ready a temperature from a LM75A temp. sensor IC using I2C protocol but I'm having some problems. The device don't send the acknowledge flag and I don't know what I'm doing wrong. There is my functions to control the I2C bus. I hope someone can help me. I'm using Keil Compiler and my microcontroller is the LPC2138. Thanks
>
> void start(void)
> {
> I2C0CONCLR = 0x28;
> I2C0CONSET = 0x20;
> while(I2C0STAT != 0x08);
> }
>
> void escreve_end(unsigned int end, unsigned char a)
> {
> I2C0CONCLR = 0xFF;
> I2C0CONSET = 0x40;
>
> if(a == 'w')
> {
> I2C0DAT = (end << 1);
> start();
> I2C0CONCLR = 0x28;
> while(I2C0STAT!=0x18); //normal 0x18
> }
>
> else
> {
> I2C0DAT = (((end << 1)+1));
> start();
> I2C0CONCLR = 0x28;
> while (I2C0STAT!=0x40); //normal 0x40
> }
> }
>
> void escreve_pointer(unsigned int point)
> {
> I2C0CONCLR = 0xFF;
> I2C0CONSET = 0x40;
> I2C0DAT = point;
> start();
> I2C0CONCLR = 0x28;
> while(I2C0STAT!=0x20);
> }
>
> unsigned int read_MSB(void)
> {
> unsigned int data;
>
> data = I2C0DAT;
>
> while(I2C0STAT!=0x58); //normal 0x50
>
> return data;
> }
>
> unsigned int read_LSB(void)
> {
> unsigned int data;
>
> data = I2C0DAT;
>
> while(I2C0STAT!=0x58);
>
> return data;
> }
>
> void stop(void)
> {
> I2C0CONSET = 0x10;
> while(I2C0CONSET!=0x10);
> }
>

But Im sure that I'm providing the right 'end' value in the main code.
On my board the LM75 have the bits S2=0, S1=0 and S0=0, so Im providing the value 0x49 to 'end' before the shift. Isnt it right? Is there any other problem?

Thanks for your help.

--- In l..., "allanbr08" wrote:
>
> But Im sure that I'm providing the right 'end' value in the main code.
> On my board the LM75 have the bits S2=0, S1=0 and S0=0, so Im providing the value 0x49 to 'end' before the shift. Isnt it right? Is there any other problem?
>
> Thanks for your help.
>

It would seem to me that 'end' would be 0x48 before the shift and would wind up as 0x90 after the shift. Then the R/W* bit would be ORd in to the LSB and the result would be 0x91 to read and 0x90 to write.

Richard


The 2024 Embedded Online Conference