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 support@ccsinfo.com

Compiling problem with I2C

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



Joined: 22 Aug 2008
Posts: 21

View user's profile Send private message

Compiling problem with I2C
PostPosted: Wed Feb 04, 2009 12:13 pm     Reply with quote

HI,
I'm trying to use the I2C port to communicate with a slave. But I get a compiler error with a build in function. My code looks like this :
Code:
#use I2C(MASTER, FORCE_HW, SLOW)

main
{
int8 i;
int8 buffer[6];
while(1){
RdData(6);               
}
}

void RdData(int8 NbBytes)
{
   int8 iBuffer;
   iBuffer=0;
   i2c_start();                // Start condition
   i2c_write(COMPASSADDR|0x01);   
   while(iBuffer!=NbBytes) {
      while(!i2c_poll()) ;
      Buffer[iBuffer++]= i2c_read();
   }
   i2c_stop();
}

and I get the error message:
Quote:
*** Error 12 "compass.c" Line 162(16,17): Undefined identifier -- i2c_poll

I can't see why the compiler doesn't find the i2c_poll() function?

Can you help?/
thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Feb 04, 2009 12:41 pm     Reply with quote

Always post your PIC and compiler version.
JacquesB



Joined: 22 Aug 2008
Posts: 21

View user's profile Send private message

PostPosted: Wed Feb 04, 2009 12:44 pm     Reply with quote

Sorry,
It compiles for PIC18F2525 and use compiler PCH 4.071
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Feb 04, 2009 1:02 pm     Reply with quote

You need to specify the pins that are used for SDA and SCL.
Add that to your #use i2c statement. Use the hardware i2c pins.
Look at the pin diagram in the PIC data sheet to find them.
JacquesB



Joined: 22 Aug 2008
Posts: 21

View user's profile Send private message

PostPosted: Wed Feb 04, 2009 1:29 pm     Reply with quote

I thought that by specifying FORCE_HW I didn't have to also specify the real pins.

I replaced :
Code:
#use I2C(MASTER, FORCE_HW, SLOW, STREAM=COMPASS )

with :
Code:
#use I2C(MASTER, SCL= PIN_C3, SDA=PIN_C4,FORCE_HW, SLOW)

and it compiled OK

thanks for the hint !
JacquesB



Joined: 22 Aug 2008
Posts: 21

View user's profile Send private message

Detection of slave
PostPosted: Fri Feb 06, 2009 12:46 pm     Reply with quote

Hi,
Is there a way with the I2C functions to detect the absence of a slave?
In the function below the program goes all the way thru even when there is no slave.
I use a PIC18F2525 with PCH C Compiler, Version 4.071
...
Code:
#use I2C(MASTER, SCL= PIN_C3, SDA=PIN_C4,FORCE_HW, SLOW, STREAM=COMPASS )
...
int8 WrCompassData(int8 EEPromAddr,int8 Data){
   i2c_start(COMPASS);                // Start condition
   i2c_write(COMPASS,COMPASSADDR);         // Addresses the Compass chip
   i2c_write(COMPASS,WRITEEEPROMCMD);
   i2c_write(COMPASS,EEPromAddr);         // Send the pointer (address) in the EEPROM
   i2c_write(COMPASS,Data);            // write the data byte
   i2c_stop(COMPASS);                  //Stop
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Feb 06, 2009 1:14 pm     Reply with quote

Quote:
Is there a way with the I2C functions to detect the absence of a slave?

Here is a test program that finds i2c slaves on a bus.

On a PicDem2-Plus board, it finds the TC74 at 0x9A and the 24LC256
at 0xA0:
Quote:

Searching for i2c slaves in address range 0x10 to 0xF6:

Found i2c slave at address: 9A
Found i2c slave at address: A0

Number of slaves found: 2

You can call the get_ack_status() routine with your slave address.
If it returns a 0x00, then it found the slave.

Code:
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)

int8 get_ack_status(int8 address)
{
int8 status;

i2c_start();
status = i2c_write(address);
i2c_stop();

return(status);
}

//============================
void main()
{
int8 addr;
int8 count;
int8 status;

count = 0;

// Valid i2c slave addresses can be in
// the range from 0x10 to 0xF6.
printf("Searching for i2c slaves in address range 0x10 to 0xF6:\n\r\n\r");

for(addr=0x10; addr < 0xF8; addr+=2)
   {
    status = get_ack_status(addr);

    if(status == 0)
      {
       printf("Found i2c slave at address: %X \n\r", addr);
       count++;
      }
   }

printf("\n\rNumber of slaves found: %u \n\r", count);

while(1);
}
JacquesB



Joined: 22 Aug 2008
Posts: 21

View user's profile Send private message

PostPosted: Fri Feb 06, 2009 1:59 pm     Reply with quote

I didn't noticed that i2c_write() would returned the ack bit

thanks
JacquesB



Joined: 22 Aug 2008
Posts: 21

View user's profile Send private message

PostPosted: Mon Feb 09, 2009 9:45 am     Reply with quote

Hi,

I'm having another problem regarding the function i2c_poll.
I was able to communicate with an I2C chip but unable to read data from it. Every time the program went into rddata() it run indefinitively on the line i2c_poll.
Here is the test program:
Code:
#include <18F2525.h>
#define FRQ 4000000            
#use delay(clock=FRQ)
#use I2C(MASTER, SCL= PIN_C3, SDA=PIN_C4,FORCE_HW, SLOW, STREAM=CHIP )

#define READEEPROMCMD 0xE1      
#define WRITEEEPROMCMD 0XF1      
#define CHIPADDR 0x32      

int8 Buffer[6];         
int8 RdData(int8 NbBytes);

void main(void)
{
   int8 EEPromAddr,i2cbuff[4],ack,i;
   setup_oscillator(OSC_4MHZ|OSC_INTRC);   
   
   EEPromAddr=0x08;
   i2cbuff[0]=CHIPADDR;
   i2cbuff[1]=READEEPROMCMD;
   i2cbuff[2]=EEPromAddr;
   i2c_start(CHIP);             
   for (i=0;i<3;i++)
   {
      ack= i2c_write(i2cbuff[i]);
      if (ack!=0) break;      
   }
   i2c_stop(CHIP);
   if (ack!=0)
      while(1);   

   if (RdData(1)==1)            
      while(1);               
   
   while(1){
   }
}

int8 RdData(int8 NbBytes)
{
   int8 iBuffer;
   iBuffer=0;
   i2c_start(CHIP,0);                
   if (i2c_write(CHIP,(CHIPADDR|0x01))!=0)
   {
      i2c_stop(CHIP);
      return 1;      
   }
   while(iBuffer!=NbBytes) {
//      while(!i2c_poll(CHIP)) ;
      Buffer[iBuffer++]= i2c_read(CHIP);
   }
   i2c_stop(CHIP);
   return 0;
}

When I rem the line : while(!i2c_poll(CHIP)) ; the chip responds with valid data.
Does anyone knows what's happenning with i2c_poll() or what's wrong with my program?

Also when the program works with the i2c_poll() removed, I can read data but after the i2c_stop() the data line is stuck at 0. I need to shut off the power of the slave chip. !! If I write data to the chip both lines goes high after the i2c_stop.
I don't know how to make that bus work properly. What's wrong.

The chip is HMC6343 electronic compass working @ 3V and I'm using 2 Mosfet on SCL & SDA lines for level shifting. I can measure on the scope that the microprocessor's SDA line is back at 5V but the slave pulls it down at 0.
JacquesB



Joined: 22 Aug 2008
Posts: 21

View user's profile Send private message

PostPosted: Mon Feb 09, 2009 10:25 am     Reply with quote

I just find out the solution for SDA line stuck at 0 after i2c_read().
On last byte to read i must not acknowledge it so that slave doesn't wait indefinitively for transmitting another byte.
So I used i2c_read(0) on last byte to read instead of i2c_read() which default to send an Ack.

I still have the question with the I2c_poll() problem...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Feb 18, 2009 12:16 pm     Reply with quote

I think i2c_poll() is only intended for use by an i2c slave program.
Why do you want to use it in a Master ? The only way the master
will get data from a slave is by issuing an i2c_read(). Data does
not accidently get into the Master PIC. It has to explicitly read it
from the slave.
JacquesB



Joined: 22 Aug 2008
Posts: 21

View user's profile Send private message

PostPosted: Wed Feb 18, 2009 1:10 pm     Reply with quote

Your're probably right. I did look at it like this.
But I started my program using an example from CCS manual: (p.172)
Code:
i2c_start(); // Start condition
i2c_write(0xc1); // Device address/Read
count=0;
while(count!=4) {
while(!i2c_poll()) ;
buffer[count++]= i2c_read(); //Read Next
}
i2c_stop(); // Stop condition

This doesn't look like a code for a slave unit...

thanks
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