|
|
View previous topic :: View next topic |
Author |
Message |
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!! |
|
|
PICoHolic
Joined: 04 Jan 2005 Posts: 224
|
|
Posted: Tue Nov 20, 2007 8:17 am |
|
|
I have a suggestion to make. PIC18F2550 & 4550 have erratas in I2C master and slave. I've never been able to activate the hardware I2C master on these platforms. So i use it by software instead (on different pins too)
Have you tried your I2C mater code with an EEPROM for ex? something other than a slave micro?
Try it in order to test your master first !
Regards |
|
|
robotam
Joined: 13 Nov 2007 Posts: 15
|
|
Posted: Tue Nov 20, 2007 8:27 am |
|
|
yes i already did that and worked |
|
|
yesahycs
Joined: 31 Oct 2007 Posts: 5
|
|
Posted: Wed Dec 05, 2007 12:35 am |
|
|
I'm interested in this topic,
robotam can u post your code that work and share on what you had changed to make it work? |
|
|
|
|
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
|