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

a petite problem about I2C bus

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



Joined: 27 Oct 2006
Posts: 3
Location: Temixco, Morelos, México.

View user's profile Send private message Yahoo Messenger MSN Messenger

a petite problem about I2C bus
PostPosted: Tue Oct 31, 2006 2:20 pm     Reply with quote

Hello:

I'm currently working in a sensor network using 3 PIC18F452 connected over an I2C bus withe a single master. I'm having pretty much problems with the slave PICs because i'm working with in16 data. I'm trying to send 16bit data over the bus from master to slaves and from slaves to master.

My algorithm is like follows:

sending 16bit data master to slave:

start();
send(slave address);
send(address in PIC);
send(high byte of data);
send(low byte of data);
stop();

sending 16bit data slave to master:

start();
send(slave address);
send(address in PIC);
start();
send(slave address + 1);
read(high byte of data);
read(low byte of data);
stop();

the latter is in which i'm having trouble to read the data sent from the slave to the master.

I'm trying to emmulate a slave more or less what it is implemented in the Devantech CMPS03 magnetic Compass. As a matter of fact, this compass uses a PIC also in an always-slave mode. I tried newbiely to read the code programed in the CMPS03 but nothing... if anyone has done this (taking into consideration the acknowledge bits and all that stuff) please tell me how you did it please!!!...

let's say that i'm trying to program the slave code for this master code:

i2c_start();
i2c_write(0xC0);
i2c_write(0x02);
i2c_start();
i2c_write(0xC1);
angalto = i2c_read(1);
angbajo = i2c_read(0);
i2c_stop();
angulo = make16(angalto, angbajo);
fprintf(COM1, "(%u), (%u) angulo = %lu\n\r ", angalto, angbajo, angulo);
_________________
Alejandro Hernández Herdocia.
alexhdzherdocia@gmail.com
alexhdzherdocia@hotmail.com
alexhdzherdocia@yahoo.com.mx
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 01, 2006 2:34 pm     Reply with quote

To do this, you need to modify the CCS example program, Ex_Slave.c
to work with two bytes (instead of one).

To get your project working immediately, I think it's easier to use
the existing Ex_Slave.c code, and just use two separate i2c operations
to get the LSB and MSB bytes. Yes, it will take a little bit longer to
do two i2c accesses than to do one access, but at least your project
can start working sooner.
rhesus



Joined: 27 Oct 2006
Posts: 3
Location: Temixco, Morelos, México.

View user's profile Send private message Yahoo Messenger MSN Messenger

Thanx for the help
PostPosted: Wed Nov 01, 2006 2:54 pm     Reply with quote

Thanx PCM Programmer, though, i've tried already that: to modify the EX_SLAVE.C code using 2 bytes to read and 2 bytes for writing from the slave to the Master but simply didn't work. The thing is that this entire system is an embedded controller for 18 DC Motors with position control, therefore the time used for transfering the data is critical and it is not recommended that the transfer for data is done byte per byte.

The Code that didn't work was as it follows:

#INT_SSP
void ssp_interupt ()
{
BYTE incoming, state;

state = i2c_isr_state();

if(state < 0x80) { //code for receiving. This is OK.
}
if(state == 0x80){ //Master is requesting data
i2c_write(hi(buffer[address]));
i2c_write(buffer[address]);
}
}


I also tried acknowledging the first transfer in which the high byte is passed, but the bus will simply go in the two lines (SDA and SCL) to low.

Any idea?

Thanx in advance!.
_________________
Alejandro Hernández Herdocia.
alexhdzherdocia@gmail.com
alexhdzherdocia@hotmail.com
alexhdzherdocia@yahoo.com.mx
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 01, 2006 3:38 pm     Reply with quote

I tried to make it work for a little while last night, but it didn't work.
I just didn't want to spend any more time on it.
rhesus



Joined: 27 Oct 2006
Posts: 3
Location: Temixco, Morelos, México.

View user's profile Send private message Yahoo Messenger MSN Messenger

Any news?
PostPosted: Sun Nov 19, 2006 2:22 am     Reply with quote

Hello:

Please let me know anytime if you know about someone that has already done this of having a multiple byte read stream in an i2c bus.

thanx.
_________________
Alejandro Hernández Herdocia.
alexhdzherdocia@gmail.com
alexhdzherdocia@hotmail.com
alexhdzherdocia@yahoo.com.mx
Ttelmah
Guest







Re: Thanx for the help
PostPosted: Sun Nov 19, 2006 8:57 am     Reply with quote

rhesus wrote:
Thanx PCM Programmer, though, i've tried already that: to modify the EX_SLAVE.C code using 2 bytes to read and 2 bytes for writing from the slave to the Master but simply didn't work. The thing is that this entire system is an embedded controller for 18 DC Motors with position control, therefore the time used for transfering the data is critical and it is not recommended that the transfer for data is done byte per byte.

The Code that didn't work was as it follows:

#INT_SSP
void ssp_interupt ()
{
BYTE incoming, state;

state = i2c_isr_state();

if(state < 0x80) { //code for receiving. This is OK.
}
if(state == 0x80){ //Master is requesting data
i2c_write(hi(buffer[address]));
i2c_write(buffer[address]);
}
}


I also tried acknowledging the first transfer in which the high byte is passed, but the bus will simply go in the two lines (SDA and SCL) to low.

Any idea?

Thanx in advance!.

The key is that you should only send _one_ byte in the interrupt handler. You need:
Code:

    if(state == 0x80){         
        //Master is requesting _first byte_
        i2c_write(hi(buffer[address]));
    }
    else {
        //second byte
        i2c_write(buffer[address]);
    }

Ideally, you would arrange the output data in a byte array, and then just use:
I2C_WRITE(buffer[state-0x80]);

to send the requested byte.

Best Wishes
Ttelmah
Guest







PostPosted: Sun Nov 19, 2006 9:00 am     Reply with quote

On the comment about 'byte by byte', I2C, _is_ a bytewise protocol. The hardware transfers the byte, but it only transfers a byte. There is no way round this, except to build something like a hardware shift register, and clock the bytes from this.

Best Wishes
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