|
|
View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Tue Jul 06, 2021 7:33 am |
|
|
Slave addresses are required to be even. Cannot be odd. |
|
|
L.T.
Joined: 24 Jul 2020 Posts: 62
|
|
Posted: Tue Jul 06, 2021 11:14 pm |
|
|
Ttelmah wrote: | Slave addresses are required to be even. Cannot be odd. |
Hi Ttelmah,
What did you mean? I dont understand. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Tue Jul 06, 2021 11:40 pm |
|
|
You said
Quote: |
But if I change it to 0x13(00010011)
|
Slave addresses can _only_ be even numbers. They cannot be odd numbers.
A slave set with an address of 0x12, responds to address bytes of both 0x12,
and 0x13. The actual 'slave address', is the upper 7 bits of the byte sent. |
|
|
L.T.
Joined: 24 Jul 2020 Posts: 62
|
|
Posted: Wed Jul 07, 2021 12:18 am |
|
|
Ttelmah wrote: | You said
Quote: |
But if I change it to 0x13(00010011)
|
Slave addresses can _only_ be even numbers. They cannot be odd numbers.
A slave set with an address of 0x12, responds to address bytes of both 0x12,
and 0x13. The actual 'slave address;, is the upper 7 bits of the byte sent. |
Hii Ttelmah,
I didnt want to say to change the slave address as 0x13. When the slave address is 0x12 and I want to send data from the master and send 0x12 as address+r/w from the master, I can send data from the master and read from the slave. 0x12 is 00010010. When I send 0x12 from the master, isn't it the slave address information from the 7th bit to the 1st bit (0001001), and the r/w bit if the 0th bit (0) is? Isn't it necessary to give a write command (1) before sending data from the master? When I send 0x13 as address+r/w from the master, the write command must be given, the last bit is 1. Why can I send data at 0x12 and not 0x13? |
|
|
L.T.
Joined: 24 Jul 2020 Posts: 62
|
|
Posted: Wed Jul 07, 2021 2:00 am |
|
|
Hi PCM programmer,
I did some changes in my code as the link you sent. I can send data from master and slave read correctly. But when master sent to slave request data order, master didnt read correctly. Slave sent 4, master read 0x26. Why?
When I debugged in the slave code, I've seen it never go inside if(state==0x80).
Code: |
#include <16F18346.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT
#define Slave_Read 0x12
#define Slave_Write 0x13
/* Delay for 4 mhz crystal */
#use delay(clock = 24MHz)
/* Setup I2C */
#pin_select SCL1OUT = PIN_C3
#pin_select SCL1IN = PIN_C3
#pin_select SDA1OUT = PIN_C6
#pin_select SDA1IN = PIN_C6
#use I2C(MASTER, I2C1, SLOW)
main()
{
int8 OKU;
setup_oscillator(OSC_HFINTRC_24MHZ,OSC_CLK_DIV_BY_16);
set_analog_pins();
int8 i2c_command = 66;
while (true)
{
OKU=0;
i2c_start(); // Start condition
i2c_write(0x12); // Device address
i2c_write(0x00);
i2c_write(4); // Write Command
i2c_stop(); // Stop condition
delay_ms(100);
output_toggle(pin_C0);
i2c_start();
i2c_write(0x12); // Device address
i2c_write(0x00);
i2c_start();
i2c_write(0x13);
OKU=i2c_read(0);
i2c_stop();
delay_ms(100);
if(OKU==4)
{
output_toggle(pin_A2);
}
}
} |
Code: | #include <16F18346.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT
/* Setup I2C */
#pin_select SCL1OUT = PIN_C3
#pin_select SCL1IN = PIN_C3
#pin_select SDA1OUT = PIN_C6
#pin_select SDA1IN = PIN_C6
#use i2c(SLAVE, I2C1, address=0x12, FORCE_HW)
BYTE address, buffer[0x10];
#INT_SSP
void ssp_interupt ()
{
int8 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) //Second received byte is data
{
buffer[address] = incoming;
if(buffer[address] == 4)
{
output_toggle(pin_A2);
}
}
}
if(state == 0x80) //Master is requesting data
{
i2c_write(buffer[address]);
}
}
main()
{
set_analog_pins();
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
while (true)
{
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Wed Jul 07, 2021 2:18 am |
|
|
OK. The problem was you referred to a slave address of 13, and this can't happen. The R/W bit is not actually part of the 'address'...
Anyway, going on to your code. The problem is how address==80 is
handled. I again refer you to the example. The point is that when you
do the read on address 0x80, you must do I2c_read(2), not the standard
read. If you do the standard read, it releases the bus, and then the slave
does not have time to load the reply.....
So:
Code: |
#INT_SSP
void ssp_interupt ()
{
int8 incoming, state;
state = i2c_isr_state();
if (state <= 0x80) //Master is sending data
{
if (state==0x80)
incoming = i2c_read(2); //critical - reads without releasing clock
else
incoming = i2c_read();
if(state == 1) //First received byte is byte address
{
address = incoming;
}
if(state >= 2 && state!=0x80) //Second received byte is data
{
buffer[address] = incoming;
if(buffer[address] == 4)
{
output_toggle(pin_A2);
}
}
}
if(state >= 0x80) //Master is requesting data
{
i2c_write(buffer[address]);
}
}
|
I've also changed it so it can handle more than one byte sent or
received. You were only handling state 2, not 3, 4, 5 etc.. |
|
|
L.T.
Joined: 24 Jul 2020 Posts: 62
|
|
Posted: Wed Jul 07, 2021 2:49 am |
|
|
Ttelmah wrote: | OK. The problem was you referred to a slave address of 13, and this can't happen. The R/W bit is not actually part of the 'address'...
Anyway, going on to your code. The problem is how address==80 is
handled. I again refer you to the example. The point is that when you
do the read on address 0x80, you must do I2c_read(2), not the standard
read. If you do the standard read, it releases the bus, and then the slave
does not have time to load the reply.....
I've also changed it so it can handle more than one byte sent or
received. You were only handling state 2, not 3, 4, 5 etc.. |
Thanks a lot Ttelmah! It works. |
|
|
|
|
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
|