|
|
View previous topic :: View next topic |
Author |
Message |
rhesus
Joined: 27 Oct 2006 Posts: 3 Location: Temixco, Morelos, México.
|
a petite problem about I2C bus |
Posted: Tue Oct 31, 2006 2:20 pm |
|
|
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
|
|
Posted: Wed Nov 01, 2006 2:34 pm |
|
|
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.
|
Thanx for the help |
Posted: Wed Nov 01, 2006 2:54 pm |
|
|
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
|
|
Posted: Wed Nov 01, 2006 3:38 pm |
|
|
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.
|
|
|
Ttelmah Guest
|
Re: Thanx for the help |
Posted: Sun Nov 19, 2006 8:57 am |
|
|
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
|
|
Posted: Sun Nov 19, 2006 9:00 am |
|
|
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 |
|
|
|
|
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
|