Comment déclarer une variable en langage C ? Quelles sont les variables les plus efficaces pour les systèmes embarqués ?

Introduction

On va voir dans ce cours comment déclarer des variables en langage C et celle qui sont le plus adaptées aux systèmes embarqués.

Macro

  • Préprocesseur (#define)

 #define permet au préprocesseur de remplacer une valeur par un mot. Par exemple :

#define PI 3.14

Ceci signifie que tous les PI de votre code seront remplacés par 3.14. C’est un rechercher-remplacer fait par le préprocesseur avant la compilation.

Définition d’une macro : Les macros sont des fonctions qui s’écrivent sur une ligne ou plusieurs et qui permettent de simplifier votre code. Pour cela, vous les définissez dans votre code et vous pouvez les appeler comme une fonction.

Les macros ne sont que des bouts de code qui sont directement remplacés dans votre code source juste avant la compilation. Ceci permet de gagner de la place dans votre programme.

  • Sans paramètre

Pour commencer, on va voir comment déclarer une macro sans paramètre :

#define ARDUINO_FACTORY() printf("Arduino Factory");

int main(int argc, char *argv[]) {
    ARDUINO_FACTORY()
    return 0;
}

Par exemple, en appelant la fonction Arduino_Factory, Arduino factory s’affiche dans la console. On va voir comment faire la même chose avec un paramètre.

  • Avec paramètre
#define Cours(numero) if (numero==0) \
                    printf("Le cours sur le servomoteur est fait pour vous\n");\
                    if (numero ==1) \
                    printf("Le cours sur le servomoteur est fait pour vous\n");\
                    if (numero ==2) \
                    printf("Le cours sur le servomoteur est fait pour vous\n");

int main(int argc, char *argv[]) {
    Cours(1)
    return 0;
}
  • Macro avec plusieurs lignes

Vous pouvez aussi faire une macro avec plusieurs lignes. Pour cela vous devez ajouter un slash avant d’ajouter une nouvelle ligne, sauf à la fin.

#define Contenu_du_site()   printf("Cours sur Arduino\n"); \
                            printf("Cours sur le langage Arduino\n"); \
                            printf("Cours sur les systemes embarques \n");

int main(int argc, char *argv[]) {
    Contenu_du_site()
    return 0;
}

Les différents types de variables

A) Char

Une chaîne de caractères ou char est une suite de caractères ou symboles faisant partie du code ASCII.

En langage C, une chaîne de caractères est un tableau dont le dernier élément est le caractère nul. Ce caractère est un caractère de contrôle donc non affichable qui permet d’indiquer une fin de chaîne de caractères. Ainsi une chaîne composée de n éléments sera en fait un tableau de n+1 éléments de type char.

Il existe plusieurs manières de déclarer une chaîne de caractères :

  • Par exemple, vous pouvez déclarer directement les valeurs à l’intérieur de votre chaîne de caractères :
#include <stdio.h>

void main(){
	char Chaine_Arduino_factory[20+1]={ 'A', 'r', 'd', 'u', 'i', 'n', 'o', '
#include <stdio.h>
void main(){
char Chaine_Arduino_factory[20+1]={ 'A', 'r', 'd', 'u', 'i', 'n', 'o', '\0' };
}
' }; }
  • Vous pouvez aussi déclarer les éléments de votre chaine de caractère plus tard dans votre programme :
#include <stdio.h>

void main(){
	char Chaine_Arduino_factory[20+1];
	Chaine_Arduino_factory[0]= 'A';
	Chaine_Arduino_factory[1]= 'r';
	Chaine_Arduino_factory[2]= 'd';
	Chaine_Arduino_factory[3]= 'u';
	Chaine_Arduino_factory[4]= 'i';
	Chaine_Arduino_factory[5]= 'n';
	Chaine_Arduino_factory[6]= 'o';
	Chaine_Arduino_factory[7]= '
#include <stdio.h>
void main(){
char Chaine_Arduino_factory[20+1];
Chaine_Arduino_factory[0]= 'A';
Chaine_Arduino_factory[1]= 'r';
Chaine_Arduino_factory[2]= 'd';
Chaine_Arduino_factory[3]= 'u';
Chaine_Arduino_factory[4]= 'i';
Chaine_Arduino_factory[5]= 'n';
Chaine_Arduino_factory[6]= 'o';
Chaine_Arduino_factory[7]= '\0';
}
'; }
  • Vous pouvez également changer la valeur d’un char avec la manière que l’on vient de voir. Vous pouvez afficher la chaîne de caractères avec :
printf("%s\n", Chaine_Arduino_factory);

Le char prends 1 seul octet  avec des caractères ASCII 8bits. De plus, une variable du type char peut subir les mêmes opérations que les variables du type short, int ou long.

B) Int

Les entiers reflètent la taille naturelle des nombres entiers de la machine (16 bits /32 bits). Donc, on ne va pas utiliser des entiers dans nos programmes parce que le type d’entier occupe deux octets sur notre système, mais sur d’autre ca sera plus ou moins que 2 octets. Les entiers ne seront donc pas compatible entre toute les machines, contrairement au short ou long.

Short : Le type short est codé sur 2 octets. Avec ce type de variable on peut utiliser le programme dans plusieurs machines. Les variables short fonctionnent pour les machines 16 bits.

Voici comment on déclare un short :

short variable_nombre = 12;

Long : Les long sont des entiers sur 32 bits. Ils prennent 4 octets dans la mémoire du microsystème. De plus, avec ce type de variable on peut utiliser le programme dans plusieurs machines.

Voici comment on déclare un long :

long variable_nombre_long = -78;

C) Les variables flottantes

Les variables flottantes permettent de stocker des nombres à virgules. Vous avez plusieurs manières de les déclarer en fonction de la machine que vous utilisez :

float : nombre à virgule flottante en simple précision. Un float que l’on déclare se code sur 32 bits.

float variable_nombre_float=2.5;

double : nombre à virgule flottante en double précision. Un double que l’on déclare se code sur 64 bits.

double variable_nombre_pi =3.141;

D) Les nombres signed ou unsigned

Il existe deux types de nombre : Les nombres signés et non signés.

  • Les nombres non signés (unsigned) : Ceux qui sont seulement entier positif.
  • Les nombres signés (signed) : Elle peut prendre des valeurs négatives et positives.

Voici un tableau récapitulant les différences entre signé et non signé pour chaque variable :

 

VariableSignedUnsigned
Char-127 à 1280 à 255
Int -32 768 à 32 7670 à 65 535
Short-32 768 à 32 7670 à 65 535
Long-2 147 483 648 à 2 147 483 6470 à 4 294 967 295
Float3.4*10-38 à 3.4*1038 
Double1.7*10-308 à 1.7*10308 

Les options de déclaration

On va maintenant voir différent type de déclaration des variables :

  • static : Limite la portée d’une variable au fichier (ceci permet d’éviter la confusion entre deux fichiers)
  • extern : Permet d’appeler une variable faisant partie d’un autre fichier  :
  • register : Permet de déclarer un registre de travail.
  • near : variable déclarée en mémoire cache
  • Volatile : variable accessible en écriture par le programme principal et par la fonction d’interruption.

State machine : permet d’avoir différents comportements en passant plusieurs fois dans la même boucle.  Ainsi, à chaque passage de la boucle on a une action différente.

Les constantes

Les constantes sont des variables que l’on ne peut pas modifier. Elles ne prennent pas de place en ram. Cela vaut vraiment le coup d’utiliser des constantes à la place des autres variables si vous ne souhaitez pas changer la valeur car vous économiser 14 octets en flash et 14 octets en ram donc 28 octets au total. Les variables sont très peu utilisés aujourd’hui.

Le compilateur ne peut pas savoir par lui même si la variable va être modifiée ou elle restera constante alors c’est à nous de savoir si on peut mettre constante ou que cela reste une variable.

A) Les suffixes

Une constante est obligatoirement un entier. Cependant, on a dit que les entiers ne sont pas forcément bien pour le langage C embarqué. On va donc ajouter un suffixe afin de préciser au compilateur si c’est une variable 16 bits (short) ou 32 bits (long).

Voici la liste des suffixes que vous pouvez appliquer à vos constantes :

 

NombreContact
1234Llong
1234uLnon signé long
123.4Ffloat

Le fait d’ajouter les suffixes uL, F ou L permet de spécifier au compilateur quelle type de variable on veut créer et par conséquent de gagner de la place en mémoire.

Il existe aussi des préfixes que vous pouvez ajouter devant votre constante, on va voir leurs utilités.

B) Les préfixes

Les préfixes sont des lettres que l’on met devant le nombre de votre constante et qui permet de transformer votre nombre décimal en binaire, hexadécimal ou octal. Voici un tableau récapitulatif :

 

NombreContact
O123Octal
Ox123Hexadécimal
Ob123Binaire

C) Chaîne de caractères

Les constantes peuvent aussi servir à déclarer des chaînes de caractères. Il existe deux méthodes :

  • Les chaînes de caractère
  • Les énumérations

1. Les chaînes de caractères

Les chaînes de caractères en langage C peuvent se déclarer de deux manières :

  • #define CHAINE CARACTERE 500
  • char chaine_caractere[taille_chaine_caractere];

2.  Constante énumérée

On va maintenant voir comment faire une liste de constante avec la fonction énumération. Cette fonction permet de simplifier la déclaration des constantes.

Voici deux exemples d’énumération :

enum logique {NON, OUI};

On peut aussi déclarer NON ou OUI sans enum :

# define NON 0

# define OUI 1

Néanmoins on perd plus de place qu’avec enum.

Le deuxième exemple est pour déclarer les mois de l’année :

enum mois {JAN =1,FEV, MAR, AVR, MAI, JUN, JUI, AOU, SEP, OCT, NOV, DEC}

Ici chaque mois aura son nombre associé. Exemple NOV aura la valeur 11. Ceci est beaucoup plus rapide que de déclarer chaque mois avec son numéro.