View previous topic :: View next topic |
Author |
Message |
ihsan
Joined: 30 Nov 2023 Posts: 9
|
i2c communication with proton basic |
Posted: Tue Jan 02, 2024 9:13 am |
|
|
hello dear friends,
I have an i2c slave pic programmed with proton basic. I know this pic address. But I cannot read slave pic datas.
I am sharing the code I wrote below, it would be very helpful if you could review my mistakes and tell me how to fix them.
Code: |
#include <main.h>
#define SLAVE_ADDR 0x12
int8 data[10];
void main()
{
while(TRUE)
{
i2c_start();
i2c_write(SLAVE_ADDR);
i2c_write(0x02);
i2c_stop();
delay_ms(250);
i2c_start();
i2c_write(SLAVE_ADDR | 1);
for(int i = 0; i < 10; i++)
{
data[i] = i2c_read();
}
i2c_stop();
}
} |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Tue Jan 02, 2024 9:48 am |
|
|
You should go to the code library forum and download the 'I2C scanner' program, install and run. It will report back what addresses of I2C devices are connected.
You may find that the slave is at another address. Some code using 7 bit addresses( + R/w bit), while CCS uses 8 bits(R/w bit included ).
Also ,be sure to have correct I2C pullup resistors on clock and data lines. 4k7 for 5 volt, 3k3 for 3 volt VDD should be OK. |
|
|
ihsan
Joined: 30 Nov 2023 Posts: 9
|
|
Posted: Wed Jan 03, 2024 12:02 am |
|
|
Thanks for your response temtronic. I use 4k7 for 5 volt. I shift 1 bit to left while I use CCS. I am curious are there any difference byte format between proton and ccs. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Wed Jan 03, 2024 2:13 am |
|
|
One thing leaps out. The last i2c_read, needs to be i2c_read(0).
This is a required part of the I2C spec. I changes the polarity of the
acknowledge to tell the slave this is the last read. If this is not done
behaviour could be indeterminate....
Looking at your code, what is the write '2' doing?. Is this setting the
register address for the read?. If so, you don't want the I2C stop and
start again. You need to do a _restart_. This is sending another 'start'
without a stop.
So something like:
Code: |
while(TRUE)
{
i2c_start();
i2c_write(SLAVE_ADDR);
i2c_write(0x02);
//i2c_stop();
//delay_ms(250);
//Does the device really need this long to prepare the reply????
//In computer terms 250mSec is an age. If the device is SMBUS
//rather than I2C, this has a 10mec timeout.
delay_ms(2);
i2c_start(); //This is now a restart
i2c_write(SLAVE_ADDR | 1);
for(int i = 0; i < 10; i++)
{
if (i!=9)
data[i] = i2c_read();
else
data[i] = i2c_read(0);
}
i2c_stop();
delay_ms(10);
}
|
I've also added a delay after the end of the transaction. If the device needs
a long delay after receiving it's read address, it is unlikely to be happy with
'back to back' reads.
Now this all depends on the nature of the hardware and code at the other
end, but shows a more typical sequence. |
|
|
ihsan
Joined: 30 Nov 2023 Posts: 9
|
|
Posted: Wed Jan 03, 2024 11:55 pm |
|
|
Thank you Ttelmah. This code is working. I write 2 for reading 10 byte data. I dont have slave source code but I know if I write 2, I can read 10 byte. It is about slave. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Thu Jan 04, 2024 1:37 am |
|
|
Good..
Nice way to start the year. Moving forwards.
Best Wishes |
|
|
|