Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Problème I2C
Asterix
Membre
Membre
Messages : 18
Âge : 21
Enregistré en : janvier 2017

#1 Message par Asterix » lun. 13 mars 2017 15:13 lien vers la Data-Sheet : Cliquez ici

Bonjour,
Je suis en train d'essayer de faire marcher l'I2C sur un pic18F452, le problème c'est que mon programme semble être bloqué dans ma fonction Init_boussole.
J'ai aussi regardé à l'oscilloscope et apparemment je n'ai pas de signal sortant de la pin SCL, il ne doit pas en avoir une par hasard :sad: ?

Voici mon programme:

main:

Code : Tout sélectionner

#include <p18f452.h>
#include "fonctions.h"
#include "PWM_fonc.h"

#pragma config OSC = HS, OSCS = OFF
#pragma config PWRT = OFF, BOR = OFF
#pragma config WDT = OFF
#pragma config CCP2MUX = ON
#pragma config STVR = ON
#pragma config LVP = OFF
#pragma config DEBUG = ON
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF, CPB = OFF, CPD = OFF
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTRB = OFF




void main(void)
{
    unsigned char vision;
    char vitesse_droit;
    char vitesse_gauche;
    float position;

    LATB = 0x0f;                //  allumer 4 bits faibles sur PORTB
    TRISB = 0xF0;                // 4 bits faibles PORTB en sortie

    Init_ADC();
    Init_PWM();
    Init_I2C();
    Init_boussole();

    vitesse_droit = 0xFF;
    vitesse_gauche = 0xFF;

    MOT_G_Avant();
    MOT_D_Avant();




    while(1)
    {
        
        position 
= Gest_Bouss();

        if (position > 50)
        {
            vitesse_gauche=0x10;
            vitesse_droit=0x10;
        }

        /*ADCON0=0b01000001;          //MILIEU
        vision = conversion();

        if (vision >= 20)
        {
            vitesse_gauche=0x00;
            vitesse_droit=0x00;
        }

        else
        {
            vitesse_gauche=0x80;
            vitesse_droit=0x80;
        }

        ADCON0=0b01001001;              //COTE DROIT
        vision = conversion();

        if (vision >= 20)
        {
            vitesse_gauche=0x00;

        }

        else
        {
            vitesse_gauche=0x80;
            vitesse_droit=0x80;
        }

        ADCON0=0b01010001;              //COTE GAUCHE
        vision = conversion();

        if (vision >= 20)
        {

            vitesse_droit=0x00;
        }

        else
        {
            vitesse_gauche=0x80;
            vitesse_droit=0x80;
        }
        */



        VITESSE_MOT_G=vitesse_gauche;
        VITESSE_MOT_D=vitesse_droit;



    }

    return;
}



I2C:

Code : Tout sélectionner

#include <p18f452.h>
#include <math.h>
#include <delays.h>
#include "fonctions.h"
#include "PWM_fonc.h"


void Init_I2C(void)
{

        TRISCbits.TRISC4 = 1;      // data direction SDA
    TRISCbits.TRISC3 = 1;      // data direction SCL

    SSPCON1=0x28;    // no collision,0, SSPEN Enable I2C, 0, I2C master, I2C master clock=Fosc/(4*SSPADD+1)
    SSPSTATbits.SMP=1;    // pas de slew rate control (standard speed mode)
    SSPADD=0x05;        // 166Khz

        return;
}

void Init_boussole(void)    //mesure en continue
{

    SSPCON2bits.SEN = 1; //start
    while (SSPCON2bits.SEN==1);    // attente raz en fin du start
    SSPBUF=0x3C;    // envoie adresse du chip HMC5883 en write
    while (SSPCON2 & 0x1F)  ; // attente bus IDLE (5 bits faibles à 0)
    while (SSPSTATbits.R_W ==1)    ; // attente fin d'envoi
    while (SSPCON2bits.ACKSTAT == 1); //  attente ACK recu
    SSPBUF=0x02;    // envoie octet 02 en write pour acces au registre de mode
    while (SSPCON2 & 0x1F)  ; // attente bus IDLE (5 bits faibles à 0)
    while (SSPSTATbits.R_W ==1)    ; // attente fin d'envoi
    while (SSPCON2bits.ACKSTAT == 1); //  attente ACK recu
    SSPBUF=0x00;    // envoie octet 00 en write dans registre de mode pour mesure en continu
    while (SSPCON2 & 0x1F)  ; // attente bus IDLE (5 bits faibles à 0)
    while (SSPSTATbits.R_W ==1)    ; // attente fin d'envoi
    while (SSPCON2bits.ACKSTAT == 1); //  attente ACK recu
    SSPCON2bits.PEN=1;    // envoi du stop
    while (SSPCON2bits.PEN == 1); //  attente fin du stop

    Delay1KTCYx(50);    // delay = 5mS

    return;
}

float Gest_Bouss(void)
{
        // gestion boussole HMC5883
        // écriture octet de commande et lecture de la réponse :(voir DATA SHEET "READ BYTE FORMAT")
            int X,Y,Z,x,y,= 0;                // raz variables recues
                        char x1=; // On place les 8 MSBs de x
                        char y1=; // On place les 8 MSBs de x
                        float teta;

            SSPCON2bits.SEN=1;    // start
            while (SSPCON2bits.SEN==1);    // attente raz en fin du start
            SSPBUF=0x3C;    // envoie adresse du chip HMC5883 en write
            while (SSPCON2 & 0x1F)  ; // attente bus IDLE (5 bits faibles à 0)
            while (SSPSTATbits.R_W ==1)    ; // attente fin d'envoi
            while (SSPCON2bits.ACKSTAT == 1); //  attente ACK recu
            SSPBUF=0x03;    // envoie octet 03 en write pour acces au registre X
            while (SSPCON2 & 0x1F)  ; // attente bus IDLE (5 bits faibles à 0)
            while (SSPSTATbits.R_W ==1)    ; // attente fin d'envoi
            while (SSPCON2bits.ACKSTAT == 1); //  attente ACK recu
            SSPCON2bits.PEN=1;    // envoi du stop
            while (SSPCON2bits.PEN == 1); //  attente fin du stop

            SSPCON2bits.SEN=1;    // start
            while (SSPCON2bits.SEN==1);    // attente raz en fin du start
            SSPBUF=0x3D;    // envoie adresse du chip HMC5883 en read
            while (SSPCON2 & 0x1F)  ; // attente bus IDLE (5 bits faibles à 0)
            while (SSPSTATbits.R_W ==1)    ; // attente fin d'envoi
            while (SSPCON2bits.ACKSTAT == 1); //  attente ACK recu

            SSPCON2bits.RCEN=1;        // passe en mode réception
            while (SSPCON2bits.RCEN == 1); //  attente octet de réception
            X=SSPBUF;        // récup caractère reçu
            SSPCON2bits.ACKDT=0;    // positionne ACK
            SSPCON2bits.ACKEN=1;    // envoi
            while (SSPCON2bits.ACKEN == 1); //  attente fin du ACK
            SSPCON2bits.RCEN=1;        // passe en mode réception
            while (SSPCON2bits.RCEN == 1); //  attente octet de réception
            x=SSPBUF;        // récup caractère reçu
            SSPCON2bits.ACKDT=0;    // positionne ACK
            SSPCON2bits.ACKEN=1;    // envoi
            while (SSPCON2bits.ACKEN == 1); //  attente fin du ACK
            SSPCON2bits.RCEN=1;        // passe en mode réception
            while (SSPCON2bits.RCEN == 1); //  attente octet de réception
            Z=SSPBUF;        // récup caractère reçu
            SSPCON2bits.ACKDT=0;    // positionne ACK
            SSPCON2bits.ACKEN=1;    // envoi
            while (SSPCON2bits.ACKEN == 1); //  attente fin du ACK
            SSPCON2bits.RCEN=1;        // passe en mode réception
            while (SSPCON2bits.RCEN == 1); //  attente octet de réception
            z=SSPBUF;        // récup caractère reçu
            SSPCON2bits.ACKDT=0;    // positionne ACK
            SSPCON2bits.ACKEN=1;    // envoi
            while (SSPCON2bits.ACKEN == 1); //  attente fin du ACK
            SSPCON2bits.RCEN=1;        // passe en mode réception
            while (SSPCON2bits.RCEN == 1); //  attente octet de réception
            Y=SSPBUF;        // récup caractère reçu
            SSPCON2bits.ACKDT=0;    // positionne ACK
            SSPCON2bits.ACKEN=1;    // envoi
            while (SSPCON2bits.ACKEN == 1); //  attente fin du ACK
            SSPCON2bits.RCEN=1;        // passe en mode réception
            while (SSPCON2bits.RCEN == 1); //  attente octet de réception
            y=SSPBUF;        // récup caractère reçu
            SSPCON2bits.ACKDT=1;    // positionne NACK  Non ACK pour le dernier octet lu !!!!
            SSPCON2bits.ACKEN=1;    // envoi
            while (SSPCON2bits.ACKEN == 1); //  attente fin du NACK
            SSPCON2bits.PEN=1;    // envoi du stop
            while (SSPCON2bits.PEN == 1); //  attente fin du stop

            // concaténation
            
            x1
=x1 << 8;
            x1=x1 | x;//On place les 8 LSBs de x

            
            y1
=y1<<8;
            y1=y1 | y;//On place les 8 LSBs de x

            // calcul angle
            teta = ((-atan2(y1,x1)*180)/3.14159265359)+180;   //angle par rapport au nord








        Delay10KTCYx(30);            // delay = 30 * 10 000 cycles temps de visu des caracteres



    return teta;
}


Merci d'avance pour votre aide :)

Problème I2C
Jérémy
Administrateur du site
Administrateur du site
Messages : 2123
Âge : 39
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#2 Message par Jérémy » lun. 13 mars 2017 16:13 lien vers la Data-Sheet : Cliquez ici

Bonjour Asterix ,

Je n'ai pas encore eu le plaisir de faire de l'I2C avec des pics . Mais ça ne serait pas trop tarder, car beaucoup de modules utilisent ce mode de communication !

As tu bien les deux pull Up sur les lignes SDA SCL ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Problème I2C
Asterix
Membre
Membre
Messages : 18
Âge : 21
Enregistré en : janvier 2017

#3 Message par Asterix » lun. 13 mars 2017 16:28 lien vers la Data-Sheet : Cliquez ici

Bonjour Jérémy,
oui j'ai bien les résistances.
J'ai aussi réussit à avoir ce que je devais avoir sur les pins de la scl. Du coup je pense que le problème vient du programme mais je ne sais pas encore où :sifflotte: .

Problème I2C
Temps-x
Avatar de l’utilisateur
Confirmé
Confirmé
Messages : 902
Enregistré en : juillet 2016
Localisation : Terre

#4 Message par Temps-x » lun. 13 mars 2017 16:43 lien vers la Data-Sheet : Cliquez ici

Bonjour

Attention, il y a une adresse à mettre en place !!

comme pour une mémoire 24CXX


A+
Quand la souris nargue le chat, c'est que son trou n'est pas loin.

Problème I2C
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 1063
Âge : 68
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#5 Message par paulfjujo » lun. 13 mars 2017 19:32 lien vers la Data-Sheet : Cliquez ici

bonsoir


Code : Tout sélectionner


    TRISCbits
.TRISC3 = 1;      // data direction SCL  



SCL doit etre en sortie ..donc TRISC.B3=0;
seul SDA peut basculer de sortie à entree lors de la reponse de l'esclave


de meme pour les 4 sorties

Code : Tout sélectionner

    
    LATB 
= 0x0f;                //  allumer 4 bits faibles sur PORTB
    TRISB = 0xF0;                // 4 bits faibles PORTB en sortie

il est preferable de mettre d'abord les Pins en Sortie
avant d'
envoyer une commande dessus

[code=php]    
    TRISB 
= 0xF0;                // 4 bits faibles PORTB en sortie[/code]
    LATB = 0x0f;                //  allumer 4 bits faibles sur PORTB

Problème I2C
Asterix
Membre
Membre
Messages : 18
Âge : 21
Enregistré en : janvier 2017

#6 Message par Asterix » mar. 14 mars 2017 23:35 lien vers la Data-Sheet : Cliquez ici

Bonjour,

Merci à tous pour vos réponses, je m'excuse de ne pas vous avoir répondu plus tôt mais en ce moment je suis en train de réviser pour des concours, j’essaierais dès que possible vos conseils et je vous tiendrait informé.

Problème I2C
Asterix
Membre
Membre
Messages : 18
Âge : 21
Enregistré en : janvier 2017

#7 Message par Asterix » mer. 15 mars 2017 17:59 lien vers la Data-Sheet : Cliquez ici

Bonjour,
j'ai vérifier sur la datasheet et la sortie SCL doit bien être réglé en entrée.
J'ai aussi vérifier à l'oscillo et je reçois bien ce que je devrais recevoir sur la SCL.
En faite j'essaie de recevoir des données d'une boussole HMC5883L mais je reçois des valeurs erronées (par exemple 3 à un instant puis à l'autre instant 208 pour la même position).


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité