2

Je travaille actuellement avec un C embarqué pour un microcontrôleur et je trouve qu'il y a parfois plusieurs périphériques qui ne diffèrent que par une seule lettre (par exemple UARTA, UARTB, etc.). Le code de chaque périphérique est souvent identique à l'exception des lettres de registres identiques. Par exemple, pour la configuration périphérique AI ferait quelque chose comme:Existe-t-il une directive de compilateur pour remplacer une partie d'une constante

UCA2CTL1 |= UCSWRST;      // Put state machine in reset 
UCA2CTL0 |= UCSYNC+UCCKPL+UCMSB;   // 3-pin, 8-bit SPI slave 
// Continue initializing peripheral registers with "A" in name 

Et pour la configuration BI périphérique ont exactement le même code, sauf que les noms de registre sont transposés par 1 lettre:

UCB2CTL1 |= UCSWRST;      // Put state machine in reset 
UCB2CTL0 |= UCSYNC+UCCKPL+UCMSB;   // 3-pin, 8-bit SPI slave 
// Continue initializing peripheral registers with "B" in name 

Je voudrais avoir la possibilité de changer le périphérique que je cible sans avoir à # ifdef/copier/coller du code ou trouver/remplacer. Y a-t-il une directive de compilation ou une astuce intelligente qui peut implémenter ce comportement pour que je n'aie à écrire le code qu'une seule fois? J'aimerais juste # définir la dernière lettre dans le périphérique, mais quelque chose comme ça semble errer dangereusement près de la puanteur du code pour moi.

+3

Y at-il une raison pour laquelle vous ne pouvez pas simplement utiliser une macro ou deux ici? – thelazydeveloper

+0

@thelazydeveloper - J'adorerais, c'est ce que je demande ici. –

+0

Vous êtes en fait mieux de ne pas le faire. Considérez "grep UCB2CTL1 *" pour voir pourquoi. –

Répondre

3

Cela fonctionnera pour vous?

#define INITUC(device) \ 
UC## device ## 2CTL1 |= UCSWRST; \ 
UC## device ## 2CTL0 |= UCSYNC+UCCKPL+UCMSB 
... 
INITUC(A); 
INITUC(B); 
1

En supposant que ces constantes sont const et non defines Vous pouvez faire quelque chose comme ça:

#define MAKECONST(X) const int X ## 1; \ 
        const int X ## 0; \ 
        X ## 1 |= UCSWRST; \ 
        X ## 0 |= UCSYNC+UCCKPL+UCMSB; 

Et puis:

MAKECONST(UCA2CTL) 
MAKECONST(UCB2CTL) 

Notez que mon exemple comprend la déclaration, que je ne sais pas si vous devez, sinon, omettre les deux premières lignes du define. E.g .:

#define SETUP(X) X ## 1 |= UCSWRST; \ 
       X ## 0 |= UCSYNC+UCCKPL+UCMSB; 
Questions connexes