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 :

macro : créer des boucles => possible ?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 854
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 854
    Par défaut macro : créer des boucles => possible ?
    Bonjour,

    Je voudrais générer ce genre de code à l'aide de macro :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    toto1 = 1;
    toto2 = 1;
    toto3 = 1;
    toto4 = 1;
    ...
    Est-il possible de le générer automatiquement à l'aide de macro (éviter de me taper toutes les lignes à la main) ?

    Pour l'écriture d'une ligne je pensais partir sur cette méthode. Mais je ne vois pas comment faire pour faire n fois l'itération
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define MAKE_TOTO(x)    totox = 1
    #define MAKE_TOTO(x)    toto ## x = 1
    // => quelle est la différence entre les deux méthodes ? les deux fonctionnent ?

  2. #2
    Membre chevronné Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Par défaut
    Bonjour,

    Je ne vois pas trop l'intérêt de faire ça...

    Pourquoi ne pas utiliser un tableau?

    Décrit un peu plus ton problème qu'on puisse t'aiguiller au mieux.

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 854
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 854
    Par défaut
    C'est pour gagner de la taille en code car je programme sur un µControlleur 32 bits.
    J'essaye de voir ce qu'on peut faire avec les macros pour avoir un code facilement configurable.
    => je voudrais à l'aide de #define définir les voies qui sont à mesurer

    J'essaye de faire une programme qui mesure des valeurs sur des voies analogiques.

    Je voudrais à l'aide de #define activer les voies analogiques à mesurer. Donc voici un code simplifier ce qu'il faudrait faire pour l'initialisation :

    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
    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    void anaInit(void){
     
    	// *******************************************
    	// configuration des I/O => input
    	TRISBbits.TRISB0 = 1; AD1PCFGbits.PCFG0 = 0;	// active voie 0
    	TRISBbits.TRISB1 = 1; AD1PCFGbits.PCFG1 = 0;	// active voie 1
    	TRISBbits.TRISB2 = 1; AD1PCFGbits.PCFG2 = 0;	// active voie 2
    	// ...
    	TRISBbits.TRISB15 = 1; AD1PCFGbits.PCFG15 = 0;	// active voie 15
    	// Remarque : on peut aussi ecrire directement dans les registres en utilisant : TRISB et AD1PCFG (registres de 16 bits);
    	//		=> cette méthode serait prévérable car on pourrait tout configurer en un seul coup (=> gain de code)
    	//		=> exemple : 
    	//			TRISB =  MASK_BIT0 | MASK_BIT1 | ... | MASK_BIT15 | TRISB;
    	//			AD1PCFG =  0xFFFF & (~MASK_BIT0) & (~MASK_BIT1) & ... & (~MASK_BIT15);
     
     
     
    	// *******************************************
    	// activation des mesure
    	AD1CSSLbits.CSSL0 = 1;	// active voie 0
    	AD1CSSLbits.CSSL1 = 1;	// active voie 1
    	// ...
    	AD1CSSLbits.CSSL15 = 1;	// active voie 15
     
     
     
    	// *******************************************
    	// configuration du nombre de voies à mesurer
    	// => mesure de 16 voies
    	AD1CON2bits.SMPI = 15; // => valeur = n - 1 
    }
     
     
     
    static unsigned long tabVal[16]; // unsigned long : taille 64 bits (8 octets)
     
    // récupère les valeurs
    void anaGet(void){
     
    	// création des pointeurs
    	// unsigned int : taille 32 bits (4 octets)	
    	unsigned int *ptReg;
    	unsigned int i;
     
    	static nb_mesures = 0;
     
     
    	// ****************************************
    	// réinitialisation des valeurs
    	if (nb_mesures == 0){
    		for(i=0; i<16; i++){
    			tabVal[i] = 0; 
    		}
    	}
     
     
    	// ****************************************
    	// récupération des valeurs
     
    	// les valeurs à lire sont dans les registres ADC1BUF0, ADC1BUF1, ..., ADC1BUFA, ADC1BUFB, .... , ADC1BUFF
    	// => ce sont des registres de 32 bits (4 octets)
    	// Remarque : les adresses des registres se suivent
    	ptReg = &ADC1BUF0;
     
     
    	for(i=0; i<16; i++){
    		// récupération des valeurs
    		// => on cumule les valeurs récupérées pour pouvoir faire un moyennage
    		tabVal[i] += *ptReg; 
     
    		ptReg++; // incrémentation du pointeur
    	}
     
     
    	// ****************************************
    	// gestion du moyennage
    	nb_mesures++;
    	if (nb_mesures == 8){
     
    		// division par 8 des valeurs
    		for(i=0; i<16; i++){
    			tabVal[i] >>= 3; 
    		}
    		nb_mesures = 0;
     
     
    		// ****************
    		// affectation des valeurs à des variables globales
    		// => code spécifique à l'application
    		// => il peut y avoir des calculs de conversion
    		temperature = tabVal[0];
    		alimentation = tabVal[1];
    		// ...
    		humidite = tabVal[15];
    	}
     
     
    }

    Attention : dans la fonction anaGet(), pour les registres ADC1BUFx, 'x' ne représente pas le numéro de la voie qui à été mesurée mais le numéro de la mesure. Exemple : ADC1BUF0 => mesure n°0, ADC1BUF5 => mesure n°5, ADC1BUFA => mesure n°10, ...

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 854
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 854
    Par défaut
    J'ai commencé à faire la fonction d'initialisation

    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
    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
     
    // **************************************************
    //     Configuration
    // **************************************************
     
    // Définir les voies à échantilloner
    // => mettre en commentaire les voies non utilisées
    // Remarque : toutes les voies analogiques sont sur le port B
    //#define AN0_ENB
    #define AN1_ENB
    #define AN2_ENB
    //#define AN3_ENB
    #define AN4_ENB
    #define AN5_ENB
    #define AN6_ENB
    #define AN7_ENB
    #define AN8_ENB
    #define AN9_ENB
    //#define AN10_ENB
    #define AN11_ENB
    #define AN12_ENB
    #define AN13_ENB
    #define AN14_ENB
    //#define AN15_ENB
     
     
    // **************************************************
    // génération automatique des #define
    // **************************************************
     
    // génération des masques
    #ifdef AN0_ENB
    	#define AN0_MASK	0x0001
    #else
    	#define AN0_MASK	0x0000
    #endif
     
    #ifdef AN1_ENB
    	#define AN1_MASK	0x0002
    #else
    	#define AN1_MASK	0x0000
    #endif
     
    #ifdef AN2_ENB
    	#define AN2_MASK	0x0004
    #else
    	#define AN2_MASK	0x0000
    #endif
     
    #ifdef AN3_ENB
    	#define AN3_MASK	0x0008
    #else
    	#define AN3_MASK	0x0000
    #endif
     
    #ifdef AN4_ENB
    	#define AN4_MASK	0x0010
    #else
    	#define AN4_MASK	0x0000
    #endif
     
    #ifdef AN5_ENB
    	#define AN5_MASK	0x0020
    #else
    	#define AN5_MASK	0x0000
    #endif
     
    #ifdef AN6_ENB
    	#define AN6_MASK	0x0040
    #else
    	#define AN6_MASK	0x0000
    #endif
     
    #ifdef AN7_ENB
    	#define AN7_MASK	0x0080
    #else
    	#define AN7_MASK	0x0000
    #endif
     
    #ifdef AN8_ENB
    	#define AN8_MASK	0x0100
    #else
    	#define AN8_MASK	0x0000
    #endif
     
    #ifdef AN9_ENB
    	#define AN9_MASK	0x0200
    #else
    	#define AN9_MASK	0x0000
    #endif
     
    #ifdef AN10_ENB
    	#define AN10_MASK	0x0400
    #else
    	#define AN10_MASK	0x0000
    #endif
     
    #ifdef AN11_ENB
    	#define AN11_MASK	0x0800
    #else
    	#define AN11_MASK	0x0000
    #endif
     
    #ifdef AN12_ENB
    	#define AN12_MASK	0x1000
    #else
    	#define AN12_MASK	0x0000
    #endif
     
    #ifdef AN13_ENB
    	#define AN13_MASK	0x2000
    #else
    	#define AN13_MASK	0x0000
    #endif
     
    #ifdef AN14_ENB
    	#define AN14_MASK	0x4000
    #else
    	#define AN14_MASK	0x0000
    #endif
     
    #ifdef AN15_ENB
    	#define AN15_MASK	0x8000
    #else
    	#define AN15_MASK	0x0000
    #endif
     
     
     
     
    // configuration des I/O et registres pour pourvoir faire les mesures analogiques
    void anaInit(void){
     
    	// ****************************************************
    	// configuration des I/O analogiques
     
    	// config des I/O
    	// => les I/O doivent être des input
    	TRISB =	AN0_MASK  | AN1_MASK  | AN2_MASK  | AN3_MASK  |
    			AN4_MASK  | AN5_MASK  | AN6_MASK  | AN7_MASK  |
    			AN8_MASK  | AN9_MASK  | AN10_MASK | AN11_MASK |
    			AN12_MASK | AN13_MASK | AN14_MASK | AN15_MASK |
    			TRISB;
     
    	// activation des voies analogiques
    	AD1PCFG =	(~AN0_MASK)  & (~AN1_MASK)  & (~AN2_MASK)  & (~AN3_MASK)  &
    				(~AN4_MASK)  & (~AN5_MASK)  & (~AN6_MASK)  & (~AN7_MASK)  &
    				(~AN8_MASK)  & (~AN9_MASK)  & (~AN10_MASK) & (~AN11_MASK) &
    				(~AN12_MASK) & (~AN13_MASK) & (~AN14_MASK) & (~AN15_MASK) ;
     
     
    	// activation des voies à échantilloner
    	AD1CSSL =	AN0_MASK  | AN1_MASK  | AN2_MASK  | AN3_MASK  |
    				AN4_MASK  | AN5_MASK  | AN6_MASK  | AN7_MASK  |
    				AN8_MASK  | AN9_MASK  | AN10_MASK | AN11_MASK |
    				AN12_MASK | AN13_MASK | AN14_MASK | AN15_MASK ;
     
     
    	AD1CON2bits.SMPI = AN_NB_VOIES - 1; 
     
    }
    Comment faire pour définir AN_NB_VOIES ?
    Pour le calcul de TRISB, le compilateur va bien simplifier tous les mask en une seule valeur ?



    Pour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #ifdef AN0_ENB
    	#define AN0_MASK	0x0001
    #else
    	#define AN0_MASK	0x0000
    #endif
    => peut-on réduire ce code sur une seul ligne (via macro ?) afin d'améliorer la lisibilité du code ?

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Pourquoi pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #define AN0_ENB 1
    #define AN1_ENB 0
    #define AN2_ENB 0
    #define AN3_ENB 1
    //.....
    #define AN_ENB(x) AN##x##_ENB
    #define AN_MASK(x) AN_ENB(x)<<x
    #define AN_MASKINV(x) ~(AN_ENB(x)<<x)
     
      AD1CSSL   =  AN_MASK(0) | AN_MASK(1) | AN_MASK(2) | AN_MASK(3) /* etc */ ;
      AD1PCFG   =  AN_MASKINV(0) & AN_MASKINV(1) & AN_MASKINV(2) & AN_MASKINV(3) /* etc */ ;
      AN_NB_VOIES =   AN0_ENB + AN1_ENB + AN2_ENB + AN3_ENB /* etc*/ ;

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 854
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 854
    Par défaut
    merci, cette solution est pas mal

    j'ai encore un problème au niveau des récupérations des valeurs dans mes variable. Actuellement, je fais comme ceci :
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    // définition des variables de stockage
    #define AN0_VAR temperature 
    #define AN1_VAR alimentation 
    #define AN15_VAR humidite 
     
     
    void anaGet(void){
     
    	// ....
    	// ....
     
    	i=0;
    	#if AN0_ENB == 1
    		AN0_VAR = tabVal[i++];
    	#endif
     
    	#if AN1_ENB == 1
    		AN1_VAR = tabVal[i++];
    	#endif
     
    	// ...
     
    	#ifdef AN15_ENB == 1
    		AN15_VAR = tabVal[i++];
    	#endif
     
     
    	// ....
    	// ....
     
    }
    => Les valeurs sont stockées dans le buffer tampon tabVal[] et je les copie vers mes variables : vous en pensez quoi de cette methode ?

    C'est possible de faire une macro pour créer ce code ?
    On a le droit de faire un truc du genre ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #define AN_VAR(x) AN##x##_VAR
    #define GET_VAR(x)					\
    	#ifdef AN_ENB(x) == 1			\
    		AN_VAR(x) = tabVal[i++];	\
    	#endif
    // => ne compile pas :'(

Discussions similaires

  1. [XL-2010] Créer une macro Générant des boucles
    Par eliovan dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 26/09/2014, 07h52
  2. macros utilisant des boucles imbriquées et sql :
    Par nostress dans le forum Macro
    Réponses: 10
    Dernier message: 22/05/2008, 17h08
  3. Réponses: 3
    Dernier message: 07/04/2005, 15h04
  4. [CR] Est il possible de créer des univers avec Seagate Info?
    Par Frank dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 27/06/2002, 15h22

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