Liaison I2C pour un PIC 18F2550
Répondre à la discussion
Affichage des résultats 1 à 12 sur 12

Liaison I2C pour un PIC 18F2550



  1. #1
    invite9ddd7dfb

    Liaison I2C pour un PIC 18F2550


    ------

    Salut,
    Je rencontre des problèmes afin de réaliser ma liaison I2C entre mon PIC 18F2550 et mon accéléromètre LIS3LV02DL.
    Je n'ai pas de quartz, j'utilise l'horloge interne du PIC.

    Je pense que mon code est bon mais je ne vois rien à l'oscilloscope sur ma ligne SDA.

    Voilà mon code. Je vous remercie d'avance.

    #include <p18f2550.h>
    #include "i2c.h"

    #pragma config WDT = OFF //Watchdog désactivé
    #pragma config MCLRE = OFF //désactiver la pin de Reset
    #pragma config LVP = OFF //Low Voltage Programming désactivé => RB5 I/O normale
    #pragma config FOSC = INTOSCIO_EC//Internal oscillator, port function on RA6, EC used by USB



    void initialisation(void)
    {
    //configuration horloge interne du pic à 32 MHz
    OSCCON = 0x70; //pas de prédiviseur => 8MHz
    OSCTUNE = 0x40; //activer la PLL *4 => 32MHz

    //désactiver le convertisseur analogique numerique
    ADCON1=0x0F;

    //désactiver le module CCP
    CCP1CON=0;

    //direction des ports 0=Output, 1= Input
    TRISBbits.TRISB0=1; //SDA
    TRISBbits.TRISB1=1; //SCL
    TRISBbits.TRISB4 = 0;//LED verte
    }

    unsigned char ReadAccelerometre(unsigned char Registre)
    {
    unsigned char bRet = 0x00;
    IdleI2C(); //Attente du bus OK
    StartI2C(); //Envoi de message de début(envoie du ST)
    IdleI2C(); //Attente de la disponibilité du bus
    WriteI2C(0x1D); //Envoi de l'adresse de l'accéléromètre 0(écrire)+(0011101)
    IdleI2C(); //Attente de la disponibilité du bus
    WriteI2C(Registre); //Envoi du registre a lire
    IdleI2C();
    RestartI2C();//SR
    WriteI2C(0x9D);
    if (SSPCON2bits.ACKSTAT) //Si AckStat == 1, on n'a pas reçu d'acquittement
    {
    StopI2C(); //Envoi de la condition de stop
    return bRet;
    }
    bRet = ReadI2C(); //Lecture I2C
    NotAckI2C(); //Pas d'acquittement car on lit qu'un seul caractère
    IdleI2C();
    StopI2C(); //Envoi du stop
    return bRet; //Retour de la valeur lue
    }


    unsigned char donnee;


    void main ()
    {
    initialisation(); //initialisation du PIC


    while(1){

    OpenI2C(MASTER,SLEW_OFF); //Overture de l'I2C en master mode
    PORTBbits.RB4 = 1;
    donnee=ReadAccelerometre(0xAC) ;//ici 1(read))+OUTZ_L(0101100)


    }

    }

    -----

  2. #2
    invitee05a3fcc

    Re : Liaison I2C pour un PIC 18F2550

    Bonjour Mika56 et bienvenue sur FUTURA

    Une simple question : tu as des PullUP sur SDA et SCL ?

  3. #3
    invite7a49d0d5

    Cool Re : Liaison I2C pour un PIC 18F2550

    Salut,

    il faut "configurer" les ports SDA et SCL en sorties (Output)... et non pas en entrées...

    vede
    ;O]
    __________________
    ...

  4. #4
    invite9ddd7dfb

    Re : Liaison I2C pour un PIC 18F2550

    salut DAUDET78 oui j'ai bien mis des pull up sur SDA et SCL

    salut vede, j'ai configurer mes ports SDA et SCL en sortie( je sais pas pourquoi je les avais mis en entrée). J'ai tester mais toujours pareil!

    Je n'ai rien sur ma ligne SDA et sur ma ligne SDL j'ai ça(voir PJ)

    Cela vient peut être de la configuration de mon horloge interne.

    merci de vos réponses et de l'acceuil.
    Images attachées Images attachées  

  5. A voir en vidéo sur Futura
  6. #5
    invite7a49d0d5

    Cool Re : Liaison I2C pour un PIC 18F2550

    re ;O]

    le registre OSCTUNE n'a rien à voir avec la PLL...
    il permet juste de "régler finement" la fréquence de l'oscillateur...
    autour de sa "fondamentale", exemple OSCON = 8Mhz,
    OSCTUNE permet un réglage "fin" entre environ 7.9 et 8.1 Mhz...

    essaie de désactiver la PLL, afin d'avoir FOsc = 8Mhz
    et donc de "ralentir" le tout... car peut-être que 32Mhz
    est trop rapide pour faire fonctionner ta librairie I2C...

  7. #6
    invitee05a3fcc

    Re : Liaison I2C pour un PIC 18F2550

    Citation Envoyé par Mika56 Voir le message
    Je n'ai rien sur ma ligne SDA et sur ma ligne SDL j'ai ça(voir PJ)
    et sur ta ligne SDA, tu n'as pas une goutte de soudure qui coince ? Retire tous les périphériques sur SDA et, hors tension, mesure la résistance SDA versus 0V.

  8. #7
    invite9ddd7dfb

    Re : Liaison I2C pour un PIC 18F2550

    vede: ok merci pour l'explication, je testerai ça demain de désactiver la PLL.

    DAUDET78: normalement j'avais vérifié toutes mes connexions. SDA est à "1" avec le PULL UP. Mais je ne peux pas pas enlever mon accéléromètre c'est du CMS et il est souder dans ma carte.
    Mais je vérifierai ça demain qd même.

    Merci de votre aide!! J'espère que ça va fonctionner!!

  9. #8
    RISC

    Re : Liaison I2C pour un PIC 18F2550

    Salut,

    Avant de vouloir faire des choses plus sophistiquées, il faut écrire un tout petit programme qui bascule les broches (SDA et SCL) en sortie.
    De cette manière tu confimeras que ces broches sont OK.

    ensuite, il ne faut pas toucher à OSCTUN à moins de vouloir faire quelquechose de spécial. Ce registre est utilisé pour ajuster l'oscillateur RC interne de façon à avoir 4 ou 8MHz (voir la spec) avec +/- 1% à 25C.
    Si tu fais de l'USB, je suppose de toute façon que tu utilises un oscillateur externe (quartz, résonnateur ou TCXO).

    Tu trouveras des exemples de code I2C pour les PIC18 ici (filtre par famille PIC18).

    a+

  10. #9
    invite9ddd7dfb

    Re : Liaison I2C pour un PIC 18F2550

    Bonjour à tous le monde,

    Alors j'ai testé vos conseils, j'ai tout d'abord vérifier mes soudures elles sont ok.
    J'ai désactivé la PLL avec cette ligne :
    #pragma config PLLDIV = 1 //No prescale (4 MHz oscillator input drives PLL directly)
    et enlevé cette ligne de mon programme:
    OSCTUNE = 0x40; //activer la PLL *4 => 32MHz

    mais toujours rien

    RISC: merci pour le lien, je l'avais déjà mais je vais me replonger dedans pour vois si j'ai pas loupé quelque chose. Par contre, je ne comprend pas ton idée de petit programme qui bascule les broches en sortie.
    Et je n'utilise pas de quartz car je n'ai pas d'usb, je suis en UART, les données que je récupère de l'accéléromètre vont vers un module Bluetooth.

    merci de vos réponses.

  11. #10
    invite9ddd7dfb

    Re : Liaison I2C pour un PIC 18F2550

    J'ai réussi à résoudre le problème, il y avait des registres à initialiser : SSPSTAT, SSPCON1, SSPCON2, SSPADD
    Par contre mon programme, n'arrive pas encore à lire dans les registres de mon accéléromètre.



    Code PHP:
    #include <p18f2550.h>
    #include "i2c.h"

    #pragma config WDT = OFF          //Watchdog désactivé
    #pragma config MCLRE = OFF       //désactiver la pin de Reset
    #pragma config LVP = OFF           //Low Voltage Programming désactivé => RB5 I/O normale
    #pragma config FOSC = INTOSCIO_EC//Internal oscillator, port function on RA6, EC used by USB  
    #pragma config PLLDIV = 1         //No prescale (4 MHz oscillator input drives PLL directly) 




    void initialisation(void)
    {
        
    //configuration horloge interne du pic à 32 MHz
        
    OSCCON 0x70;        //pas de prédiviseur => 8MHz
        //OSCTUNE = 0x40;        //
        
        //désactiver le convertisseur analogique numerique
        
    ADCON1=0x0F;
        
        
    //désactiver le module CCP
        
    CCP1CON=0;
        
        
    SSPSTAT=0b10000000
        
    SSPCON1=0x28;
        
    SSPCON2=0x00;
        
    SSPADD=0xF0;
        
        
    //direction des ports 0=Output, 1= Input 
        
    TRISBbits.TRISB0=0//SDA
        
    TRISBbits.TRISB1=0//SCL
        
    TRISBbits.TRISB4 0;//LED verte
        
    OpenI2C(MASTER,SLEW_OFF); //Overture de l'I2C en master mode



    void tempo(unsigned int compte)
    {
    while(
    compte--);
    }


    unsigned char ReadAccelerometre(unsigned char Registre)
    {
    unsigned char bRet 0x00;
    IdleI2C(); //Attente du bus OK
    tempo(10000);
    StartI2C(); //Envoi de message de début(envoie du ST)
    tempo(10000);
    IdleI2C(); //Attente de la disponibilité du bus
    tempo(10000);
    WriteI2C(0x3A); //Envoi de l'adresse de l'accéléromètre (0011101)+0(écrire)
    tempo(10000);
    IdleI2C(); //Attente de la disponibilité du bus
    tempo(10000);
    WriteI2C(Registre); //Envoi du registre a lire 
    tempo(10000);
    IdleI2C();
    tempo(10000);
    RestartI2C();//SR
    tempo(10000);
    WriteI2C(0x3B);//Envoi de l'adresse de l'accéléromètre (0011101)+1(lire)
        
    if (SSPCON2bits.ACKSTAT//Si AckStat == 1, on n'a pas reçu d'acquittement
        
    {
            
    PORTBbits.RB4 1;
            
    StopI2C(); //Envoi de la condition de stop
            
    return bRet;
        }
    bRet ReadI2C(); //Lecture I2C
    NotAckI2C(); //Pas d'acquittement car on lit qu'un seul caractère
    IdleI2C();
    StopI2C(); //Envoi du stop
    return bRet//Retour de la valeur lue








    unsigned char donnee;


    void main ()
    {
        
        
    initialisation();        //initialisation du PIC
        
        
        //while(1){

    donnee=ReadAccelerometre(0xAC);//ici 1(read))+OUTZ_L(0101100)


        //        }



  12. #11
    RISC

    Re : Liaison I2C pour un PIC 18F2550

    Salut,

    Tu as dit que tu utilises aussi l'UART ? Avec l'oscillateur interne ?
    Si c'est le cas tu vas avoir de serieux problèmes car l'oscillateur interne n'a pas une précision suffisante pour être utilisé pour l'UART. La norme prévoit normalement 4% max de différence c'est à dire +/-2% max de chaque coté.
    Cette valeur n'est atteignable que si ton PIC reste autour de 25C et que tu n'aies pas changé sa calibration d'origine.
    Si tu veux que ton système fonctionne dans une gamme de température plus large, il faut utiliser un résonnateur céramique ou un quartz ou alors changer de PIC pour un modèle ayant des tolérances plus serrées sur l'oscillateur interne comme le PIC18F14K50 (+/-2% de 0 à 85C).

    a+

  13. #12
    invite9ddd7dfb

    Re : Liaison I2C pour un PIC 18F2550

    Ok merci Risc mais je crois que je vais rester comme ça pour l'instant, je rajouterai un quartz si j'ai le temps.

    Sinon j'ai bien mes informations sur ma ligne SDA mais par contre il les envoie plusieurs fois et je ne comprends pas pourquoi.

    Voici le code : j'essaye juste d'envoyer une fois l'adresse de l'accéléromètre 3A mais à l'oscillo je le vois toutes les 7 ms.

    Code:
    #include <p18f2550.h>
    #include "i2c.h"
    
    #pragma config WDT = OFF 		 //Watchdog désactivé
    #pragma config MCLRE = OFF       //désactiver la pin de Reset
    #pragma config LVP = OFF  		 //Low Voltage Programming désactivé => RB5 I/O normale
    #pragma config FOSC = INTOSCIO_EC//Internal oscillator, port function on RA6, EC used by USB  
    #pragma config PLLDIV = 1		 //No prescale (4 MHz oscillator input drives PLL directly) 
    
    
    
    
    void initialisation(void)
    {
        //configuration horloge interne du pic à 32 MHz
        OSCCON = 0x70;        //pas de prédiviseur => 8MHz
        //OSCTUNE = 0x40;        //
        
        //désactiver le convertisseur analogique numerique
    	ADCON1=0x0F;
    	
    	//désactiver le module CCP
        CCP1CON=0;
        
        
        SSPSTAT=0b10000000; 
        SSPCON1=0x28;
        SSPCON2=0x00;
        SSPADD=0xF0;
        
        //direction des ports 0=Output, 1= Input 
        TRISBbits.TRISB0=0; //SDA
    	TRISBbits.TRISB1=0; //SCL
    	TRISBbits.TRISB4 = 0;//LED verte
    	OpenI2C(MASTER,SLEW_OFF); //Overture de l'I2C en master mode
    } 
    
    
    void tempo(unsigned int compte)
    {
    while(compte--);
    }
    
    
    unsigned char ReadAccelerometre(unsigned char Registre)
    {
    unsigned char bRet = 0x00;
    IdleI2C(); //Attente du bus OK
    
    StartI2C(); //Envoi de message de début(envoie du ST)
    
    IdleI2C(); //Attente de la disponibilité du bus
    WriteI2C(0x3A); //Envoi de l'adresse de l'accéléromètre (0011101)+0(écrire)
    tempo(1000);
    PORTBbits.RB4 = 1;
    return bRet; //Retour de la valeur lue
    }
    et le main
    Code:
    void main ()
    {
    	
        initialisation();        //initialisation du PIC
        
        ReadAccelerometre(0xAC);//ici 1(read))+OUTZ_L(0101100)
    
    }
    Merci de vos réponses

Discussions similaires

  1. PIC 18F2550 pour l' USB
    Par invite1feace2e dans le forum Électronique
    Réponses: 7
    Dernier message: 26/05/2011, 23h34
  2. Liaison I2C entre deux PIC (Maître -Esclace)
    Par invite0c16129b dans le forum Électronique
    Réponses: 3
    Dernier message: 14/04/2010, 17h38
  3. Probleme liaison I2C PIC 16F877
    Par invitecd367060 dans le forum Électronique
    Réponses: 8
    Dernier message: 18/03/2009, 08h17
  4. emulation i2c pour pic en C
    Par invite0490cd3a dans le forum Électronique
    Réponses: 17
    Dernier message: 19/03/2008, 10h23
  5. I2c Pour Pic 16f84a
    Par invite1a81daeb dans le forum Électronique
    Réponses: 1
    Dernier message: 27/09/2006, 00h14
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...