|
|
View previous topic :: View next topic |
Author |
Message |
gonlo82
Joined: 10 Dec 2010 Posts: 5
|
Unstable behavior on Pic Master I2C with 2 Slaves |
Posted: Mon Jun 20, 2011 10:46 am |
|
|
Hello. I'm a CCS(ver 4.3.0.278) beginner programmer. I trying to fix an unstable behavior between a master and 2 slaves 16f876a Pics. If a connect only a master with only one slave they work well. The master collect the info and shows it in a lcd. But when there are 2 slaves connected the info is altered after 4 secs showing the max value acquired by the two slaves through their pins AN0.
I attach the codes below and a picture below. I hope receive some help.
MASTER
Code: |
#include <16f876a.h>
#fuses XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4M)
#define LCD_DATA_PORT getenv("SFR:PORTB")
#define LCD_ENABLE_PIN PIN_B2
#define LCD_RS_PIN PIN_B0
#define LCD_RW_PIN PIN_B1
#include <lcd.c>
#use i2c(MASTER,SDA=PIN_C4, SCL=PIN_C3/*,FAST,FORCE_HW*/)
#use fast_io(c)
int8 lee_master,escla1,escla2,escla3,escla4,escla5,escla6;
int8 ack=5;
void read_i2c(int dir); // Función que escribe en el PIC esclavo.
void main()
{
lcd_init();
while(true)
{
//if(input(PIN_a0)==1)
//{
read_i2c(0xA1);// Leemos un byte del dispositivo con id=0xA1
escla1=lee_master;
delay_ms(10);
lcd_gotoxy(1,1);
printf(lcd_putc,"\fESCLAVO 1\n");
//lcd_gotoxy(1,2);
printf(lcd_putc,"%3u",escla1);
//}
delay_ms(2000);
//if(input(PIN_a0)==0)
//{
read_i2c(0xB1);// Leemos un byte del dispositivo con id=0xA1
escla2=lee_master;
delay_ms(170);
lcd_gotoxy(1,1);
printf(lcd_putc,"\fESCLAVO 2\n");
//lcd_gotoxy(1,2);
printf(lcd_putc,"%3u",escla2);
delay_ms(2000);
//}
}
}
void read_i2c( int dir)
{
i2c_start();
ack=i2c_write(dir);//This function returns the ACK Bit.
// 0 means ACK, 1 means NO ACK, 2 means there was a collision if in
//Multi_Master Mode. This does not return an ACK if using i2c in slave mode
delay_ms(10);
lee_master=i2c_read(0); // 0 means ACK
delay_ms(10);
i2c_stop();
}
|
SLAVE
Code: |
#include <16f876A.h>
#fuses /*XT,*/NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#DEVICE ADC=8
#use delay(clock=4M)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3,ADDRESS=0xB0/*, FAST , FORCE_HW*/)
#use standard_io(b)
#use fast_io(a)
#use fast_io(c)
int8 q,r=0;
float p;
int8 estado=0,status[6];
int8 dato[6];
int8 i=0,j=0;
#int_SSP
void SSP_isr()//Returns the state of I2C communications in I2C slave mode
// after an SSP interrupt.+ state is an 8 bit int
{
estado=i2c_isr_state();//detecta el estado del bus i2c
if(estado>0 && estado<0x80) // el esclavo recibe datos
{//0x7F - Master has written data; i2c_read() will immediately return the data
i++;
dato[i]=i2c_read();
}
else if(estado >= 0x80) // maestro lee dato o el esclavo escribe datos
{
j++;
status[j]=i2c_write(q);
delay_ms(10);
}/*0x81-0xFF - Transmission completed and acknowledged; respond with i2c_write()
to pre-load the transmit buffer for the next transation (the next I2C read
performed by master will read this byte).
*/
}
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
setup_adc_ports(AN0); //Canal 0 analógico
setup_adc(ADC_CLOCK_INTERNAL); //Fuente de reloj RC
while(true){
set_adc_channel(0);
delay_us(20);
q = read_adc(); //Lectura canal0
p = 5.0 * q / 255.0; //Conversión a tens
}
}
|
PROTEUS SIMULATION (VER 7.7.2)
[img]http://imageshack.us/photo/my-images/42/masterwith2slaves.jpg/[/img] _________________ I m working for me in electrical troobleshooting. Pic's Matter interest me a lot to improve my skills. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Mon Jun 20, 2011 12:18 pm |
|
|
quick comments
1) get rid of the fast_io commands !! Unless YOU setup the I/O ports correctly using the set_tris... commands, you'll have a LOT of trouble. Let the compiler automatically handle the ports!!
2) Do you have the correct pullup resistors on the I2C bus lines ?
3) The /* */ in the code is very confusing to me, maybe the compiler as well. It's easier to make 2 similar statements and comment out the one not being tried.
4) I'd setup all peripherals BEFORE enabling any interrupts just to be certain all is correct before the ISRs are enabled.
5) Get rid of Proteus. It is FULL of bugs,errors and other bad things ! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 21, 2011 1:28 pm |
|
|
This 2-page thread discusses problems and solutions for making 2 or more
PIC i2c slaves work with one PIC i2c master:
http://www.ccsinfo.com/forum/viewtopic.php?t=39242
Study it carefully. For example, it does not put 10 ms delay in the slave's
#int_ccp isr (which you are doing). Try to make your code do it the
same way as the working code. |
|
|
|
|
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
|