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:
Programme Esclave: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(); }
Nous vous remercions d'avance pour vos réponses.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]); } }
-----