CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Help for the I2C communication!

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Kyaw Kyaw



Joined: 17 Dec 2006
Posts: 15
Location: Singapore

View user's profile Send private message AIM Address MSN Messenger

Help for the I2C communication!
PostPosted: Mon Dec 18, 2006 7:26 pm     Reply with quote

Hi all,
Now I faced the problem with I2C communication between PIC 16F877A and Light sensor. When I read data from sensor, I always get FF(hex) value. My light sensor Acceptable freq is 400KHz (max) and PIC is running with 20MHz (crystal). Can I control the freq for I2C using CCS to solve this problem? Please give me some advices!

Thanks and Best Regards,
Kyaw Kyaw.
_________________
Thanks and Best Regards,
Kyaw Kyaw.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Dec 18, 2006 8:26 pm     Reply with quote

Quote:
My light sensor Acceptable freq is 400KHz (max)
PIC is running with 20MHz (crystal).
Can I control the freq for I2C using CCS to solve this problem?

If you use the hardware i2c pins (C4 and C3) and if you use the
FORCE_HW parameter in the #use i2c() statement, then you can
set the speed of the i2c clock, and it will be reasonably accurate.
If you specify the FAST parameter, then the i2c clock should run
at approximately 400 KHz.

Quote:
When I read data from sensor, I always get FF(hex) value.

However, the i2c clock speed will not be the cause of this problem.
(ie., whether the i2c clock runs at 100 KHz or 400 KHz).

The problem will either be in your i2c driver code for the sensor
or in your hardware. (For example, if you left out the pull-up resistors
on SDA and SCL). Post the manufacturer and part number of your
light sensor chip.
Kyaw Kyaw



Joined: 17 Dec 2006
Posts: 15
Location: Singapore

View user's profile Send private message AIM Address MSN Messenger

my Light Sensor ID and Codes
PostPosted: Mon Dec 18, 2006 8:39 pm     Reply with quote

Hi PWM programmer,

I don't know how to set the clk freq in I2C mode. Could you kindly show me how to set the freq please?

My light sensor I tried to communicate with PIC is ISL 29001. And below one is the simple program using to test the communication.

#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600,xmit=PIN_B0,rcv=PIN_B5)
#use i2c(master,sda=Pin_C4, scl=Pin_C3) //Configure Device as Master
//============================
byte data1;
byte data2;

VOID main()
{
WHILE(1)
{
prINTf ("\n\rHello World\n\r");

i2c_start();
i2c_write(0x44); // Send the ISL29001 address
i2c_write(0x30); // Set internally timed
delay_ms(20);

i2c_start();
data1=i2c_read();
data2=i2c_read();
i2c_stop();
printf ("\n\r data1 value1 is %x",data1);
printf ("\n\r data1 value2 is %x",data2);

delay_ms (1000);

}
}
_________________
Thanks and Best Regards,
Kyaw Kyaw.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 19, 2006 1:11 am     Reply with quote

Here are two driver functions and a demo program for the ISL29001.
I don't have the hardware to test, but this code should probably work.

According to the ISL29001 data sheet, you should run the chip with
a Vdd of +3.3v (typically). The i2c pins are 5v tolerant, so you can
connect the i2c pull-up resistors to 5v, and connect it to a PIC which
is running from a +5v power supply. (This is explained in the Pin
Descriptions section on page 3 of the data sheet).

The ISL29001 data sheet has a sample schematic on page 10, which
shows the external components required. You can use 4.7K resistors
for the i2c pull-ups.
Code:

#include <16F877A.H>
#fuses HS, NOWDT, PROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3, FORCE_HW)

#define ISL29001_I2C_WRITE_ADDR  0x88
#define ISL29001_I2C_READ_ADDR   0x89

//---------------------------------------
void isl29001_write_command(int8 command)
{
i2c_start();
i2c_write(ISL29001_I2C_WRITE_ADDR);
i2c_write(command);
i2c_stop();
}

//---------------------------------------
// Do an A/D conversion on the specified diode
// (0 or 1) and return the unsigned 16-bit result.
// Use the internal timing mode.

int16 isl29001_read_diode(int8 diode)
{
int8 command;
int8 lsb;
int8 msb;
int16 retval;
 
// Convert the diode value of 0 or 1
// to the command value of 0 or 4.
command = (diode & 1)  << 2;

// Send the command.
i2c_start();
i2c_write(ISL29001_I2C_WRITE_ADDR);
i2c_write(command);
i2c_stop();

// Wait for conversion time.
delay_ms(125);   

// Read the 16-bit result.
i2c_start();
i2c_write(ISL29001_I2C_READ_ADDR);
lsb = i2c_read();
msb = i2c_read(0);
i2c_stop();

// Combine lsb and msb into a 16-bit value.
retval = make16(msb, lsb);

return(retval);
}
   
//===============================
void main()
{
int16 result;

     
while(1)
  {
   result = isl29001_read_diode(0);
   printf("Diode 0:  %LX\n\r");
   
   result = isl29001_read_diode(1);
   printf("Diode 1:  %LX\n\r");
 
   delay_ms(250);
  }
     
}     
Kyaw Kyaw



Joined: 17 Dec 2006
Posts: 15
Location: Singapore

View user's profile Send private message AIM Address MSN Messenger

Hi PWM Programmer
PostPosted: Tue Dec 19, 2006 3:43 am     Reply with quote

Hi,
I tried to burn ur program and run it but still not change the value from FFFF. Could you please show me how to set the clk freq for communication? I don't know how to change the clk freq for I2C mode. Thanks for your supports and solution.

Thanks and Best Regards,
Kyaw Kyaw.
_________________
Thanks and Best Regards,
Kyaw Kyaw.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 19, 2006 1:16 pm     Reply with quote

Quote:
I don't know how to change the clk freq for I2C mode.

You can do it like this:
Code:
#use i2c(Master, SDA=PIN_C4, SCL=PIN_C3, FORCE_HW, FAST=300000)

Specify FORCE_HW, and then specify the i2c clock speed with the
FAST statement. In the example above, I have specified 300 KHz.

If you use "FAST" with no speed parameter, it defaults to 400 KHz.
Example:
Code:
#use i2c(Master, SDA=PIN_C4, SCL=PIN_C3, FORCE_HW, FAST)


However, you think that changing the i2c clock speed from 100 KHz
to 400 KHz will magically fix the problem with reading FF's. I don't
think that's going to happen. It could be that there's a problem in
my driver (since I don't have a hardware chip to test), but I think
there is likely a problem in your hardware connections.
jds-pic



Joined: 17 Sep 2003
Posts: 205

View user's profile Send private message

PostPosted: Tue Dec 19, 2006 1:18 pm     Reply with quote

Kyaw Kyaw wrote:
Hi,
Could you please show me how to set the clk freq for communication? I don't know how to change the clk freq for I2C mode.


the i2c bus normally runs at either 100KHz (STD mode) or 400KHz (FAST mode).

within CCS you don't explicitly set a clock frequency; the i2c driver defaults to STD unless you specify FAST in the #use_i2c directive.

do you have a 'scope that you can put onto SCL and SDA to see if ANY data is going back and forth between the PIC and the client IC?

jds-pic
Ttelmah
Guest







PostPosted: Tue Dec 19, 2006 4:07 pm     Reply with quote

First check that you are usig the right address. PCM_programmer, has the right address. The address is 0x44, with then the read/write bit added below this, so it ends up being multiplied by two for sending to the chip.
Your code would not work, if the address was right, since you never set the chip to return data.
PCM_programmers functions look right. Try using the command write function to set the mode you want, and then his read function.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 19, 2006 4:45 pm     Reply with quote

I'm assuming that he only wants to read the two diodes, so I have
the code to send the command, placed within the "read diodes" function.

I'm not sure what the state of the ISL29001 chip is, upon power-up.
It's possible that it comes up in the "power down" state. The data sheet
isn't clear on this. It might be that you have to send the "Reset"
command to remove the "power down" state, before you can talk to
the chip with i2c.

Also, the schematic on page 10 of the data sheet shows that you have
to connect the Power Down pin to ground. (The chip can be put in
a power-down state either by a software command or a hardware pin).
If any of those pins are not connected correctly, the result might be
to read all FF's back.
http://www.intersil.com/data/fn/FN6166.pdf
Kyaw Kyaw



Joined: 17 Dec 2006
Posts: 15
Location: Singapore

View user's profile Send private message AIM Address MSN Messenger

Thank for ur supports
PostPosted: Tue Dec 19, 2006 7:31 pm     Reply with quote

Hi all,
Thanks for ur supports. But now i try to run with PWM Programmer's code and i made all the setting correctly according to the schematic shown in the ISL 29001 datasheet. Actually I want is to get the Diode1 Data only because I want the light intensity value for control. Could you please make a check for the timming diagram of ISL 29001 included in page 6 of datasheet? I think we need to make acknowledge after sending the device address (0x44 + Read/Write) and after power down command. Thanks for consideration of my problem.

It may be the fault of my IC ISL 29001 because it is too small and I mounted in socket PCBvia soldering. But I check with the camera to see whether it is connected proprely to the socket PCB or not. I didn't see any fault.

Thanks and Best Regards,
Kyaw Kyaw.
_________________
Thanks and Best Regards,
Kyaw Kyaw.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 19, 2006 8:42 pm     Reply with quote

Quote:

I think we need to make acknowledge after sending the device address
(0x44 + Read/Write) and after power down command.

The slave device (the ISL29001) does an ACK to show the master (PIC)
that it has received the address byte. We don't need to add any code
to handle this.

Quote:
(0x44 + Read/Write)

This part is disturbing. Are you using the code that I posted, with
the address of 0x88, or did you change it to 0x44 ? It must be 0x88
for a write and 0x89 for a read operation.

Quote:
and after power down command

This comment is even more disturbing. Are you sending the ISL29001
a power-down command ? If so, why ?

You should follow the example code that I posted. Don't change the
i2c address. Don't send a power-down command to the ISL29001.

Also, I have a moderate belief that the chip is not connected correctly
or was damaged during soldering.
Kyaw Kyaw



Joined: 17 Dec 2006
Posts: 15
Location: Singapore

View user's profile Send private message AIM Address MSN Messenger

Reply
PostPosted: Tue Dec 19, 2006 9:39 pm     Reply with quote

Hi PWM programmer,
I didn't change anything except the PIN Assignement for RS 232 mode because I used B0 and B5 to communication with computer. The rests are still the same as u made, even the ISL 29001 address (0x88 for read and 0x89 for write) commands. Unfortunately it still show FFFF (hex) for data reading. I also tried to send power down mode (0x8c) after sending the write address command. At that time it didn't show anything even the data value of FFFF(hex) or sample sentence. I also suspect on the IC soldering. This IC is very tiny one and I also try my best to solder it. Do you have any idea for power down mode. Thanks for ur support and considering my problem. Below is the code i tried to test.

#include <16F877A>
#fuses HS, NOWDT, PROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_B0, rcv=PIN_B5)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3, FORCE_HW)


int16 result=0;

VOID main()
{
WHILE(1)
{
prINTf ("\n\rHello World Testing ISL 29001\n\r");

i2c_start();
i2c_write(0x88); // Send the ISL29001 address
i2c_write(0x8c); // send power down signal
i2c_write(0x30); // Set internally timed
i2c_stop();
delay_ms(2500);

i2c_start();
i2c_write(0x89);
result=i2c_read();
i2c_stop();
printf ("\n\r data1 value1 is %x\n\r",result);

delay_ms (1000);

}
}
_________________
Thanks and Best Regards,
Kyaw Kyaw.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 19, 2006 10:30 pm     Reply with quote

You're not following my sample driver. You are inventing stuff.
I give up.
Kyaw Kyaw



Joined: 17 Dec 2006
Posts: 15
Location: Singapore

View user's profile Send private message AIM Address MSN Messenger

hi pwm programmer
PostPosted: Tue Dec 19, 2006 11:20 pm     Reply with quote

i also tried with ur program also. but still cannot get the result. that why i tried to use this program.

thanks & best regards,
kyaw kyaw.
_________________
Thanks and Best Regards,
Kyaw Kyaw.
Kyaw Kyaw



Joined: 17 Dec 2006
Posts: 15
Location: Singapore

View user's profile Send private message AIM Address MSN Messenger

It is IC's fault!
PostPosted: Thu Dec 21, 2006 2:44 am     Reply with quote

Hi all, Today i tried to see the sda and scl pin outputs with scope and i found that it is working according to the timing diagram of ISL 29001 but still got FFFF hex and it was not included the 30 hex for writing to ISL29001. I tested with PWM Programmer's codes. It should be the ISL29001's defect. Thanks for helping me to solving my difficulties. Smile Smile
_________________
Thanks and Best Regards,
Kyaw Kyaw.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group