Aller au contenu


Photo
- - - - -

I2c? MPLAB? Comment ça marche..


  • Veuillez vous connecter pour répondre
4 réponses à ce sujet

#1 alass27

alass27

    Nouveau membre

  • Membres
  • 3 messages

Posté 12 avril 2011 - 10:14

Bonsoir,

Je suis actuellement étudiant a l'institut universitaire et
technologique en GEII à Cachan et j'aimerais que vous m’éclairiez
sur le fonctionnement du port i2c,j'ai pour but de créer un programme
afin de détecter des obstacles grâce a un capteur SRF10 ultrason à l'aide d'un microcontroleur PIC18F4550
mais le problème c'est que je n'arrive pas à comprendre le fonctionnement d'un port i2c
je vu qu'il y avait beaucoup de notions à comprendre et qu'il y'avait une bibliothèque toute faite
pour la programmation mais si je ne comprend pas la base du fonctionnement de l'i2c
la programmation n'est pas possible !
Si quelqu'un peut m'aider ça m'avancerait pas mal lol :)

Cordialement

#2 alass27

alass27

    Nouveau membre

  • Membres
  • 3 messages

Posté 14 avril 2011 - 02:18

Help please!

#3 Jbot

Jbot

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 801 messages
  • Gender:Male
  • Location:Paris

Posté 14 avril 2011 - 02:27

http://fr.wikipedia.org/wiki/I2C

En gros c'est un bus série, tu envoie l'adresse, puis la data pour une écriture, ou l'adresse et tu attends la data dans le cas d'une lecture.


Malédiction du Créatif :
Plus vous avez d’idées et moins vous arrivez à les structurer.


#4 alass27

alass27

    Nouveau membre

  • Membres
  • 3 messages

Posté 17 avril 2011 - 06:49

Merci pour la réponse !
Mais je ne vois toujours pas comment faire =s
ça m'a l'air compliqué à gérer l'i2c !
tous que je veux c'est récupérer la distance
d'un obstacle avec un capteur SRF10 ultrason j'ai retourner
internet pour trouver des bon exemples mais sans résultat lol
je ne vois pas comment faire, ce que nous avions utilisé comme
capteur au premier semestre étaient des capteurs analogiques.
Si quelqu'un de bien calé en i2c peut m'aider ça serait sympas.

#5 Guillaume TDRIS

Guillaume TDRIS

    Membre

  • Membres
  • 49 messages
  • Gender:Male
  • Location:Saint Soupplet

Posté 08 mai 2011 - 12:27

Si tu veux j'ai une librairie pour l'i2C en langage C pour un 18F4550

Voila le .c

#include <p18F4550.h>
#include "i2c.h"
#include "LCD_I2C.h"
#include "delays.h"

#define vitesse_I2C 400000 // I2C a 100Khz (pas touche...)
#define FOSC 48000000 // microcontroleur à 48 Mhz

#define v (FOSC/4*vitesse_I2C)-1

//-------------------------------------------------------------------------------------------------------------------------
// Définition et initialisation des variables de type structuré "I2C_CONTROL"

I2C_CONTROL GYRO_EEPROM = {Gyro_EEaddr, Gyro_EEaddr<<1, (Gyro_EEaddr<<1)|1 };
I2C_CONTROL GYRO_MG1101 = {Gyro_MG1101addr, Gyro_MG1101addr<<1, (Gyro_MG1101addr<<1)|1 };


void Init_I2C(void)
{

SSPSTAT &= 0x3F; // power on state
SSPCON1 = 0x00; // power on state
SSPCON2 = 0x00; // power on state
SSPCON1 |= SLAVE_7; // select serial mode
SSPSTAT |= 0; // slew rate on/off
DDRBbits.RB1 = 1; // Set SCL (PORTB,1) pin to input
DDRBbits.RB0 = 1; // Set SDA (PORTB,0) pin to input
SSPCON1 |= SSPENB; // enable synchronous serial port
SSPADD = 0x20<<1; // slave address
SSPCON1bits.CKP = 1; // no clock

PIE1bits.SSPIE = 1; // autorisation de l'interruption de l'i2c
IPR1bits.SSPIP = 0; // I2C en basse priorité
PIR1bits.SSPIF = 0; // on déactive le bit SSPIF pour permettre a l'interruption d'avoir lieu

}
/*********************************************************************/
#undef StartI2C
void StartI2C( void )
{
SSPCON2bits.SEN = 1; // initiate bus start condition
}

/*******************************************************************/
#undef IdleI2C
void IdleI2C( void )
{
while ( ( SSPCON2 & 0x1F ) | ( SSPSTATbits.R_W ) )
continue;
}

/*******************************************************************/
signed char putsI2C( unsigned char *wrptr )
{
while ( *wrptr ) // transmit data until null character
{
if ( SSPCON1bits.SSPM3 ) // if Master transmitter then execute the following
{
if ( putcI2C ( *wrptr ) ) // write 1 byte
{
return ( -3 ); // return with write collision error
}
IdleI2C(); // test for idle condition
if ( SSPCON2bits.ACKSTAT ) // test received ack bit state
{
return ( -2 ); // bus device responded with NOT ACK
} // terminate putsI2C() function
}

else // else Slave transmitter
{
PIR1bits.SSPIF = 0; // reset SSPIF bit
SSPBUF = *wrptr; // load SSPBUF with new data
SSPCON1bits.CKP = 1; // release clock line
while ( !PIR1bits.SSPIF ); // wait until ninth clock pulse received

if ( ( !SSPSTATbits.R_W ) && ( !SSPSTATbits.BF ) )// if R/W=0 and BF=0, NOT ACK was received
{
return ( -2 ); // terminate PutsI2C() function
}
}

wrptr ++; // increment pointer

} // continue data writes until null character

return ( 0 );
}


/*******************************************************************/
unsigned char ReadI2C( void )
{
SSPCON2bits.RCEN = 1; // enable master for 1 byte reception
while ( !SSPSTATbits.BF ); // wait until byte received
return ( SSPBUF ); // return with read byte
}


/*******************************************************************/
#undef StopI2C
void StopI2C( void )
{
SSPCON2bits.PEN = 1; // initiate bus stop condition
}

/*******************************************************************/
#undef AckI2C
void AckI2C( void )
{
SSPCON2bits.ACKDT = 0; // set acknowledge bit state for ACK
SSPCON2bits.ACKEN = 1; // initiate bus acknowledge sequence
}

//////////////////////////////////
unsigned char TestAck()
{
if ( !SSPCON2bits.ACKSTAT ) // test la condition ACK=0
return I2C_SUCCESS; // retourne avec pas d'erreur sur le bit acknowledge ACKSTAT
else
return I2C_ERROR; // retourne avec erreur sur le bit acknowledge ACKSTAT
}


/*******************************************************************/
unsigned char WriteI2C( unsigned char data_out )
{
SSPBUF = data_out; // write single byte to SSPBUF
if ( SSPCON1bits.WCOL ) // test if write collision occurred
return ( -1 ); // if WCOL bit is set return negative #
else
{
while( SSPSTATbits.BF ); // wait until write cycle is complete
return ( 0 ); // if WCOL bit is not set return non-negative #
}
}


char EMByteWrite( unsigned char *pTxData, unsigned short Length )
{
int ii;
IdleI2C(); // ensure module is idle
StartI2C(); // initiate START condition
while ( SSPCON2bits.SEN ); // wait until start condition is over
if ( PIR2bits.BCLIF ) // test for bus collision
{
return ( -1 ); // return with Bus Collision error
}
else // start condition successful
{
if ( WriteI2C( *pTxData ) ) // write byte - R/W bit should be 0
{
return ( -3 ); // set error for write collision
}
pTxData++;
for( ii = 1; ii<Length; ii++ )
{
IdleI2C(); // ensure module is idle
if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
{
// PORTB|=0b00001100;
if ( WriteI2C( *pTxData ) ) // write word address for EEPROM
{
// PORTB&=0b11111011;
return ( -3 ); // set error for write collision
}
pTxData++;
}
else
{
// PORTB|=0b00000001;
return ( -2 ); // return with Not Ack error condition
ii=Length;
}
}

IdleI2C(); // ensure module is idle
StopI2C(); // send STOP condition
while ( SSPCON2bits.PEN ); // wait until stop condition is over
if ( PIR2bits.BCLIF ) // test for bus collision
{
return ( -1 ); // return with Bus Collision error
}
return ( 0 ); // return with no error
}
}


unsigned char PageRead( unsigned char control, unsigned char address, unsigned char *rdptr, unsigned char length )
{
unsigned char status;


IdleI2C(); // ensure module is idle
StartI2C(); // initiate START condition
while ( SSPCON2bits.SEN ); // wait until start condition is over

WriteI2C( control<<1 ); // write 1 byte

IdleI2C();
status = TestAck(); // ensure module is idle

if( status == I2C_SUCCESS )
{
WriteI2C( address ); //The register memory address (used to address the 16 bytes in MG1101 RAM)
// is internally incremented following the receipt of each data word.
IdleI2C();
status = TestAck();

if( status == I2C_SUCCESS )
{
RestartI2C(); // generate I2C bus restart condition
while ( SSPCON2bits.RSEN ); // wait until re-start condition is over

WriteI2C( (control<<1) | 1 );// WRITE 1 byte - R/W bit should be 1 for read

IdleI2C();
status = TestAck();

if( status == I2C_SUCCESS )
{
while ( length )
{
*rdptr++ = ReadI2C(); // save byte received

length--;

if(length)
AckI2C();
else
NotAckI2C();

while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
}

StopI2C(); // send STOP condition
while ( SSPCON2bits.PEN );// wait until stop condition is over
}
}
}

return status;
}


unsigned char PageWrite( unsigned char control, unsigned char address, unsigned char *pData, unsigned char length ) //EEPageWrite
{
unsigned char addr=0, status;

IdleI2C(); // ensure module is idle
StartI2C(); // initiate START condition
while ( SSPCON2bits.SEN ); // wait until start condition is over

WriteI2C( control ); // write 1 byte

IdleI2C();
status = TestAck(); // ensure module is idle


if( status == I2C_SUCCESS )
{
WriteI2C( address ); //The register memory address (used to address the 16 bytes in MG1101 RAM)
// is internally incremented following the receipt of each data word.
IdleI2C();
status = TestAck();
}

while( (status == I2C_SUCCESS) && (addr<length) ) // test for ACK condition, if received
{
WriteI2C( *pData++ );

IdleI2C();
status = TestAck();
addr++;
}

StopI2C(); // réalise une condition de stop sur le bus I2C
while( SSPCON2bits.PEN );

Delay10KTCYx(5); // temps d'attente de 50ms

return status;
}



unsigned char ByteWrite( unsigned char control, unsigned char address, unsigned char data )
{
unsigned char status;

IdleI2C(); // ensure module is idle
StartI2C(); // initiate START condition
while ( SSPCON2bits.SEN ); // wait until start condition is over

WriteI2C( control );

IdleI2C();
status = TestAck(); // ensure module is idle

if( status == I2C_SUCCESS )
{
WriteI2C( address ); //The register memory address (used to address the 16 bytes in MG1101 RAM)
// is internally incremented following the receipt of each data word.
IdleI2C();
status = TestAck();

if( status == I2C_SUCCESS )
{
WriteI2C( data );
IdleI2C();
status = TestAck();
}
}

StopI2C(); // send STOP condition
while ( SSPCON2bits.PEN ); // wait until stop condition is over

Delay10KTCYx(5); // temps d'attente de 50ms

return status;
}


unsigned char ByteRead( unsigned char control, unsigned char address )
{
unsigned char status, data;

IdleI2C(); // ensure module is idle
StartI2C(); // initiate START condition
while ( SSPCON2bits.SEN ); // wait until start condition is over

WriteI2C( control<<1 );

IdleI2C();
status = TestAck(); // ensure module is idle

if( status == I2C_SUCCESS )
{
WriteI2C( address ); //The register memory address (used to address the 16 bytes in MG1101 RAM)
// is internally incremented following the receipt of each data word.
IdleI2C();
status = TestAck();

if( status == I2C_SUCCESS )
{
RestartI2C(); // generate I2C bus restart condition
while ( SSPCON2bits.RSEN );// wait until re-start condition

WriteI2C( (control<<1) | 1 );
IdleI2C();
status = TestAck();

if( status == I2C_SUCCESS )
{
data = ReadI2C(); // enable master for 1 byte reception
NotAckI2C(); // send ACK condition
while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
}
}
}

StopI2C(); // send STOP condition
while ( SSPCON2bits.PEN ); // wait until stop condit

return ( data );
}


Et voila le .h associé

/* PIC18 I2C peripheral library header */

/* SSPCON1 REGISTER */
#define SSPENB 0x20 /* Enable serial port and configures
SCK, SDO, SDI */
#define SLAVE_7 6 /* I2C Slave mode, 7-bit address */
#define SLAVE_10 7 /* I2C Slave mode, 10-bit address */
#define MASTER 8 /* I2C Master mode */

/* SSPSTAT REGISTER */
#define SLEW_OFF 0xC0 /* Slew rate disabled for 100kHz mode */
#define SLEW_ON 0x00 /* Slew rate enabled for 400kHz mode */

//-------------------------------------------------------------------------------------------------------------------------
// Modèle de structure de control I2C

typedef struct
{
unsigned char addr;
unsigned char write;
unsigned char read;
}I2C_CONTROL;

//-------------------------------------------------------------------------------------------------------------------------
// Variables de type structuré importées du fichier "i2c.c"

extern I2C_CONTROL GYRO_EEPROM;
extern I2C_CONTROL GYRO_MG1101;


//-------------------------------------------------------------------------------------------------------------------------
// Adresse des modules I2C

#define Gyro_EEaddr 0b1010000
#define Gyro_MG1101addr 0b1010111


//-------------------------------------------------------------------------------------------------------------------------
// I2C bus states

#define I2C_SUCCESS 1
#define I2C_ERROR 0

#define StopI2C() SSPCON2bits.PEN=1
#define StartI2C() SSPCON2bits.SEN=1
#define RestartI2C() SSPCON2bits.RSEN=1
#define NotAckI2C() SSPCON2bits.ACKDT=1, SSPCON2bits.ACKEN=1
#define AckI2C() SSPCON2bits.ACKDT=0, SSPCON2bits.ACKEN=1
#define IdleI2C() while ((SSPCON2 & 0x1F) | (SSPSTATbits.R_W))
#define CloseI2C() SSPCON1 &=0xDF
#define DataRdyI2C() (SSPSTATbits.BF)
#define getcI2C ReadI2C
#define putcI2C WriteI2C

void Init_I2C(void);
unsigned char WriteI2C( unsigned char data_out );
unsigned char ReadI2C( void );
unsigned char TestAck( void );

unsigned char ByteWrite( unsigned char control, unsigned char address, unsigned char data );
unsigned char ByteRead( unsigned char control, unsigned char address );
unsigned char PageWrite( unsigned char control, unsigned char address, unsigned char *pData, unsigned char length );
unsigned char PageRead( unsigned char control, unsigned char address, unsigned char *rdptr, unsigned char length );





Ça date méchamment... De mémoire ce protocole est assez pénible à faire marcher. Regarde au moins la méthode d'initialisation celle la elle fonctionne c'est sur.




0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users