TP 5 : SPI (Interface Périphérique Série)
1. Introduction
Dans ce TP, nous allons explorer le protocole de communication SPI, largement utilisé dans les systèmes embarqués pour les échanges de données entre deux ou plusieurs périphériques.
L’objectif final sera de construire un lecteur audio sur la carte de laboratoire, qui lira des fichiers .wav depuis une carte SD et les jouera à l’aide du haut-parleur intégré.
2. Protocole SPI (Serial Peripheral Interface)
SPI est une norme de communication synchrone développée par Motorola. Elle fonctionne en mode full-duplex (transfert de données simultané dans les deux directions).
La communication repose sur une architecture Maître-Esclave (un périphérique Maître et un ou plusieurs Esclaves). Le Maître initie toujours la communication.
SPI est aussi appelé protocole à quatre fils, car il utilise quatre lignes distinctes :
- MOSI — Master Out Slave In (données envoyées du Maître vers l’Esclave)
- MISO — Master In Slave Out (données envoyées de l’Esclave vers le Maître)
- SCLK — Horloge série (signal d’horloge généré par le Maître)
- CS / SS — Chip Select / Slave Select (utilisé par le Maître pour sélectionner un Esclave ; actif à l’état BAS)
2.1 Connexion de plusieurs Esclaves
Plusieurs périphériques Esclaves peuvent être connectés à un seul Maître. Les lignes MOSI, MISO et SCLK sont partagées, tandis que chaque Esclave possède sa propre ligne CS / SS.
Quand le Maître souhaite communiquer avec un Esclave spécifique, il place la ligne CS / SS correspondante à l’état BAS (actif). Toutes les autres lignes SS restent HAUTES, et les Esclaves concernés ignorent la communication.
3. Transmission de Données en SPI
Pour démarrer la communication :
- Le Maître définit la fréquence d’horloge (elle ne doit pas dépasser la vitesse maximale supportée par l’Esclave).
- Il sélectionne l’Esclave en plaçant sa ligne CS / SS à BAS.
Pendant chaque cycle d’horloge SPI (mode full-duplex) :
- Le Maître envoie un bit via MOSI, que l’Esclave lit.
- Simultanément, l’Esclave envoie un bit via MISO, que le Maître lit.
Cela s’effectue généralement à l’aide de registres à décalage connectés en boucle dans le Maître et l’Esclave.
En général :
- Le bit de poids fort (MSB) est envoyé en premier.
- Une fois un mot transmis, les deux périphériques ont échangé l’ensemble du contenu de leurs registres à décalage.
Une fois la transmission terminée :
- Le Maître arrête le signal d’horloge (SCLK).
- Il désélectionne l’Esclave en plaçant la ligne CS / SS correspondante à HAUT.
Remarque : Tous les Esclaves non sélectionnés ignorent les lignes SCLK et MOSI, et ne pilotent pas la ligne MISO.
Un seul Esclave peut être sélectionné à la fois par le Maître.
4. SPI sur l’ATMega324
Le microcontrôleur ATMega324 fournit une interface SPI pouvant fonctionner en mode Maître ou Esclave.
Comme d’habitude, la configuration et l’utilisation de cette interface impliquent l’utilisation de registres de contrôle, de statut et de données.
La description complète des registres liés au SPI se trouve dans la fiche technique de l’ATmega324P, chapitre : SPI – Serial Peripheral Interface (à partir de la page 214).
Voici un aperçu des registres SPI les plus importants :
Registre de Contrôle SPI (SPCR)
Bit | Nom | Description |
---|---|---|
6 | SPE | Activation du SPI — Mettre à 1 pour activer l’interface SPI |
5 | DORD | Ordre des bits — 1 : LSB en premier, 0 : MSB en premier |
4 | MSTR | Sélection Maître/Esclave — 1 : mode Maître, 0 : mode Esclave |
3-0 | CPOL, CPHA, SPR1, SPR0 | Polarité, phase et fréquence de l’horloge SPI |
Registre de Statut SPI (SPSR)
Bit | Nom | Description |
---|---|---|
7 | SPIF | Drapeau d’interruption SPI — Mis à 1 quand un transfert est terminé |
Registre de Données SPI (SPDR)
Le registre SPDR est utilisé à la fois pour transmettre et recevoir des données :
- Écrire dans ce registre démarre une nouvelle transmission (en mode Maître).
- Lire dans ce registre permet d’obtenir les données reçues via SPI.
5. Carte SD au format FAT
La carte de laboratoire intègre un lecteur de carte SD qui communique avec le microcontrôleur ATMega324 via le protocole SPI — c’est l’application principale du TP d’aujourd’hui.
Le schéma ci-dessous montre comment le lecteur de carte SD est connecté au microcontrôleur. Remarquez que certaines broches déjà utilisées dans les TP précédents sont ici réutilisées pour les signaux SPI.
Format de la carte SD : FAT32
Les cartes SD que nous utiliserons sont formatées avec le système de fichiers FAT32. Pour simplifier les opérations sur les fichiers, nous utiliserons la bibliothèque Petit FAT Filesystem — choisie pour sa faible empreinte mémoire (2–4 Ko) et sa consommation RAM minimale (seulement 46 octets + pile).
API de la bibliothèque Petit FAT Filesystem
Voici les principales fonctions fournies par la bibliothèque :
FRESULT pf_mount (FATFS*); // Monter ou démonter un volume
FRESULT pf_open (const char*); // Ouvrir un fichier
FRESULT pf_read (void*, WORD, WORD*); // Lire des données depuis un fichier
FRESULT pf_write (const void*, WORD, WORD*); // Écrire des données dans un fichier
FRESULT pf_lseek (DWORD); // Déplacer le pointeur de fichier
FRESULT pf_opendir (DIR*, const char*); // Ouvrir un répertoire
FRESULT pf_readdir (DIR*, FILINFO*); // Lire un répertoire
Ces fonctions permettent un accès bas niveau aux fichiers depuis un système embarqué — exactement ce dont nous avons besoin pour implémenter un lecteur audio de base sur notre carte à microcontrôleur.
6. Exercices
📥 Téléchargez l’archive du code de départ :
lab5_skel.zip
Dans ce TP, vous n’aurez pas beaucoup de code à écrire, mais il est important de bien comprendre comment votre code interagit avec le squelette fourni et le comportement des fonctions de bibliothèque que vous utiliserez.
Tâche 1 : Contrôle SPI (2p)
Implémentez les fonctions de communication SPI de base dans spi.c
:
SPI_init()
SPI_exchange()
- Configurez PB4 (SS) comme sortie et mettez-le à HAUT pour désactiver les interruptions SPI déclenchées par la sélection esclave.
- Suivez les exemples de la page 217 de la fiche technique.
- Référez-vous au schéma de câblage de la section 5 pour identifier les broches MOSI et SCLK.
- Configurez le SPI en mode Maître avec SCLK = fosc/16 (fréquence plus lente pour compatibilité avec la carte SD).
- N’oubliez pas d’utiliser les registres avec suffixe
0
:SPCR0
,SPDR0
, etc. - Utilisez
SPDR0
pour envoyer une donnée et recevoir la réponse dans une seule fonction (full-duplex), remplaçant ainsi les fonctionsSPI_read()
etSPI_write()
.
Tâche 2 : Contrôle de la carte SD (2p)
Dans sd.c
, implémentez :
SD_init()
SD_receive()
SD_transmit()
- PA2 (SS pour la carte SD) doit être configurée en sortie. Laissez la gestion des niveaux HAUT/BAS au code squelette.
- Utilisez
SPI_exchange()
à la fois pour l’émission et la réception. - Dans
SD_receive()
, envoyez 0xFF comme octet factice pour initier une lecture (le Maître initie toujours la communication). - ✅ Vérification : Après avoir téléversé le code, l’écran LCD doit afficher
Mounted!
au lieu deMounting...
. Si ce n’est pas le cas, appuyez sur RESET et effectuez un débogage si nécessaire.
Tâche 3 : Affichage du premier fichier (2p)
Implémentez init_directory()
dans lab5.c
pour afficher le premier fichier .wav
du dossier /music
:
- Utilisez
pf_opendir()
pour ouvrir le dossier. - Utilisez
pf_readdir()
pour parcourir les entrées. - Ignorez les fichiers dont le nom commence par un underscore
_
. - Utilisez
LCD_clear_top_line()
etLCD_printAt()
pour afficher le nom du fichier.
POINT DE CONTRÔLE (1pt)
Après quelques secondes, l’écran LCD doit afficher : "Mounted!"
Cela confirme que la carte SD a bien été initialisée et montée.
Tâche 3 – Lecture de la température (2pts)
Configurez l’ADC et lisez la température depuis un capteur analogique (par exemple LM35).
Étapes d’implémentation :
- Créez et implémentez
adc_init()
etadc_read()
- Configurez :
- Tension de référence : AVcc
- Prescaler ADC : 8
- Convertissez la valeur ADC en tension, puis en °C (ex :
temp = voltage * 100
) - Affichez la température sur l’écran LCD
- Envoyez aussi la lecture via USART (série)
Tâche 4 – Enregistrement des températures sur carte SD (2pts)
Implémentez log_temperature()
dans lab5.c
pour sauvegarder les températures dans un fichier CSV.
Exigences :
- Utilisez
SD_log_data()
pour écrire dans le fichier - Affichez la température actuelle sur le LCD
- Envoyez la température via USART
- Lorsqu’on appuie sur le bouton PD6, ajoutez une nouvelle ligne de log
Tâche 5 – Navigation dans les enregistrements (2pts)
Implémentez init_log_display()
et next_log_entry()
pour lire le fichier log.csv
ligne par ligne.
Fonctionnalités :
- Affichez chaque ligne du CSV (entrée) sur le LCD
- En appuyant sur le bouton PB2, passez à la ligne suivante
- Une fois la fin atteinte, recommencez à partir du début
POINT DE CONTRÔLE (1pt)
Vous devez pouvoir faire défiler tous les enregistrements de température à l’aide du bouton.
Une fois terminé, votre enregistreur doit permettre :
- Lecture temps réel du capteur
- Enregistrement sur bouton-poussoir
- Navigation complète dans les logs via l’écran LCD et un bouton