Notions de base de la
programmation C embarqué
Microcontrôleurs · Compilateurs · Variables · Structures de contrôle · Pointeurs · Tableaux
📋 Table des matières
Introduction — Systèmes embarqués
Microcontrôleurs
STM32, PIC, Atmel — circuits intégrés tout-en-un (CPU + mémoire + périphériques)
Raspberry Pi
Mini-ordinateur Linux, idéal pour prototypage et applications IoT
Smartphones
Samsung, iPhone, Huawei — systèmes embarqués complexes multi-cœurs
FPGA
Spartan 3E, Artix 7 — circuits reconfigurables pour traitements parallèles
🐢 Langages haut niveau
Java, Python, C# — plus simples mais gourmands en ressources. Nécessitent un OS ou runtime.
❌ Pas adapté aux MCU
⚡ Langage C (bas niveau)
Proche de la machine, compilation efficace, accès direct aux registres matériels, faible empreinte mémoire.
✅ Idéal pour MCU
Notions de base de la programmation C
En C, tout le code est organisé en fonctions. La fonction spéciale main() est le point d'entrée de tout programme.
/* … */ ou après // — ils sont ignorés par le compilateur.• Le C est sensible à la casse :
main ≠ Main.• Les mots réservés (
for, while, int…) s'écrivent toujours en minuscules.
Le code source C est du texte lisible par un humain. Le compilateur le traduit en code machine exécutable par le microcontrôleur.
Règle : une variable doit être déclarée avant utilisation et associée à un type.
| Type | Taille (octets) | Minimum | Maximum |
|---|---|---|---|
int | 4 | −2 147 483 648 | 2 147 483 647 |
unsigned int | 4 | 0 | 4 294 967 295 |
short | 2 | −32 768 | 32 767 |
unsigned short | 2 | 0 | 65 535 |
long | 4 | −2 147 483 648 | 2 147 483 647 |
unsigned long | 4 | 0 | 4 294 967 295 |
char | 1 | −128 | 127 |
unsigned char | 1 | 0 | 255 |
float | 4 | −3.4×10³⁸ | 3.4×10³⁸ |
double | 8 | −1.7×10³⁰⁸ | 1.7×10³⁰⁸ |
C#include <stdio.h> int main() { int a; // Déclaration a = 127; // Affectation float b = 3.14; // Déclaration + initialisation char c = 'A'; // Caractère (stocké comme entier) printf("a = %d, b = %f, c = %c\n", a, b, c); return 0; }
Cliquez sur Exécuter pour voir le résultat.
| Opérateur | Nom | Exemple | Résultat |
|---|---|---|---|
| + | Addition | a + b | Somme de a et b |
| - | Soustraction | a - b | Différence |
| * | Multiplication | a * b | Produit |
| / | Division | 7 / 2 → 3 (entiers) / 7 / 2.0 → 3.5 | Quotient |
| % | Modulo | 7 % 2 → 1 | Reste de la division |
| Opérateur | Nom | Notation | Utilisation MCU |
|---|---|---|---|
| & | AND | X & Y | Masquer des bits (lire un bit) |
| | | OR | X | Y | Mettre un bit à 1 |
| ~ | NOT | ~X | Inverser tous les bits |
| ^ | XOR | X ^ Y | Basculer un bit |
| >> | Décalage droit | X>>Y | Division par 2^Y |
| << | Décalage gauche | X<<Y | Multiplication par 2^Y |
Cliquez sur Exécuter pour voir le résultat.
Exemple :
(4 < 10) vaut 1 (vrai) · !(5 > 1) vaut 0 (faux)
| Opérateur | Signification | Exemple |
|---|---|---|
| == | Égal à | a == b |
| != | Différent de | a != b |
| < | Strictement inférieur | a < b |
| <= | Inférieur ou égal | a <= b |
| > | Strictement supérieur | a > b |
| >= | Supérieur ou égal | a >= b |
Cint x = 5; // Affectation combinée x += 3; // équivalent à x = x + 3 → x vaut 8 x -= 2; // équivalent à x = x - 2 → x vaut 6 x *= 2; // équivalent à x = x * 2 → x vaut 12 // Incrémentation / décrémentation x++; // post-incrément : utilise x, PUIS x = x + 1 ++x; // pré-incrément : x = x + 1, PUIS utilise x x--; // décrémentation de 1
Cliquez sur Exécuter pour voir le résultat.
📺 printf() — Affichage
printf("format", valeurs);
Affiche du texte et des valeurs formatées sur la console.
⌨️ scanf() — Saisie
scanf("format", &variable);
Lit une valeur entrée par l'utilisateur (le & donne l'adresse).
| Spécificateur | Type | Exemple printf |
|---|---|---|
%d | int | printf("%d", age); |
%ld | long | printf("%ld", x); |
%u | unsigned int | printf("%u", n); |
%f | float / double | printf("%.2f", pi); |
%c | char | printf("%c", lettre); |
%s | char[] (chaîne) | printf("%s", nom); |
Exemple#include <stdio.h> int main() { int nombreDeVies = 5, niveau = 1; float score = 98.5; printf("Vous avez %d vies, niveau %d, score %.1f\n", nombreDeVies, niveau, score); int age = 0; printf("Entrez votre âge : "); scanf("%d", &age); printf("Âge saisi : %d\n", age); return 0; }
Cliquez sur Exécuter pour voir le résultat.
Exemplefloat moy; printf("Donnez votre moyenne : "); scanf("%f", &moy); if (moy >= 10) { printf("Mabrouk ! Vous avez réussi.\n"); } else { printf("Échec : il faut travailler encore plus !\n"); }
Cliquez sur Exécuter pour voir le résultat.
if imbriquésif (A > B) { printf("%d est plus grand que %d\n", A, B); } else { if (A < B) printf("%d est plus petit que %d\n", A, B); else printf("%d est égal à %d\n", A, B); }
Cliquez sur Exécuter pour voir le résultat.
switch est préféré quand on teste une seule variable entière contre plusieurs valeurs constantes. Les types autorisés : int, short, long, char.
switchswitch (choix) { case 1: printf("Option 1 choisie\n"); break; // OBLIGATOIRE pour ne pas tomber dans le case suivant case 2: printf("Option 2 choisie\n"); break; default: // exécuté si aucun case ne correspond printf("Erreur de choix\n"); }
Cliquez sur Exécuter pour voir le résultat.
for// Affiche "Bonjour" 10 fois int a, k = 10; for (a = 1; a <= k; a++) { printf("Bonjour\n"); } // Compte à rebours for (int i = 10; i >= 1; i--) { printf("%d\n", i); } printf("Décollage !\n");
Cliquez sur Exécuter pour voir le résultat.
whileint i = 0; while (i < 5) { printf("i = %d\n", i); i++; // IMPORTANT : sinon boucle infinie ! }
Cliquez sur Exécuter pour voir le résultat.
i++; — le programme s'arrêtera tout seul après un certain nombre de tours (protection anti-boucle infinie), au lieu de planter ton navigateur.do-whileint choix; do { printf("Entrez 1 ou 2 : "); scanf("%d", &choix); } while (choix != 1 && choix != 2); // La saisie est garantie au moins une fois
Cliquez sur Exécuter pour voir le résultat.
Les fonctions permettent de structurer, réutiliser et tester le code séparément.
Fonctions// Définition de la fonction float evaluerExp(float a, float b) { float val = 0; val = 2 * (a + b); return val; // retourne un seul résultat } int main() { float resultat = evaluerExp(3.0, 5.0); // appel avec paramètres effectifs printf("Résultat : %f\n", resultat); // affiche 16.0 return 0; }
Cliquez sur Exécuter pour voir le résultat.
Les pointeurs
❌ Par valeur (copie)
La fonction reçoit une copie de la variable. Les modifications n'affectent pas l'original.
✅ Par adresse (pointeur)
La fonction reçoit l'adresse de la variable. Les modifications se répercutent sur l'original.
| Opérateur | Nom | Rôle | Exemple |
|---|---|---|---|
| & | Adresse de | Donne l'adresse d'une variable | p = &n; |
| * | Déréférencement | Accède au contenu pointé | *p = 40; |
Pointeursint n = 20; int *pNombre = NULL; // toujours initialiser à NULL pNombre = &n; // pNombre contient l'adresse de n printf("%d\n", *pNombre); // affiche 20 (contenu de n) *pNombre = 40; // modifie n via le pointeur printf("%d\n", n); // affiche 40 !
Cliquez sur Exécuter pour voir le résultat.
En C, return ne retourne qu'une seule valeur. Pour retourner plusieurs résultats, on passe les adresses des variables en paramètre.
min & maxvoid min_max(int a, int b, int *pmin, int *pmax) { if (a < b) { *pmin = a; *pmax = b; } else { *pmin = b; *pmax = a; } } int main() { int a = 8, b = 3, min, max; min_max(a, b, &min, &max); printf("min = %d, max = %d\n", min, max); // min=3, max=8 return 0; }
Cliquez sur Exécuter pour voir le résultat.
Tableaux et structures
Tableauxint Premiers[4]; Premiers[0] = 2; Premiers[1] = 3; Premiers[2] = 5; Premiers[3] = 7; printf("Le 3e nombre premier : %d\n", Premiers[2]); // 5 printf("Somme 2e+3e : %d\n", Premiers[1] + Premiers[2]); // 8 // Parcours avec une boucle for for (int i = 0; i < 4; i++) { printf("Premiers[%d] = %d\n", i, Premiers[i]); }
Cliquez sur Exécuter pour voir le résultat.
struct// Définition de la structure struct etudiant { char nom[30]; int age; float moyenne; }; // Avec typedef — plus pratique typedef struct etudiant Etudiant; int main() { Etudiant E1; // Déclaration E1.age = 20; // Accès aux champs avec '.' E1.moyenne = 14.5; printf("Donner le nom : "); scanf("%s", E1.nom); printf("Étudiant : %s, âge %d, moy %.1f\n", E1.nom, E1.age, E1.moyenne); return 0; }
| Accès | Signification |
|---|---|
E1.age | Champ age de l'étudiant E1 |
E1.moyenne | Champ moyenne de E1 |
E1.nom[0] | Premier caractère du nom de E1 |
E1 = E2 | Copie globale de toute la structure |
Travaux Dirigés — Exercices
gcc -o prog mon_programme.c && ./prog
Affichage de variables
Déclarez un entier age et un double taille. Initialisez-les et affichez-les avec des messages descriptifs.
Somme de deux nombres
Demandez deux entiers à l'utilisateur et affichez leur somme.
Calcul de moyenne
Saisir trois décimaux et afficher leur moyenne.
Mon premier programme
Afficher le message "Bonjour, monde !" sur la console.
Cliquez sur Exécuter pour voir le résultat.
Nombre pair ou impair
Saisir un entier et déterminer s'il est pair ou impair. Indice : utiliser %.
Le plus grand de deux nombres
Saisir deux nombres et afficher le plus grand.
Type de triangle
Entrer les trois côtés d'un triangle et déterminer s'il est équilatéral, isocèle ou scalène.
Année bissextile
Vérifier si une année est bissextile (divisible par 4, sauf si divisible par 100 mais pas par 400).
Cliquez sur Exécuter pour voir le résultat.
Compte à rebours
Afficher un compte à rebours de 10 à 1 avec while, puis "Décollage !".
Somme des N premiers entiers
Saisir N et calculer la somme 1 + 2 + … + N avec for.
Table de multiplication
Afficher la table de multiplication d'un nombre donné (de 1 à 10).
Factorielle
Calculer n! pour un entier positif donné.
Cliquez sur Exécuter pour voir le résultat.
Initialisation et affichage
Déclarer un tableau de 5 entiers, l'initialiser avec {1,2,3,4,5} et afficher tous les éléments.
Somme des éléments
Calculer et afficher la somme de tous les éléments d'un tableau.
Plus grand élément
Trouver et afficher la valeur maximale d'un tableau d'entiers.
Inversion d'un tableau
Inverser l'ordre des éléments d'un tableau et afficher le résultat.
Cliquez sur Exécuter pour voir le résultat.
Microcontrôleurs · ARM Cortex-M4 · STM32 · Langage C