toujours rien de speiciale
la memoire reste avec c'est valeur initiale
-----
toujours rien de speiciale
la memoire reste avec c'est valeur initiale
voila mon code
mon oscillateur est un circuit RC 1.5MHz pour information
Code://******** REQUIRED DEFINES *********** // #define BITNUM(adr, bit) ((unsigned)(&adr)*8+(bit)) // static bit SCL @ BITNUM(PORTA,0) //-- The SCL output pin // #define SCL_TRIS //-- The SCL Direction Register Bit // #define SDA //-- The SDA output pin // #define SDA_TRIS //-- The SDA Direction Register Bit #pragma chip pic16f877 bit SCL_TRIS @TRISC.3; bit SDA_TRIS @TRISC.4; bit SCL @PORTC.3; bit SDA @PORTC.4; bit VALID @PORTB.2; char sortie @PORTD; //unsigned compt,i:8; unsigned tempo:16; char msg,compteur; /* #define I2CLOW 0 //-- Puts pin into output/low mode #define I2CHIGH 1 //-- Puts pin into Input/high mode */ //********* I2C Bus Timing - uS ************ #define I2CSTARTDELAY 50 #define I2CSTOPDELAY 50 #define I2CDATASETTLE 20 #define I2CCLOCKHIGH 100 #define I2CHALFCLOCK 50 #define I2CCLOCKLOW 100 #define I2CACKWAITMIN 50 //********************* FUNCTIONS ************************ //char I2C_Send(char Address,char Data,char Num); //char I2C_Read(char Address,char Data,char Num); char i2csendbyte(char msg); char i2cgetbyte(void); char i2cgetack(void); void i2csendack(void); void i2cdelay(char delay); void i2cstart(void); void i2cstop(void); void i2cclock(void); char i2creadbit(void); void antirebond(void); void main(void) { compteur=01; OPTION_REG=0b00000000; TRISB=0b11111111; TRISC=0b11111111; TRISD=0B00000000; // configuaration du 2 port while(1) { if (!VALID) { compteur++; //test action sur BP antirebond(); while(!VALID); antirebond(); i2cstart(); i2csendbyte(0xA0); //envoie adress physique i2cgetack(); i2csendbyte(compteur);// envoie adress de la case memoire ou je veux ecrire i2cgetack(); i2csendbyte(10); //envoie donnee i2cgetack(); i2cstop(); i2cstart(); i2csendbyte(0xA1); //mode Read i2cgetack(); sortie=i2cgetbyte();//lit la donnee i2cstop(); } } } ///////////////////////: char i2csendbyte(char msg) { char count; SDA=0; SCL=0; i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time for(count=8;count>0;count--) //-- Send 8 bits of data { if( (msg & 0x80)== 0) //-- Get the Bit { SDA=0; //-- Ensure Port pin is low SDA_TRIS=0; //-- Lower pin if bit = 0 } else { SDA_TRIS=0; //-- Release pin if bit = 1 } msg=msg<<1; //-- Shift next bit into position i2cclock(); //-- Pulse the clock } SDA_TRIS=1; //-- Release data pin for ACK return(1); } //************** END OF i2csendbyte //************************************************************************* // char i2cgetbyte(void) // // Reads in a byte from the I2C Port //************************************************************************* char i2cgetbyte(void) { char count,msg=0; SDA=0; SCL=0; i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time for(count=8;count>0;count--) //-- Read 8 bits of data { msg=msg <<1; SDA_TRIS=1; //-- Release pin so data can be recieved if(i2creadbit()) { msg +=1; } } return(msg); } //************************************************************************* // i2cstart //************************************************************************* void i2cstart(void) { //-- Ensure pins are in high impedance mode -- SDA_TRIS=1; SCL_TRIS=1; SCL=0; SDA=0; i2cdelay(I2CSTARTDELAY); //-- Generate the start condition SDA_TRIS=0; SDA=0; i2cdelay(I2CSTARTDELAY); SCL_TRIS=0; i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time } //************** END OF i2cstart //************************************************************************* // i2cstop //************************************************************************* void i2cstop(void) { //-- Generate Stop Condition -- SDA_TRIS=0; SCL_TRIS=1; i2cdelay(I2CSTOPDELAY); SDA_TRIS=1; } //************** END OF i2cstop //************************************************************************* // i2cclock //************************************************************************* void i2cclock(void) { i2cdelay(I2CDATASETTLE); //-- Minimum Clock Low Time SCL_TRIS=1; //-- Release clock i2cdelay(I2CCLOCKHIGH); //-- Minimum Clock High Time SCL_TRIS=0; //-- Lower the clock i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time } //************** END OF i2cclock //************************************************************************* // i2creadbit //************************************************************************* char i2creadbit(void) { char T=0; i2cdelay(I2CDATASETTLE); //-- Minimum Clock Low Time SCL_TRIS=1; //-- Release clock i2cdelay(I2CHALFCLOCK); //-- 1/2 Minimum Clock High Time if(SDA !=0 ) T=1; //-- READ in the data bit i2cdelay(I2CHALFCLOCK); //-- 1/2 Minimum Clock High Time SCL_TRIS=0; //-- Lower the clock i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time return(T); } //************** END OF i2cclock //************************************************************************* // i2cgetack //************************************************************************* char i2cgetack(void) { SDA=0; SCL=0; SCL_TRIS=0; //-- Ensure clock is low SDA_TRIS=1; //-- Release the Data pin so slave can ACK SCL_TRIS=1; //-- raise the clock pin i2cdelay(I2CHALFCLOCK); //-- wait for 1/2 the clock pulse if(SDA) //-- sample the ACK signal { return(0); //-- No ACK so return BAD } i2cdelay(I2CHALFCLOCK); //-- Else wait for rest of clock SCL_TRIS=0; //-- Finish the clock pulse i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time return(1); } //************** END OF i2cgetack //************************************************************************* // void i2csendack(void) //************************************************************************* void i2csendack(void) { //--- Send Ack to slave except for last time --- SDA=0; SDA_TRIS=0; //-- Send ACK i2cdelay(I2CDATASETTLE); //-- Give it time to settle i2cclock(); //-- Pulse the clock SDA_TRIS=1; //-- Release ACK i2cdelay(I2CDATASETTLE); //-- Gap between next byte } //************** END OF i2csendack //************************************************************************* // i2cdelay // // This delay is approx us plus the function call delays // Should be close enough for I2C //************************************************************************* void i2cdelay(char delay) { antirebond(); // DelayMs(delay); //-- For Debug } //************** END OF i2cdelay // void antirebond(void) { for (tempo=0;tempo<2000;tempo++); //fonction pour antirebond de 20 ms }
et les temporisation qui sont dans mon programme sont fait pour un quartz 20MHZ
est ce que ca pourrait influencer le fonctionnement???
si oui est ce que quelqu'un peut me calculerr les valeurs des tempo avec mon oscillateur ou bien juste m'explique comment faire la conversion des valeurs de 20MHZ a 1.5 MHZ
et merci
Hi Amine,
oui pourquoi pas (encore que théoriquement...non),
vu que c'est de la simu, mets un quartz 20Mhz, pour voir...
sinon moi, même pour "recevoir" le ack, je laisse la sortie SDA en sortie...
56454445
3B4F29
______________________________ __________
46554D4552204E4520545545205041 53203B4F29
ok je ferai ca demain matin j'avais penser a ca mais je voulais pas me lancer au dessous car je dois changer le circuit un travail de plus
mais demain je le ferai pour mettre fin a cette sugestion pourpasser a autre chose
merci vede et bonne week end et bonne nuit
On met SDA à 0 avant !
Puis on met 0 dans le trisC pour avoir 0, et 1 pour avoir 1 .
C'est la résistance de rappel qui fait le 1 puisque la sortie est en haute impédance.
///////////////////////:
char i2csendbyte(char msg)
{
char count;
SDA=0;
SCL=0;
i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time
SDA=0; //-- Ensure Port pin is low
for(count=8;count>0;count--) //-- Send 8 bits of data
{
if( (msg & 0x80)== 0) //-- Get the Bit
{
SDA_TRIS=0; //-- Lower pin if bit = 0
}
else
{
SDA_TRIS=1; //-- Release pin if bit = 1
}
msg=msg<<1; //-- Shift next bit into position
i2cclock(); //-- Pulse the clock
}
SDA_TRIS=1; //-- Release data pin for ACK
return(1);
}
1.5mhz c'est la fréquence du quartz ou l'accès max à l'eeprom ?si oui est ce que quelqu'un peut me calculerr les valeurs des tempo avec mon oscillateur ou bien juste m'explique comment faire la conversion des valeurs de 20MHZ a 1.5 MHZ
Si c'est le quartz , ça sera simplement plus lent.
Si c'est le 24C il faudra bien 15 instructions entre la monté et la descente du clock pour un accés à 1.5mhz.
ça parait beaucoup, normalement c'est 100khz ou 500khz pour un 24Cxx
donc entre 40 et 200 instructions à 20mhz.
et 3 à 15 instructions avec un quartz 1.5mhz.
pour cette votre de ce poste j'ai un oscillateur a 1.5MHZ (circuit RC)1.5mhz c'est la fréquence du quartz ou l'accès max à l'eeprom ?
Si c'est le quartz , ça sera simplement plus lent.
Si c'est le 24C il faudra bien 15 instructions entre la monté et la descente du clock pour un accés à 1.5mhz.
ça parait beaucoup, normalement c'est 100khz ou 500khz pour un 24Cxx
donc entre 40 et 200 instructions à 20mhz.
et 3 à 15 instructions avec un quartz 1.5mhz.
pour le probleme dans la fonction i2csendbyte();
j'arrive pas a bien saisir votre remarques
est ce que je dois modifier ma fonction ou bien c'est deja fait???
1.5mhz c'est la fréquence du quartz ou l'accès max à l'eeprom ?
Si c'est le quartz , ça sera simplement plus lent.
Si c'est le 24C il faudra bien 15 instructions entre la monté et la descente du clock pour un accés à 1.5mhz.
ça parait beaucoup, normalement c'est 100khz ou 500khz pour un 24Cxx
donc entre 40 et 200 instructions à 20mhz.
et 3 à 15 instructions avec un quartz 1.5mhz.donc d'apres votre remarques mon code doit etre comme ca
Code:if( (msg & 0x80)== 0) //-- Get the Bit { SDA_TRIS=0; //-- Lower pin if bit = 0 } else // j'enleve cette else avec l'instruction SDA_tris=1; { SDA_TRIS=1; //-- Release pin if bit = 1 et } msg=msg<<1; //-- Shift next bit into position i2cclock(); //-- Pulse the clock }
le code est bon , mais il y a rien à enlever
et mettre SDA=0 avant la boucleelse // j'enleve cette else avec l'instruction SDA_tris=1;
0X80 test le bit 7 et met 1 ou 0 sur le port
après on décal <<1 pour voir le bit suivant
8 fois
le post#35 est corrigé.
j'ai pas bien compris est ce que je dois modifier cette partie ou bien non car
j'arrive pas a suivre
si il y a des modifications a faire ?indique moi ou ca doit etre et merci
merci vraiment FREEPICBASIC
mon code fonction maintenant j'arrriva voir des donnees envoyees sur ma memoire
mais il y a un warning dans le simulation log dans ISIS
"I2CMEM: STOP condition whilst is transmiting data is unreliable"
merci encore une fois a tout le monde
manque l'ack avant le stop
tu devrais le mettre dans les procédures d'écriture et de lecture, ça ferait gagner du code et éviterait les oublis
sortie=i2cgetbyte();//lit la donnee
i2cgetack();
i2cstop();
merci je vais l'ajouter
ca marche nickel
merci a tout le monde pour votre aides
a la prochaine pour une nouvelle aventure