L'intégration d'un écran OLED dans un système embarqué améliore considérablement l'interface homme-machine. Ce guide détaille la configuration et le pilotage d'un module OLED basé sur le contrôleur SSD1306 (ou compatible comme SH1106, SH1107 et SSD1309) à l'aide d'un microcontrôleur STM32. Nous utiliserons le protocole de communication SPI et la bibliothèque open-source stm32-ssd1306 pour simplifier le développement sous l'environnement Keil uVision et STM32CubeMX.
Matériel requis et câblage
Pour cette implémentation, un module OLED de 0.96 pouce utilisant l'interface SPI est connecté à une carte de développement STM32. Les broches du module doivent être reliées aux ports GPIO du microcontrôleur comme suit :
- VCC : Alimentation (3.3V)
- GND : Masse
- SCK : Horloge SPI (SCLK)
- SDA : Données SPI (MOSI)
- RES : Réinitialisation matérielle (Reset)
- DC : Sélection Données/Commande (Data/Command)
- CS : Sélection de puce (Chip Select)
Configuraton du projet avec STM32CubeMX
La première étape consiste à générer le code d'initialisation via STM32CubeMX :
- Créez un nouveau projet en sélectionnant le microcontrôleur cible (par exemple, STM32L4R5ZI ou STM32F103C8T6).
- Activez l'interface SPI correspondant aux broches connectées. Configurez le mode en Full-Duplex Master et définissez la taille des données (Data Size) sur 8 Bits.
- Configurez les broches de contrôle (RES, DC, CS) en tant que sorties GPIO (GPIO_Output). Assurez-vous que la vitesse de bascule est réglée sur High pour optimiser les performances d'affichage.
- Configurez l'horloge système et générez le code pour l'IDE Keil uVision en utilisant la bibliothèque HAL.
Intégration de la bibliothèque SSD1306
Téléchargez la bibliothèque stm32-ssd1306 et incorporez-la dans l'arborescence de votre projet. Par exemple, placez les fichiers dans un répertoire nommé Drivers/OLED.
Dans Keil, ajoutez les fichiers source (.c) au groupe de votre projet et incluez le chemin d'accès des en-têtes (.h) dans les options de compilation (C/C++ -> Include Paths).
Adaptation des fichiers d'en-tête
L'environnement Keil ne fournit pas nativement certaines dépendances standard. Ouvrez le fichier ssd1306.h et neutralisez l'inclusion de _ansi.h en redéfinissant manuellement les macros nécessaires :
/* Supprimez ou commentez la ligne d'inclusion originale */
/* #include <_ansi.h> */
/* Ajoutez les définitions de compatibilité suivantes */
#define _BEGIN_STD_C extern "C" {
#define _END_STD_C }
Ensuite, renommez le fichier ssd1306_conf_template.h en ssd1306_conf.h. Modifiez ce fichier de configuration pour qu'il corresponde à votre matériel. Puisque nous utilisons le bus SPI matériel généré par CubeMX, activez l'option correspondante et incluez l'en-tête principal :
#include "main.h"
/* Décommentez la ligne pour activer l'interface SPI */
#define SSD1306_USE_SPI
/* Définissez les broches de contrôle si nécessaire, ou laissez les valeurs par défaut si elles correspondent à votre schéma */
Initialisation et affichage graphique
Une fois le projet configuré, vous pouvez initialiser l'écran et dessiner des éléments graphiques. Voici une implémentation modifiée dans le fichier principal pour démontrer l'utilisation de l'API de manière structurée :
#include "main.h"
#include "ssd1306.h"
#include "ssd1306_fonts.h"
#include <stdio.h>
#include <string.h>
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
void RenderUserInterface(void) {
char msg_buffer[32];
// Effacer le tampon d'affichage avec un fond noir
ssd1306_Fill(Black);
// Dessiner une bordure autour de l'écran
ssd1306_DrawRectangle(2, 2, 125, 61, White);
// Préparer et centrer le texte principal
snprintf(msg_buffer, sizeof(msg_buffer), "System Ready");
uint8_t str_length = strlen(msg_buffer);
uint8_t x_position = (128 - (str_length * 6)) / 2; // Calcul pour la police 6x8
ssd1306_SetCursor(x_position, 28);
ssd1306_WriteString(msg_buffer, Font_6x8, White);
// Ajouter un indicateur d'état
ssd1306_SetCursor(10, 45);
ssd1306_WriteString("SPI Active", Font_6x8, White);
// Transférer le tampon vers le contrôleur OLED
ssd1306_UpdateScreen();
}
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI1_Init();
// Initialisation du module SSD1306
if (ssd1306_Init() != 0) {
// Gestion de l'erreur de communication I2C/SPI
Error_Handler();
}
// Appel de la fonction d'affichage personnalisée
RenderUserInterface();
while (1) {
// Boucle d'exécution principale
}
}
Ce script initialise le bus, remplit l'écran en noir, trace un cadre rectangulaire, écrit des chaînes de caractères à des coordonnées calculées dynamiquement, et envoie finalement le tampon mémoire vers le contrôleur SSD1306.