IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Lire des words à la place de bytes (fonction I2C)


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Juin 2007
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 61
    Par défaut Lire des words à la place de bytes (fonction I2C)
    Bonjour à tous,
    je programme en C un microcontroleur. Je souhaite communiqué avec un capteur en I2C. Il y a deja une librairie de faite pour le capteur et et j'ai besoin d'utiliser dans cette librairie:
    i2c_readByte(SLAVE_ADDR_L, DEV_ID_REG, &val[0]);
    i2c_readWord(SLAVE_ADDR_L, MAN_ID_REG, &readBackVal[0]);
    i2c_writeWord(SLAVE_ADDR_L, RCOUNT_CH0_REG, PROXIMITY_REFCOUNT);

    J'ai le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    void i2c_writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *value)
    {
        uint8_t i=0;
        I2C_MasterSendStart(devAddr, I2C_WRITE_XFER_MODE);
        I2C_MasterWriteByte(regAddr);
        while (i++ < length) {
            I2C_MasterWriteByte(((uint8_t)*value) >> 8);
            I2C_MasterWriteByte((uint8_t)*value++);
        }
        I2C_MasterSendStop();
    }
     
    void i2c_writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t value)
    {
        i2c_writeWords(devAddr, regAddr, 1, &value);
    }
    et le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    void I2CReadBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *value)
    {
        uint8_t i=0;
        I2C_MasterSendStart(devAddr, I2C_WRITE_XFER_MODE);
        I2C_MasterWriteByte(regAddr);
        I2C_MasterSendRestart(devAddr, I2C_READ_XFER_MODE);
        while (i++ < (length-1)) {
            *value++ = I2C_MasterReadByte(I2C_ACK_DATA);
        }
        *value = I2C_MasterReadByte(I2C_NAK_DATA);
        I2C_MasterSendStop();
    }
     
    void i2c_readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *value)
    {
        I2CReadBytes(devAddr, regAddr, 1, value);
    }
    Mais je bloque pour le i2c_readWord qui doit être finalement la récupération de 2 bytes:
    Si j'essaye:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void i2c_readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *value)
    {
        uint16_t result = 0;
        uint8_t b;
        I2C_MasterSendStart(devAddr, I2C_WRITE_XFER_MODE);
        I2C_MasterWriteByte(regAddr);
        I2C_MasterSendRestart(devAddr, I2C_READ_XFER_MODE);
        b = I2C_MasterReadByte(I2C_ACK_DATA) << 8;
        *value = b + I2C_MasterReadByte(I2C_ACK_DATA);
        I2C_MasterSendStop();
    }
    en mettant bien un uint16_t *value en parametre , plus tard dans une des fonction j'ai un warning:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void Sensor_checkDevice(void)
    {
        uint8_t val[1] = {0};
        uint8_t readBackVal[2] = {0};
        uint16_t data = 0;
    
        i2c_readByte(SLAVE_ADDR_L, DEV_ID_REG, &val[0]);
        i2c_readWord(SLAVE_ADDR_L, MAN_ID_REG, &readBackVal[0]); <---------INCOMPATIBLE POINTER TYPE PASSING Uint8_t to Uint16_t
    
        data = ((uint16_t) (readBackVal[0] << 8) | readBackVal[1]);
    }
    Merci pour votre aide, c'est peu être simple mais je bloque

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    readBackVal devrait être déclaré comme uint16_t et utilisé comme suit:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void Sensor_checkDevice(void)
    {
        uint8_t val[1] = {0};
        uint16_t readBackVal = 0;
        uint16_t data = 0;
     
        i2c_readByte(SLAVE_ADDR_L, DEV_ID_REG, &val[0]);
        i2c_readWord(SLAVE_ADDR_L, MAN_ID_REG, &readBackVal); <---------INCOMPATIBLE POINTER TYPE PASSING Uint8_t to Uint16_t
     
        data = readBackVal;
    }

    Il faut aussi corriger readWord:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void i2c_readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *value)
    {
        uint16_t result = 0;
        uint8_t b;
        I2C_MasterSendStart(devAddr, I2C_WRITE_XFER_MODE);
        I2C_MasterWriteByte(regAddr);
        I2C_MasterSendRestart(devAddr, I2C_READ_XFER_MODE);
        b = I2C_MasterReadByte(I2C_ACK_DATA);
        result = b << 8;
        *value = result + I2C_MasterReadByte(I2C_ACK_DATA);
        I2C_MasterSendStop();
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Pourquoi ne pas lire directement &data?

    Pour des problèmes de boutisme (endianess)?

  4. #4
    Membre confirmé
    Inscrit en
    Juin 2007
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 61
    Par défaut
    Merci bien
    mais le soucis c'est que toute la librairie est codé comme ca, ce qui veux dire que si je mets uint16_t, il faut que je change toutes les uint8_tde la librairie...
    Pas top comme solution

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void checkDevice(void)
    {
        uint8_t val[1] = {0};
        uint8_t readBackVal[2] = {0};
        uint16_t data = 0;
     
        i2c_readByte(SLAVE_ADDR_L, DEV_ID_REG, &val[0]);
        i2c_readWord(SLAVE_ADDR_L, MAN_ID_REG, &readBackVal[0]);
     
        data = ((uint16_t) (readBackVal[0] << 8) | readBackVal[1]);
    }
    Finalement, est ce que la meilleur solution ce serait pas de laissé uint8_t *value et d'écrire le MSB dans la premiere case value[0] et le LSB dans la deuxieme case value[1] pour que le reste de la librairie soit correcte
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void i2c_readWord(uint8_t devAddr, uint8_t regAddr, uint8_t *value)
    {
        uint16_t result = 0;
        uint8_t b;
        I2C_MasterSendStart(devAddr, I2C_WRITE_XFER_MODE);
        I2C_MasterWriteByte(regAddr);
        I2C_MasterSendRestart(devAddr, I2C_READ_XFER_MODE);
        value[0] = I2C_MasterReadByte(I2C_ACK_DATA);
     
        value[1] = I2C_MasterReadByte(I2C_ACK_DATA);
        I2C_MasterSendStop();
    }
    Ca me parait trop simple :s

  5. #5
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 252
    Par défaut
    Salut Sasuke1234,
    On dirait une question très mal posé

    Tu ne veux pas plutôt dire simplement : Comment utilise t-on une telle fonction dans un programme en C ?
    void i2c_readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *value)




    ps : Dans la fonction void i2c_readWord le retour d'une donnée sur 16 bits est déjà implémenté.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     ...
     ...
     b = I2C_MasterReadByte(I2C_ACK_DATA) << 8;
     *value = b + I2C_MasterReadByte(I2C_ACK_DATA);
     ...

    Pourquoi essayes tu de le refaire dans ton programme ?
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    data = ((uint16_t) (readBackVal[0] << 8) | readBackVal[1]);




    Et si tu fais simplement ça ?
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void Sensor_checkDevice(void)
    {
        uint16_t data = 0;
        uint16_t *pointeur_data = data;
     
        i2c_readWord(SLAVE_ADDR_L, MAN_ID_REG, pointeur_data);
     
        /* data contient un mot de 16 bits issu du bus I2C */ 
    }

  6. #6
    Membre confirmé
    Inscrit en
    Juin 2007
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 61
    Par défaut
    Salut,
    désolé je si je suis pas très claire dans mes explications,
    dans la librairie C qui est donné avec le capteur, il y a pleins de fonctions:
    par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    uint32_t readMeasProxSensor(void)
    {
    	uint8_t readBackVal[2] = {0};
    	uint16_t dataMSB = 0;
    	uint16_t dataLSB = 0;
     
    	//CH0 measurement
    	i2c_readWord(SLAVE_ADDR_L, DATA_MSB_CH0_REG, &readBackVal[0]);	//MSB
    	dataMSB = (((uint16_t) (readBackVal[0] << 8)) | readBackVal[1]) & ~(0xF000);			//Mask the upper 4 bits
     
    	i2c_readWord(SLAVE_ADDR_L, DATA_LSB_CH0_REG, &readBackVal[0]);	//LSB
    	dataLSB = (((uint16_t) readBackVal[0] << 8)) | readBackVal[1];			//Mask the upper 4 bits
     
    	return ( (((uint32_t) dataMSB) << 16) | dataLSB);
    }
    ou encore

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void clearDRDY(void)
    {
    	//Clearing the DRDY bit when INTB interrupt occurs by reading STATUS reg
    	uint8_t readBackVal[2] = {0};
     
    	i2c_readWord(SLAVE_ADDR_L, STATUS_REG, &readBackVal[0]);
    }
    Le truc c'est que les fonctions i2c vont dépendre de l'environnement de développement, c'est donc a chacun de faire la sienne.

    C'est pourquoi j'ai besoin de la fonction i2c_readWord qui marche avec toutes les fct de la librairie, de sorte de pas à avoir modifier plusieurs lignes de code (c'est plus claire dans ma tête déjà)
    Donc en faite si je veux que ca marche pour toutes les fonctions, il faut en paramètre (uint8_t devAddr, uint8_t regAddr, uint8_t value)
    puis dans ma fonction readWord, je met le premier octet dans la case 0 et le deuxieme octet dans la case 1

    Make sense?

  7. #7
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 252
    Par défaut
    Salut,
    Citation Envoyé par Sasuke1234 Voir le message
    désolé je si je suis pas très claire dans mes explications
    Non, non, autant pour moi ! C'est moi qui avait mal compris ta demande et je m'en excuse.

    - Tu as une bibliothèque bizarrement implémenté, peut être pour la raison que ternel évoque ?
    - Et tu ne peux pas réctifier l'implémentation comme Médinoc te l'a montré.

    Je ne sais pas comment t'aider.

    Désolé,
    Bon courage.

Discussions similaires

  1. [SimpleXML] Lire des données en fonction de valeurs d%u2019attributs
    Par Oswalde dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 06/03/2010, 18h15
  2. Lire des fichiers Word en Html "FireFox"
    Par dot-_-net dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 30/08/2009, 14h36
  3. Réponses: 1
    Dernier message: 18/03/2009, 16h03
  4. Fonction pour lire des nombres dans un fichier
    Par passant_ dans le forum Débuter
    Réponses: 11
    Dernier message: 28/10/2008, 18h47
  5. Lire des byte avec Scanner
    Par ToTo13 dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 25/01/2007, 15h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo