Bonjour,

Nous souhaitons effectuer deux actions consécutives dans une seule interruption I2C. Nous utilisons deux pic 16f877 avec deux programmes distincts, un maitre, un esclave. Le problème est que le pic esclave ne gère pas les deux actions consécutives de lecture et d'écriture, il passe directement à l'écriture.

Programme Maitre:
Code:
//communication pic a pic par protocole I2C
// Programme du maitre
#include <16f877.h>
#use delay(clock=4000000)
#use i2c(MASTER,SCL=PIN_C3,SDA=PIN_C4,slow)
#fuses HS,NOWDT,NOPROTECT,NOLVP
#include <lcd_vert.c>

//declaration des variables
byte  d[3]={0x41,'z','2'}; // declaration tableau ecriture sur i2c
byte data[4]={0x41,0x41,0x41,0x41};		//tableau de 4 octets
#locate data0=0X30	//fixe le début de la zone mémoire "data"
int i;

//Declarations des fonctions
void lecture_pic_esclave1();
void ecriture_pic_esclave1();
///////////////////////Programme principal
void main()
{
InitLCD();

for (i=0;i<4;i++)  data[i]=0x41; 

while (1)
{
ecriture_pic_esclave1();
gotoxy(1,1);			//
printlcd(d[1]);			// visualisation
gotoxy(1,5);			// LCD
printlcd(d[2]);			//
delay_ms(1000);

lecture_pic_esclave1();
delay_ms(10);
gotoxy(2,1);
for (i=0;i<4;++i)
printf(PrintLCD,"%u ",data[i]);
}
}
/////////////////////////////
void ecriture_pic_esclave1()
{
    i2c_start();		// lancement i2c
	i2c_write(0x02);	// adressage
	i2c_write(d[0]);	// stokage données dans memoire
	i2c_write(d[1]);
	i2c_write(d[2]);
	i2c_stop();
}
/////////////////////////////
void lecture_pic_esclave1()
{
i2c_start(); 
i2c_write(0x03);
data[0]=i2c_read(1);  
data[1]=i2c_read(1); 
data[2]=i2c_read(1); 
data[3]=i2c_read(0); 
i2c_stop(); 
}
Programme Esclave:
Code:
//communication pic a pic par protocole I2C:
// Programme de l'esclave
#include <16f877a.h>
#include <P16F877.h>
#use delay(clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3,address=0x02)
#fuses HS,NOWDT,NOPROTECT,NOLVP

	// ATTENTION .	L'adresse ne doit pas être celle d'un circuit câblé sur la carte (mémoire,capteur de température...)
					// ni celle d'un autre périphérique extérieur.
					//
					// L'adresse envoyée par le maître doit être:
					//				  - paire pour une écriture de donnée vers l'esclave 
					//				  - impaire supéreure pour une lecture d'une donnée disponible chez l'esclave.
					//									
					// En fixant l'adresse à 02 pour ce périphérique le maître devra utiliser 02 pour écrire et 03 pour lire

#include <lcd_vert.c>

byte dataD,data[10]={0,0,0,0,0,0,0,0,0,0};		//tableau de 10 octets
#locate data0=0X30	//fixe le début de la zone mémoire "data"
int compte,i=0;
int1 a=0;
byte  d[4]={27,250,3,1};

///////////prog interruption
#int_ssp
void SSP_interupt() //on fait appel aux interruptions GLOBAL & INT_ssp
{
output_high(PIN_B3); 
	dataD=0;
	compte=0;
if(i2c_poll()) dataD=i2c_read(); // on stock dans data les donnees recues par i2c	
 if(dataD==0X41)	//synchronise la lecture de la phrase 
		{
		while(compte!=2)
			{
			while(!i2c_poll());
			data[compte++]=i2c_read();
output_high(PIN_B2); 
                                                                                             
			}
		}
 
 if(!i2c_poll())
	{
	i2c_write(d[0]);
	i2c_write(d[1]);
	i2c_write(d[2]);
	i2c_write(d[3]);
	i2c_stop();
output_high(PIN_B1); 
	}
 
}
 
///////////////////////Programme principal
void main()
{
set_tris_B(0x00);
PORTB=0;
enable_interrupts(GLOBAL); //validation de l'interrruption
enable_interrupts(INT_ssp); //validation de l'interruption
initlcd();
while (1)
{
gotoxy(1,1); 
printf(PrintLCD,"%c ",data[0]);
gotoxy(1,10); 
printf(PrintLCD,"%c ",data[1]);
delay_ms(1000);
gotoxy(2,1);
for (i=0;i<4;++i)
printf(PrintLCD,"%u ",d[i]);
}
}
Nous vous remercions d'avance pour vos réponses.