1. #1
    Membre habitué
    Homme Profil pro
    Technicien Layout
    Inscrit en
    août 2015
    Messages
    213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : août 2015
    Messages : 213
    Points : 188
    Points
    188

    Par défaut Macro, structure, fonction

    Bonjour, en ce moment je travaille sur un projet dans lequel j'essaye d'utiliser un capteur de proximité le VL6180X, j'ai récupéré l'API sur st.com et comme a mon habitude j'essaye de comprendre le code en mode debugger...
    Il y a une partie que j'ai du mal a comprendre et c'est pour cette raison que je viens sur le forum afin de trouver une ou plusieurs âmes charitable...

    Donc je pars de cette fonction:

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #ifdef VL6180x_HAVE_UPSCALE_DATA
    	VL6180xDevDataSet(dev, UpscaleFactor,  DEF_UPSCALE);
    #endif

    les trois arguments sont respectivement l'adresse du device - le paramètre a activer - la valeur du paramètre

    Plus haut dans le code on retrouve la mm fonction mais en #define:

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #if VL6180x_SINGLE_DEVICE_DRIVER
    extern  struct VL6180xDevData_t SingleVL6180xDevData;
    #define VL6180xDevDataGet(dev, field) (SingleVL6180xDevData.field)
    #define VL6180xDevDataSet(dev, field, data) SingleVL6180xDevData.field = (data)
    #endif

    VL6180x_SINGLE_DEVICE_DRIVER est bien défini a 1 dans mon code donc on exécute cette condition. Par contre je ne comprends pas ce que le define fait par exemple a la ligne 4 "#define VL6180xDevDataSet(dev, field, data) SingleVL6180xDevData.field = (data)"?

    Comme on peut le voir dans le morceau de code précédent SingleVL6180xDevData est une structure externe:

    Code C : 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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    /**
     * @struct VL6180xDevData_t
     *
     * @brief Per VL6180x device St private data structure \n
     * End user should never access any of these field directly
     *
     * These must never access directly but only via VL6180xDev/SetData(dev, field) macro
     */
    struct VL6180xDevData_t {
     
    	uint32_t Part2PartAmbNVM;  /*!< backed up NVM value */
    	uint32_t XTalkCompRate_KCps; /*! Cached XTlak Compensation Rate */
     
    	uint16_t EceFactorM;        /*!< Ece Factor M numerator  */
    	uint16_t EceFactorD;        /*!< Ece Factor D denominator*/
     
    	struct RangeIgnoreData_t RangeIgnore;
     
    #ifdef VL6180x_HAVE_ALS_DATA
    	uint16_t IntegrationPeriod; /*!< cached als Integration period avoid slow read from device at each measure */
    	uint16_t AlsGainCode;       /*!< cached Als gain avoid slow read from device at each measure */
    	uint16_t AlsScaler;         /*!< cached Als scaler avoid slow read from device at each measure */
    #endif
     
    #ifdef VL6180x_HAVE_UPSCALE_DATA
    	uint8_t UpscaleFactor;      /*!<  up-scaling factor*/
    #endif
     
    #ifdef VL6180x_HAVE_WRAP_AROUND_DATA
    	uint8_t WrapAroundFilterActive; /*!< Filter on/off */
    	struct FilterData_t FilterData; /*!< Filter internal data state history ... */
    #endif
     
    #if VL6180x_CACHED_REG
    	uint8_t CacheFilled;             /*!< Set if valid data got fetched use to control when to fill up register cache */
    	uint8_t CachedRegs[VL6180x_CACHED_REG_CNT];          /*!< Cache register storage */
    #endif
    #if VL6180x_HAVE_DMAX_RANGING
    	struct DMaxData_t DMaxData;
    	uint8_t DMaxEnable;
    #endif
    	int8_t  Part2PartOffsetNVM;     /*!< backed up NVM value */
    };

    Bon ok on lit dans les commentaires qu'il ne faut pas attaquer directement cette structure mais plutot utiliser la macro VL6180xDev/SetData(dev, field) bon on est content mais pas plus avancé pour comprendre ce code...

    Pour résumer j'essaye surtout de comprendre ce que fait:

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define VL6180xDevDataGet(dev, field) (SingleVL6180xDevData.field)
    #define VL6180xDevDataSet(dev, field, data) SingleVL6180xDevData.field = (data)

    Merci pour votre aide.

  2. #2
    Expert éminent
    Avatar de Auteur
    Profil pro
    Inscrit en
    avril 2004
    Messages
    6 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2004
    Messages : 6 660
    Points : 9 463
    Points
    9 463

    Par défaut

    bonsoir,

    ce sont des macros c.developpez.com/faq/?page=Le-preprocesseur

    A mon avis tu n'as qu'un seul composant VL6180X sinon tu ne passerais pas la condition #if VL6180x_SINGLE_DEVICE_DRIVER
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    extern  struct VL6180xDevData_t SingleVL6180xDevData;
    tu définis ainsi une variable SingleVL6180xDevData de type struct VL6180xDevData_
    Ensuite, pour accéder aux paramètres de cette structure, une fonction est définie avec # define : chaque fois que le préprocesseur "verra" dans ton code VL6180xDevDataSet(dev, field, data) il le remplacera par SingleVL6180xDevData.field = (data). La variable dev n'est visiblement pas nécessaire dans ce cas car tu as 1 seul composant (il doit exister une valeur par défaut ici).


    Dans le cas où tu possèdes plusieurs composants cette condition n'est pas réalisée et tu appelles directement la fonction VL6180xDevDataSet(dev, UpscaleFactor, DEF_UPSCALE);. Les programmeurs font ainsi une économie de code : soit tu appelles la fonction soit une macro qui remplit directement les champs de la structure.

  3. #3
    Membre habitué
    Homme Profil pro
    Technicien Layout
    Inscrit en
    août 2015
    Messages
    213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : août 2015
    Messages : 213
    Points : 188
    Points
    188

    Par défaut

    Citation Envoyé par Auteur Voir le message
    bonsoir,

    ce sont des macros c.developpez.com/faq/?page=Le-preprocesseur

    A mon avis tu n'as qu'un seul composant VL6180X sinon tu ne passerais pas la condition #if VL6180x_SINGLE_DEVICE_DRIVER
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    extern  struct VL6180xDevData_t SingleVL6180xDevData;
    tu définis ainsi une variable SingleVL6180xDevData de type struct VL6180xDevData_
    Ensuite, pour accéder aux paramètres de cette structure, une fonction est définie avec # define : chaque fois que le préprocesseur "verra" dans ton code VL6180xDevDataSet(dev, field, data) il le remplacera par SingleVL6180xDevData.field = (data). La variable dev n'est visiblement pas nécessaire dans ce cas car tu as 1 seul composant (il doit exister une valeur par défaut ici).


    Dans le cas où tu possèdes plusieurs composants cette condition n'est pas réalisée et tu appelles directement la fonction VL6180xDevDataSet(dev, UpscaleFactor, DEF_UPSCALE);. Les programmeurs font ainsi une économie de code : soit tu appelles la fonction soit une macro qui remplit directement les champs de la structure.
    Merci pour la réponse et le lien (instructif)

    Comme tu l'as fait remarqué j'utilise un seul capteur:

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /**
     * @def VL6180x_SINGLE_DEVICE_DRIVER
     * @brief enable lightweight single vl6180x device driver
     *
     * value 1 =>  single device capable
     * Configure optimized APi for single device driver with static data and minimal use of ref pointer \n
     * limited to single device driver or application in non multi thread/core environment \n
     *
     * value 0 =>  multiple device capable user must review "device" structure and type in porting files
     * @ingroup Configuration
     */
    #define VL6180x_SINGLE_DEVICE_DRIVER 1

    Gestion single ou multi:

    vl6180x_platform.h:

    Code C : 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
    18
    #if  VL6180x_SINGLE_DEVICE_DRIVER
        typedef uint8_t VL6180xDev_t;
     
    #else /* VL6180x_SINGLE_DEVICE_DRIVER */
     
        struct MyVL6180Dev_t {
            struct VL6180xDevData_t Data;
        #if I2C_BUFFER_CONFIG == 2
            uint8_t i2c_buffer[VL6180x_MAX_I2C_XFER_SIZE];
            #define VL6180x_GetI2cBuffer(dev, n) ((dev)->i2c_buffer)
        #endif
        };
        typedef struct MyVL6180Dev_t *VL6180xDev_t;
     
    #define VL6180xDevDataGet(dev, field) (dev->Data.field)
    #define VL6180xDevDataSet(dev, field, data) (dev->Data.field)=(data)
     
    #endif /* #else VL6180x_SINGLE_DEVICE_DRIVER */

  4. #4
    Expert éminent
    Avatar de Auteur
    Profil pro
    Inscrit en
    avril 2004
    Messages
    6 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2004
    Messages : 6 660
    Points : 9 463
    Points
    9 463

    Par défaut

    On le voit bien dans le .h que tu as posté :

    un capteur :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    #define VL6180xDevDataSet(dev, field, data) SingleVL6180xDevData.field = (data)
    plusieurs capteurs :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    #define VL6180xDevDataSet(dev, field, data) (dev->Data.field)=(data)
    même fonction mais affectation différente.

  5. #5
    Expert confirmé
    Avatar de Vincent PETIT
    Homme Profil pro
    Ancien développeur matériel électronique (Hard/Soft)
    Inscrit en
    avril 2002
    Messages
    1 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ancien développeur matériel électronique (Hard/Soft)
    Secteur : Service public

    Informations forums :
    Inscription : avril 2002
    Messages : 1 483
    Points : 4 401
    Points
    4 401

    Par défaut

    Salut,
    En complément des réponses, de qualités, de Auteur.

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define VL6180xDevDataGet(dev, field) (SingleVL6180xDevData.field)
    #define VL6180xDevDataSet(dev, field, data) SingleVL6180xDevData.field = (data)
    Ci dessus ceux sont les Getter / Setter qu'on retrouve dans la programmation objet. Comprendre respectivement "lire le composant ou plutôt le champs field de la structure" / "écrire dans le composant ou plutôt dans le champs field de la structure". C'est pour cette raison qu'il y a ce genre de commentaire.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    /**
     * @struct VL6180xDevData_t
     *
     * @brief Per VL6180x device St private data structure
     * End user should never access any of these field directly
     *
     * These must never access directly but only via VL6180xDev/SetData(dev, field) macro
     */
    On te demande d'utiliser les macro #define VL6180xDevDataGet et #define VL6180xDevDataSet pour lire est écrire dans la structure qui définie les champs du composant.



    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #if VL6180x_SINGLE_DEVICE_DRIVER
         extern  struct VL6180xDevData_t SingleVL6180xDevData;
         #define VL6180xDevDataGet(dev, field) (VL6180xDevData_t.field)
         #define VL6180xDevDataSet(dev, field, data) VL6180xDevData_t.field = (data)
    #endif
    Ci dessus, ce qui est indenté entre le #if et le #endif est défini que si VL6180x_SINGLE_DEVICE_DRIVER vaut 1.


    Donc si on fait un petit résumé, le même que Auteur (en #2) on a ça :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    struct VL6180xDevData_t {
     
    	uint32_t Part2PartAmbNVM;  /*!< backed up NVM value */
    	[...]
    	int8_t  Part2PartOffsetNVM;     /*!< backed up NVM value */
    };
     
    VL6180xDevData_t SingleVL6180xDevData;
     
     
    /* lire dans la structure, un champs */
    #define VL6180xDevDataGet(dev, field) (SingleVL6180xDevData.field)
     
    /* écrire dans la structure, un champs */
    #define VL6180xDevDataSet(dev, field, data) SingleVL6180xDevData.field = (data)

    VL6180xDevData_t est une structure.
    SingleVL6180xDevData est une variable de type structure du dessus.
    Tous les chaînes de caractères qui seront égales à VL6180xDevDataGet(dev, field) vont être replacées, dans le source du programme, par SingleVL6180xDevData.field on remarquera que le champs dev ne sert a rien dans le cas d'un seul capteur voir ce que Auteur a écrit juste avant moi.

    Voilà
    A+ Julien

  6. #6
    Membre habitué
    Homme Profil pro
    Technicien Layout
    Inscrit en
    août 2015
    Messages
    213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : août 2015
    Messages : 213
    Points : 188
    Points
    188

    Par défaut

    Eh bien merci pour vos explications, c'est bien plus clair a présent. Quel plaisir de revenir sur le forum afin d'échanger avec des passionnés. C'est la première question mais je pense qu'il va y en avoir beaucoup d'autre .

    je vous retrouve la ou je vous ai quitté il y a quelques mois excellent...

    Vincent les enfants vont bien ?


    A+

  7. #7
    Expert confirmé
    Avatar de Vincent PETIT
    Homme Profil pro
    Ancien développeur matériel électronique (Hard/Soft)
    Inscrit en
    avril 2002
    Messages
    1 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ancien développeur matériel électronique (Hard/Soft)
    Secteur : Service public

    Informations forums :
    Inscription : avril 2002
    Messages : 1 483
    Points : 4 401
    Points
    4 401

    Par défaut

    Hey Hey....

    Emmy,
    Fanny,
    Valentin,
    Manon

    Se portent à merveille merci. Bande de sales gosses C'est du sport par moment !!!!


    Et je me marie dans 2 mois

    Et toi la famille ?

  8. #8
    Membre habitué
    Homme Profil pro
    Technicien Layout
    Inscrit en
    août 2015
    Messages
    213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : août 2015
    Messages : 213
    Points : 188
    Points
    188

    Par défaut

    Félicitation pour le futur mariage. Chez nous tout le monde va bien, au plus ils grandissent et au plus ils font des bêtises, la normalité quoi...
    Toujours pas décidé de venir faire un tour dans le sud-est ? ( on a une chambre de libre )

    Ce soir je vous rebalance du code car j'ai un petit soucis avec l'exemple. la nucleo(L476-RG) + shield(X-nucleo6180xa1 version 2) fonctionne bien. ==>http://www.st.com/content/st_com/en/...o-6180xa1.html

    Mais dans mon projet je n'utilise pas ce shield mais un VL6180X-satellite ==> http://www.st.com/en/evaluation-tool...80x-satel.html donc j'essaye de bricoler le code exemple pour que cela fonctionne avec le satellite et uniquement lui. La grosse différence avec le shield c'est qu'il y a un afficheur 7 segments et un expander qui gère l'afficheur ainsi que les pins d'interruption car on peut ajouter 3 satel sur ce shield.

    Pour l'instant je suis bloqué car en connectant mon satel avec le mapping approprié (je pense avoir le bon mapping idem shield version 1) avec mon analyseur logique je ne récupère aucune trame I2C... Par contre si je mets le shield version 2 la je récupère bien une trame I2C sur SCL/SDA.

    Bon j'ai conscience que c'est rès vague comme info mais j'essaye d'etre plus concret ce soir.

  9. #9
    Expert confirmé
    Avatar de Vincent PETIT
    Homme Profil pro
    Ancien développeur matériel électronique (Hard/Soft)
    Inscrit en
    avril 2002
    Messages
    1 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ancien développeur matériel électronique (Hard/Soft)
    Secteur : Service public

    Informations forums :
    Inscription : avril 2002
    Messages : 1 483
    Points : 4 401
    Points
    4 401

    Par défaut


    Alors à ce soir ! Pense a mettre le sujet en Résolu si c'est bon pour cette question.

    ++

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VBA-E] Lancement d'une macro en fonction du contenu d'une cellule
    Par Zak Blayde dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 30/01/2007, 15h13
  2. [Macro] Exécuter une macro en fonction d'un contrôle
    Par sugan dans le forum VBA Access
    Réponses: 6
    Dernier message: 02/10/2006, 16h02
  3. Macro en fonction d'une sélection de plage de cellules.
    Par Labiche dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 08/08/2006, 10h23
  4. [VBA-E] macro avec fonction "TRANSPOSE"
    Par Ardeciel dans le forum Macros et VBA Excel
    Réponses: 20
    Dernier message: 12/06/2006, 16h11
  5. choix entre macro et fonction
    Par remi77 dans le forum C
    Réponses: 4
    Dernier message: 22/10/2003, 14h26

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