|
|
View previous topic :: View next topic |
Author |
Message |
semmoor
Joined: 09 May 2012 Posts: 46 Location: KSA
|
I2C master and 2 slaves, getting wrong ADC values !!! |
Posted: Fri Jul 13, 2012 3:41 pm |
|
|
Hi guys, I'm just using the same code written by pcmprogrammer, but with two slaves and getting wrong values, when the microcontroller starts it gives the correct value but then immediately changes to 255 for ever !!!.
However, when I request data from slave_1 only it works, and the same when I only request data form slave_2 it gives the correct values.
So why can't I use both of them at the same time to get correct values?
This the master code:
Code: |
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#include "lcd.c"
#define SLAVE1_WRT_ADDR 0x12
#define SLAVE1_READ_ADDR 0x13
#define SLAVE2_WRT_ADDR 0x14
#define SLAVE2_READ_ADDR 0x15
//====================================
void main()
{
int8 data; //stores data sent by slave_1
int8 data_2; //stores data sent by slave_2
lcd_init();
while(1)
{
//requesting data form slave_1
i2c_start();
i2c_write(SLAVE1_READ_ADDR);
data = i2c_read(0);
i2c_stop();
printf("Slave_1 ADC: %u \n\r", data); //displaying data sent by slave_1 on RS232
delay_ms(500);
//requesting data form slave_2
i2c_start();
i2c_write(SLAVE2_READ_ADDR);
data_2 = i2c_read(0);
i2c_stop();
lcd_putc("\f"); //clear lcd
printf(lcd_putc,"Slave_2 ADC: %u \n\r", data_2); //displaying data sent by slave_2 on LCD
delay_ms(500);
}
}
|
and this is slave_1 code:
Code: |
#include <16F877.h>
#device adc=8
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x12)
int8 adc_result;
#INT_SSP
void ssp_interrupt()
{
int8 incoming, state;
state = i2c_isr_state();
if(state < 0x80) // Master is sending data
{
incoming = i2c_read();
}
if(state == 0x80) // Master is requesting data from slave
{
i2c_write(adc_result);
}
}
//======================================
void main ()
{
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(0);
delay_us(20);
adc_result = read_adc();
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(1)
{
adc_result = read_adc();
delay_ms(500);
}
}
|
Lastly this is the slave_2 code:
Code: |
#include <16F877.h>
#device adc=8
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x14)
int8 adc_result;
#INT_SSP
void ssp_interrupt()
{
int8 incoming, state;
state = i2c_isr_state();
if(state < 0x80) // Master is sending data
{
incoming = i2c_read();
}
if(state == 0x80) // Master is requesting data from slave
{
i2c_write(adc_result);
}
}
//======================================
void main ()
{
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(0);
delay_us(20);
adc_result = read_adc();
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(1)
{
adc_result = read_adc();
delay_ms(500);
}
}
|
Last edited by semmoor on Fri Jul 13, 2012 5:38 pm; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Fri Jul 13, 2012 3:46 pm |
|
|
Do you have the correct I2C bus resistors installed for speed-distance-VCC ? |
|
|
semmoor
Joined: 09 May 2012 Posts: 46 Location: KSA
|
|
Posted: Fri Jul 13, 2012 4:13 pm |
|
|
temtronic wrote: | Do you have the correct I2C bus resistors installed for speed-distance-VCC ? |
yup, I'm using 2.2k for scl and sda.
I tried with different resistor values like 1.7k and 4.7k, but still doesn't work. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Fri Jul 13, 2012 7:54 pm |
|
|
hmmmm...
I'd run PCM pgmr's I2C test program to see if it sees both slaves... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Sat Jul 14, 2012 12:44 am |
|
|
One 'classic' possible problem.
State 0x80 needs you to first _read_ the byte from the slave, then write.
So he slave code need:
Code: |
#INT_SSP
void ssp_interrupt(void) {
int8 incoming, state;
state = i2c_isr_state();
if(state <= 0x80) // Master is sending data - note the =
{
incoming = i2c_read();
}
if(state == 0x80) // Master is requesting data from slave
{
i2c_write(adc_result);
}
}
|
This is a very common 'miss' on I2C, with state 0x80, being 'unique' in requiring this 'double' transaction.
Best Wishes |
|
|
semmoor
Joined: 09 May 2012 Posts: 46 Location: KSA
|
!! |
Posted: Sat Jul 14, 2012 7:13 am |
|
|
Ttelmah wrote: | One 'classic' possible problem.
State 0x80 needs you to first _read_ the byte from the slave, then write.
So he slave code need:
Code: |
#INT_SSP
void ssp_interrupt(void) {
int8 incoming, state;
state = i2c_isr_state();
if(state <= 0x80) // Master is sending data - note the =
{
incoming = i2c_read();
}
if(state == 0x80) // Master is requesting data from slave
{
i2c_write(adc_result);
}
}
|
This is avery common 'miss' on I2C, with state 0x80, beng 'unique' in requiring this 'double' transaction.
Best Wishes |
I did exactly what you said but still didn't work, it didn't even show any result i saw just blank on lcd and RS232, so nothing is displayed. |
|
|
semmoor
Joined: 09 May 2012 Posts: 46 Location: KSA
|
|
Posted: Sat Jul 14, 2012 12:28 pm |
|
|
No solutions ??
it's the second day and still didn't solve this issue!! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Sat Jul 14, 2012 1:10 pm |
|
|
What's your report on using PCM pgmr's I2C testing program ?? |
|
|
semmoor
Joined: 09 May 2012 Posts: 46 Location: KSA
|
|
Posted: Sat Jul 14, 2012 1:28 pm |
|
|
temtronic wrote: | What's your report on using PCM pgmr's I2C testing program ?? |
can you please give me PCM pgmr's I2C testing program ??
please temtronic, and thank you for helping me. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Sun Jul 15, 2012 2:38 am |
|
|
Hasn't anyone heard of using search?.....
If you do a search for 'I2C diagnostic', and 'search for all terms', the very first thread links to where PCM programmer originally posted this.
<http://www.ccsinfo.com/forum/viewtopic.php?t=47707&postdays=0&postorder=asc&highlight=i2c+diagnostic&start=15>
It has been referenced by dozens (possibly hundreds) of other I2C threads, and looking through these would find links to it.
It really is a most 'basic' test, scanning the bus for devices, and if it finds them, telling you the addresses they are on. Brilliant basic test that the bus is working, pull-ups are adequate, and connections are OK. |
|
|
semmoor
Joined: 09 May 2012 Posts: 46 Location: KSA
|
|
Posted: Sun Jul 15, 2012 5:52 am |
|
|
Ttelmah wrote: | Hasn't anyone heard of using search?.....
If you do a search for 'I2C diagnostic', and 'search for all terms', the very first thread links to where PCM programmer originally posted this.
<http://www.ccsinfo.com/forum/viewtopic.php?t=47707&postdays=0&postorder=asc&highlight=i2c+diagnostic&start=15>
It has been referenced by dozens (possibly hundreds) of other I2C threads, and looking through these would find links to it.
It really is a most 'basic' test, scanning the bus for devices, and if it finds them, telling you the addresses they are on. Brilliant basic test that the bus is working, pull-ups are adequate, and connections are OK. |
Ttelmah thank you for the link:
i tried I2C diagnostic it says nothing found !!
how come?? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Sun Jul 15, 2012 7:21 am |
|
|
Well we know his program works so possible causes include
1) incorrect pullup resistors on the I2C busses
2) no ground between devices
3) no power to devices
4) incorrect setup/configuration of devices
5) bad solder joint,loose wiring,etc.
6) 3 blue moons in the sky
It is very difficult to pinpoint why it fails to see your devices as your setup is not in front of us!
Since you're using PICs as I2C devices,I'd try it with a real I2C device,say a DS1307 RTC if you have one.Using a real device will prove the I2C test program works on your breadboard or test setup.
hth
jay |
|
|
semmoor
Joined: 09 May 2012 Posts: 46 Location: KSA
|
|
Posted: Sun Jul 15, 2012 10:20 am |
|
|
temtronic wrote: | Well we know his program works so possible causes include
1) incorrect pullup resistors on the I2C busses
2) no ground between devices
3) no power to devices
4) incorrect setup/configuration of devices
5) bad solder joint,loose wiring,etc.
6) 3 blue moons in the sky
It is very difficult to pinpoint why it fails to see your devices as your setup is not in front of us!
Since you're using PICs as I2C devices,I'd try it with a real I2C device,say a DS1307 RTC if you have one.Using a real device will prove the I2C test program works on your breadboard or test setup.
hth
jay |
temtronic, thank you my friend i appreciate that i will try to check what you told me, and thanks to all. |
|
|
semmoor
Joined: 09 May 2012 Posts: 46 Location: KSA
|
|
Posted: Sun Jul 15, 2012 10:29 am |
|
|
guys i modified the above code to send a string from slave(pic_1) to master(pic_2), but didn't work it only sends the first char!
so, what can you advice me to make the slave sends a string like "ABCD" whenever the master requests a data?
this is the slave code:
Code: |
#include <16F877.h>
#device adc=8
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x14)
#INT_SSP
void ssp_interrupt()
{
int8 incoming, state;
state = i2c_isr_state();
if(state < 0x80) // Master is sending data
{
incoming = i2c_read();
}
if(state == 0x80) // Master is requesting data from slave
{
i2c_write('A'); //send first char to slave
i2c_write('B'); //send second char to slave
i2c_write('C'); //send third char to slave
}
}
//======================================
void main ()
{
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(1)
{
}
}
|
master code:
Code: |
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#define SLAVE1_WRT_ADDR 0x14
#define SLAVE1_READ_ADDR 0x15
//====================================
void main()
{
char data[3]; //stores data sent by slave
while(1)
{
i2c_start();
i2c_write(SLAVE1_READ_ADDR);
data[0] = i2c_read(0); delay_ms(100); //stores first char sent by slave
data[1] = i2c_read(0); delay_ms(100); //stores second char
data[2] = i2c_read(0); delay_ms(100); //stores third char sent by slave
i2c_stop();
printf(" [ %s ] \r\n", data); //now display completed string on RS232
delay_ms(500);
}
}
|
when i make a simple run for the code above i only see the first char printed on RS232. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1345
|
|
Posted: Sun Jul 15, 2012 1:04 pm |
|
|
try only NACK'ing the last byte you read in the master code. You are NACK'ing all 3. Usually when you NACK a read byte, that is the master telling the slave it is finished. |
|
|
|
|
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
|