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

i2c_write() command

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



Joined: 19 Nov 2003
Posts: 22

View user's profile Send private message

i2c_write() command
PostPosted: Fri Feb 20, 2004 12:06 pm     Reply with quote

Hi,

I would like to know what's the meaning of the instruction "i2c_write" in the following code (code related with the master of the i2c communication). Is it to specify which device is going to read data from? What does the value '0x01' mean?

i2c_start();
i2c_write(SLAVE_ADDRESS | 0x01);
LCD_string[iLCD]=i2c_read(0);

Thanks for all,

Imanol
Vector Research



Joined: 16 Feb 2004
Posts: 10
Location: Kelowna B.C

View user's profile Send private message Visit poster's website

re:i2c_write() command
PostPosted: Fri Feb 20, 2004 12:58 pm     Reply with quote

the 0x01 sets the read/write bit in the address, So in this case the master sends the slaves address with the read bit set, the slave then responds back with the data at that address. a 0x00= write to to the slave address 0x01= read from slave address


Vince
jds-pic2
Guest







PostPosted: Fri Feb 20, 2004 1:06 pm     Reply with quote

don't forget though that the slave address is left shifted by one bit.

for example,

Code:

#define I2CWRITE     0b00000000
#define I2CREAD      0b00000001

// this is a handy routine for taking the i2c physical address
// and shifting the bits left so that the address can simply be
// OR'd with an i2c write command...
int   i2c_addr_mask(int device_addr)
{
   /* xxxxxIJK --> 00000IJK, then 00000IJK --> 0000IJK0 */
   return((device_addr & 0x07)<<1);
}


#define DS1624_ID                      0b10010000
#define DS1624_CMD_ACCESSCONFIG        0xAC
#define DS1624_CMD_INITIATECONVERT     0xEE
#define DS1624_CMD_ACCESSTEMPERATURE   0xAA
#define DS1624_CMD_ACCESSMEMORY        0x17


#use i2c(master,sda=PIN_SCTLDAT,scl=PIN_SCTLCLK)
void i2c_ds1624_init(int device_addr)
{
   int addr_mask;
   addr_mask=i2c_addr_mask(device_addr);
   i2c_start();
   i2c_write(DS1624_ID | addr_mask | I2CWRITE); /* mode is write */
   i2c_write(DS1624_CMD_ACCESSCONFIG);       /* send access config command */
   i2c_write(0x00);       /* set up for continuous temp conversions */
   i2c_stop();
   delay_ms(20);          /* wait for the data to be written */
   i2c_start();
   i2c_write(DS1624_ID | addr_mask | I2CWRITE);   /* mode is write */
   i2c_write(DS1624_CMD_INITIATECONVERT);   /* initiate temperature conversions */
   i2c_stop();
}



jds-pic
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Feb 20, 2004 1:30 pm     Reply with quote

Quote:
don't forget though that the slave address is left shifted by one bit.


That's true, but it's so much easier to define the slave address as
an 8-bit value in your code, instead of a 7-bit value that you have
to shift left.

For example, in a 24LC256 driver, I do this:
Code:
#define EEPROM_I2C_WRITE_ADDR  0xA0
#define EEPROM_I2C_READ_ADDR   0xA1

Then in the code, you use it like this:
Code:
char read_eeprom_byte(long 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);
}

This way, you don't have to worry about shifting the slave address
and it's so much easier.
jds-pic2
Guest







PostPosted: Fri Feb 20, 2004 1:56 pm     Reply with quote

PCM programmer wrote:

That's true, but it's so much easier to define the slave address as
an 8-bit value in your code, instead of a 7-bit value that you have
to shift left.


agreed. unless you have many i2c devices hanging off of the bus, which is the case in my example above.

so. for example, the function
i2c_ds1624_init(int device_addr)

is used to initialize 6 Dallas DS1624 temperature sensor devices, and it's easier to abstract them by their physical addresses (set by A0/A1/A2 pins) rather than their logical READ/WRITE addresses.

Code:

main() {
[...]
for (i=DS1624[0].addr; i<=DS1624[5].addr; i++)
  i2c_ds1624_init(DS1624[i].addr);
[...]


since all of the left shifting happens in the i2c abstraction layer (where it should), i only need to deal with physical addresses in my code. and when it comes to debugging the schematics at 2AM that's a benefit [to me...].

but as you noted you can go the other way as well.

jds-pic[/code]
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