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

#use i2c preprocessor

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



Joined: 19 Jan 2004
Posts: 2

View user's profile Send private message

#use i2c preprocessor
PostPosted: Mon Jan 19, 2004 5:48 am     Reply with quote

I seem to be having trouble with the preprocessor command #use i2C. To switch paths between two i2C buses I had written the #use lines to direct the comms to either pins on B or pins on C. However the code only seems to use the first #use i2C that it encounters.

Is this a common problem? What is the solution?
neil



Joined: 08 Sep 2003
Posts: 128

View user's profile Send private message

I?C is multidrop
PostPosted: Mon Jan 19, 2004 7:05 am     Reply with quote

Hi, why have 2 I2C buses? It is a multidrop bus, which uses addressing to distinguish between different devices! You can only use one bus at a time anyway.

However, if you mean that you are putting both buses in your code and deciding to use one or the other at compile time, you can use a #ifdef to use the appropriate line.

eg:
Code:
#define USE_I2C_B  // comment this out and it will use second I2C on port C.

#ifdef USE_I2C_B
     #use I2C(master, sda=PIN_B0, scl=PIN_B1)
#else
     #use I2C(master, sda=PIN_C4, scl=PIN_C3, FORCE_HW)
#endif
This is all Preprocessor and does compile. I haven't checked whether it works on a chip, but I don't see why not.

HTH, Neil.
Guest








Re: I²C is multidrop
PostPosted: Mon Jan 19, 2004 7:21 am     Reply with quote

Thanks for the help.
One bus is fully populated with eeprom memory (addresses 0-7). I'd like to add two chips, one for time and one for temperature. The high address of one of these chips is the same as the eemprom memory (0xa0). To get over this I had hoped to use two i2c buses and switch between them in the code by using one of two #use i2c, changing to bus 2 to get time and temperature and then back to bus1 for most of the work The sequence would be to get time and temperature and record it to memory, get a swathe of data and record it to memory and then finish off with time and temperature recorded to memory.

Andrew

neil wrote:
Hi, why have 2 I²C buses? It is a multidop bus, which uses addressing to distinguish between different devices! You can only use one bus at a time anyway.

However, if you mean that you are putting both buses in your code and deciding to use one or the other at compile time, you can use a #ifdef to use the appropriate line.

eg:
Code:
#define USE_I2C_B  // comment this out and it will use second I2C on port C.

#ifdef USE_I2C_B
     #use I2C(master, sda=PIN_B0, scl=PIN_B1)
#else
     #use I2C(master, sda=PIN_C4, scl=PIN_C3, FORCE_HW)
#endif
This is all Preprocessor and does compile. I haven't checked whether it works on a chip, but I don't see why not.

HTH, Neil.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Mon Jan 19, 2004 7:35 am     Reply with quote

You always have the option to bit bang the second i2c port. That is what I do. We have several pics communicating on i2c and data is stored in serial eeproms. The eeproms are bit banged on a separate port because the other devices are writing configuration data on the first port which is being saved on the second. This keeps the bus traffic down and reduces collision errors.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jan 19, 2004 1:44 pm     Reply with quote

Quote:
I seem to be having trouble with the preprocessor command #use i2C. To switch paths between two i2C buses I had written the #use lines to direct the comms to either pins on B or pins on C. However the code only seems to use the first #use i2C that it encounters.


The solution is two use two different "#use i2c" statements, and
then to put all the routines that pertain to a particular i2c bus, below
the proper #use i2c statement for that bus.

The compiler will then generate two complete sets of the i2c
library code, but with the ASM code setup to use different pins
for each set of code.

You can't just have one set of i2c library code, and then magically
tell it to change the pins at run-time. The instructions that use the
specified i2c pins are hard-coded by the compiler at compile-time.
So you will end up with two instances of the library code, but with
each one tailored to the specified i2c pins.

See the example below:
(Note: This is not a full driver of any sort. It's just an example
of how to specify which i2c bus to use for each set of i2c functions).

#include "16F877.h"
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 8000000)
#use rs232(baud = 9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#define EEPROM_I2C_WRITE_ADDR 0xA0
#define EEPROM_I2C_READ_ADDR 0xA1

void init_ext_eeprom(void);
void write_eeprom_byte(int16 addr, char data);
int8 read_eeprom_byte(int16 addr);

void init_temp(void);
void temp_config(int8 data);
int8 read_temp(void);

//============================================
main()
{
int8 value;
int8 current_temp;

// Do some EEPROM operations on the i2c bus on pins B0 and B1.
init_ext_eeprom();
write_eeprom_byte(0, 0x55);
value = read_eeprom_byte(0);

// Do some operations with the temperature chip on the
// i2c bus that is on pins C4 and C3.
init_temp();
current_temp = read_temp();


while(1);
}

//==================================
// The external EEPROM (24LC256) is on the i2c
// bus that is on Pins B0 and B1. For the next
// three functions, the compiler will generate
// "bit-banged" i2c code on pins B0 and B1.

#use i2c (Master, sda = PIN_B0, scl = PIN_B1)

void init_ext_eeprom(void)
{
output_float(PIN_B0);
output_float(PIN_B1);
}

//-------------------------------------------
void write_eeprom_byte(int16 addr, int8 data)
{
i2c_start();
i2c_write(EEPROM_I2C_WRITE_ADDR);
i2c_write((char)(addr >> 8));
i2c_write((char)addr);
i2c_write(data);
i2c_stop();
delay_ms(6);
}

//------------------------------------
int8 read_eeprom_byte(int16 addr)
{
char data;
i2c_start();
i2c_write(EEPROM_I2C_WRITE_ADDR);
i2c_write((char)(addr >> 8));
i2c_write((char)addr);

i2c_start();
i2c_write(EEPROM_I2C_READ_ADDR);

data = i2c_read(0);
i2c_stop();

return(data);
}

//====================================
// The temperature chip is on the i2c bus
// that is on pins C4 and C3. Because we now
// have a new "#use i2c" statement below, which
// defines different pins, all calls to i2c functions
// that are below this statement will have "bit-banged"
// i2c code generated for pins C4 and C3.

#use i2c(Master, SDA = PIN_C4, SCL = PIN_C3)

void init_temp()
{
output_high(PIN_C4);
output_high(PIN_C3);
i2c_start();
i2c_write(0x90);
i2c_write(0xee);
i2c_stop();
temp_config(8);
}
//------------------------------------

void temp_config(int8 data)
{
i2c_start();
i2c_write(0x90);
i2c_write(0xac);
i2c_write(data);
i2c_stop();
}

//-----------------------------------
// Returns degrees F (0-255)
int8 read_temp(void)
{
int8 datah, datal;
int16 data;

i2c_start();
i2c_write(0x90);
i2c_write(0xaa);
i2c_start();
i2c_write(0x91);
datah=i2c_read();
datal=i2c_read(0);
i2c_stop();
data=datah;
data=data*9;
if((datal & 0x80)!=0)
data=data+4;
data=(data/5) + 32;
datal=data;
return(datal);
}
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