|
|
View previous topic :: View next topic |
Author |
Message |
ebarnes
Joined: 16 Apr 2007 Posts: 11
|
I2C slave transmitting data |
Posted: Tue Oct 09, 2007 2:23 pm |
|
|
I must be having a brain freeze.
Could someone write a few lines if pseudo code for transmitting data via I2C when in slave mode?
I know that a master can send data to a slave by sending the slave address. I use slave address 0x2 and my master transmits fine to the slave. What I want to do is have the slave continuously update, and when the master needs the data, it requests the slave to transmit it.
Thanks in advance. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 09, 2007 6:30 pm |
|
|
Quote: | What I want to do is have the slave continuously update, |
What does this mean ? Are you talking about a multi-master system ? |
|
|
ebarnes
Joined: 16 Apr 2007 Posts: 11
|
|
Posted: Thu Oct 11, 2007 11:47 am |
|
|
I have 2 pic16f690 talking as master transmitting to a slave continously in a loop.
what i want to do is reverse this where the slave will tramsmit to the master when the master requests data.
i did the latter just to test the i2c functions and get communication going.
i have a pic that continously reads current. and when the master wants to know what the current is, it will request that information from the slave.
in other words, i want a master to initiate a data transfer to the master from a slave. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 11, 2007 12:15 pm |
|
|
So currently, the PIC with sensor is the master. You want to make it
be the slave. (That's the normal way people do it).
Put the following code in your i2c Master PIC. Put the CCS Ex_Slave.c
program in the Slave PIC. Then connect the serial port on the Master
PIC to your PC, and start up a terminal window. It should display the
character that the Master PIC read from the i2c Slave PIC. It should
be a 'B' character. Don't forget the pull-up resistors on the i2c bus.
Code: | #include <16F877.H>
#fuses XT, NOWDT, PROTECT, 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)
//====================================
void main()
{
int8 data;
// Write the letter 'B' to the slave board.
i2c_start();
i2c_write(0xA0);
i2c_write(0x00);
i2c_write('B');
i2c_stop();
// Read from the slave board and display the data.
i2c_start();
i2c_write(0xA0);
i2c_write(0x00);
i2c_start();
i2c_write(0xA1);
data = i2c_read(0);
i2c_stop();
printf("read %c \n\r", data);
while(1);
} |
|
|
|
ebarnes
Joined: 16 Apr 2007 Posts: 11
|
|
Posted: Thu Oct 11, 2007 2:07 pm |
|
|
Ahh! yes, how simple. Thank-you for enlighting me on this.
You are da-man! |
|
|
Ttelmah Guest
|
|
Posted: Mon Nov 19, 2007 9:55 am |
|
|
On I2C, the device 'address', is the top seven bits of the byte writen immediately after a 'start'. The bottom bit, sets the direction of the following transfer wanted.
So the 'read' code, sends the address (0b1010000x), with 'x' being '0', to say this is a 'write', followed by the bytes representing the location to be talked to, 'inside' this device. The direction bit, has to be '0', or the location bytes can't be sent. Then the master 'changes direction', by sending a second 'start', without stopping the bus first, followed by the device address again, and now the direction bit set to '1' (read), to 'read from' the selected location.
Best Wishes |
|
|
robotam
Joined: 13 Nov 2007 Posts: 15
|
|
Posted: Mon Nov 19, 2007 10:10 am |
|
|
Ttelmah wrote: | On I2C, the device 'address', is the top seven bits of the byte writen immediately after a 'start'. The bottom bit, sets the direction of the following transfer wanted.
So the 'read' code, sends the address (0b1010000x), with 'x' being '0', to say this is a 'write', followed by the bytes representing the location to be talked to, 'inside' this device. The direction bit, has to be '0', or the location bytes can't be sent. Then the master 'changes direction', by sending a second 'start', without stopping the bus first, followed by the device address again, and now the direction bit set to '1' (read), to 'read from' the selected location.
Best Wishes |
thank you for answer.
my problem is , i can send data from the master to slave but i can't receive data from the slave.
regards |
|
|
robotam
Joined: 13 Nov 2007 Posts: 15
|
|
Posted: Mon Nov 19, 2007 11:42 am |
|
|
Master code
Quote: | #include <18F2550.h>
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
//#fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG,VREGEN,PUT
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use i2c(MASTER, SDA=PIN_B0, SCL=PIN_B1)
#use standard_io(A)
#use standard_io(B)
BYTE address, buffer[0x10];
void main(){
int8 data;
while(1){
i2c_start();
i2c_write(0xA0);
i2c_write(0x00);
i2c_write(0x05);
i2c_stop();
delay_ms(300);
/*
i2c_start();
i2c_write(0xA0);
i2c_write(0x00);
i2c_write(0x0C);
i2c_stop();
delay_ms(2000);
*/
i2c_start();
i2c_write(0xA0);
i2c_write(0x00);
i2c_start();
i2c_write(0xA1);
data=i2c_read(0);
i2c_stop();
if(data==0x05)
output_high (PIN_A1);
else
output_low (PIN_A1);
}
}
|
Slave code
Quote: |
#include <30F4012.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=20000000)
//#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(SLAVE, SDA=PIN_F2, SCL=PIN_F3, address=0xA0)
int8 data;
char TEXT[] = "A";
BYTE address, buffer[0x10];
//int state , incoming;
//#INT_SSP
#INT_SI2C
//#INT_MI2C
void ssp_interupt () // ssp_interupt ()
{
BYTE incoming, state;
state = i2c_isr_state();
if(state < 0x80) //Master is sending data
{
incoming = i2c_read();
if(state == 1) //First received byte is address
address=incoming;
if(state == 2)
{
buffer[address]=incoming; //Second received byte is data
output_b(incoming);
}
}
if(state == 0x80) //Master is requesting data
{
output_low (PIN_B2);
output_low (PIN_B1);
delay_ms(50);
output_high (PIN_B2);
output_high(PIN_B1);
delay_ms(50);
i2c_write(buffer[address]);
//i2c_write(0x05);
}
}
void main ()
{
enable_interrupts(INTR_GLOBAL);
enable_interrupts(INT_SI2C);
enable_interrupts(INT_MI2C);
while (TRUE) {
}
} |
I can send to the slave board but i can't receive data from the slave.
Please Help!! |
|
|
SET
Joined: 15 Nov 2005 Posts: 161 Location: Glasgow, UK
|
|
Posted: Mon Nov 19, 2007 12:10 pm |
|
|
Quote: | if(state < 0x80) //Master is sending data
{
incoming = i2c_read();
if(state == 1) //First received byte is address
address=incoming;
if(state == 2)
{
buffer[address]=incoming; //Second received byte is data
output_b(incoming);
}
} |
Above is excerpt from your slave code i2c receive ISR. You set 'address' to the value received as I2C device address (which is fine), then you put the following received bytes into your buffer starting from index 'address' (which isnt likely to be correct..)
Shouldnt it be more like:
Code: | void ssp_interupt () // ssp_interupt ()
{
BYTE incoming, state;
static BYTE buf_addr;
state = i2c_isr_state();
if(state < 0x80) //Master is sending data
{
incoming = i2c_read();
if(state == 1) //First received byte is address
{
address=incoming;
buf_addr = 0;
}
if(state == 2)
{
buffer[buf_addr++]=incoming; //Second received byte is data
output_b(incoming);
}
}
if(state == 0x80) //Master is requesting data
{
output_low (PIN_B2);
output_low (PIN_B1);
delay_ms(50);
output_high (PIN_B2);
output_high(PIN_B1);
delay_ms(50);
// this isnt right either..
i2c_write(buffer[address]);
}
} |
|
|
|
robotam
Joined: 13 Nov 2007 Posts: 15
|
|
Posted: Mon Nov 19, 2007 12:15 pm |
|
|
Thanks for your suggestion,
But the problem is that the master doesn't receive data from the slave.
the slave code is frome ex_slave.c from "ccs". |
|
|
SET
Joined: 15 Nov 2005 Posts: 161 Location: Glasgow, UK
|
|
Posted: Mon Nov 19, 2007 12:50 pm |
|
|
Code: | i2c_start();
i2c_write(0xA0);
i2c_write(0x00);
i2c_start();
i2c_write(0xA1);
data=i2c_read(0);
i2c_stop();
if(data==0x05)
output_high (PIN_A1);
else
output_low (PIN_A1); |
This is your master code, reading from the slave (at address A0), looks ok..
And your slave code is:
Code: | if(state == 0x80) //Master is requesting data
{
output_low (PIN_B2);
output_low (PIN_B1);
delay_ms(50);
output_high (PIN_B2);
output_high(PIN_B1);
delay_ms(50);
// this isnt right either..
i2c_write(buffer[address]);
} |
So Code: | i2c_write(buffer[address]); | should be which is what you had but commented out, I guess that didnt work, and your debug pins didnt change level? |
|
|
robotam
Joined: 13 Nov 2007 Posts: 15
|
|
Posted: Mon Nov 19, 2007 12:52 pm |
|
|
i already tryed it and same result |
|
|
Ttelmah Guest
|
|
Posted: Mon Nov 19, 2007 3:37 pm |
|
|
You are delaying for 100mSec in the 'write' routine, before writing the data. The master expects the data to be there immediately...
Best Wishes |
|
|
robotam
Joined: 13 Nov 2007 Posts: 15
|
|
Posted: Tue Nov 20, 2007 2:57 am |
|
|
Ttelmah wrote: | You are delaying for 100mSec in the 'write' routine, before writing the data. The master expects the data to be there immediately...
Best Wishes |
thank you for your answer but, i did that to know if really the master is requesting data from the slave, but it's not the case.
thank you |
|
|
robotam
Joined: 13 Nov 2007 Posts: 15
|
|
Posted: Tue Nov 20, 2007 6:38 am |
|
|
PLEASE HELP!! |
|
|
|
|
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
|