Tutoriel - Bibliothèque STM32_I2C_LCD

Interface pour contrôler des écrans LCD alphanumériques via I2C avec un STM32

Consultez la librairie sur GitHub.

1. Introduction

La bibliothèque STM32_I2C_LCD permet de contrôler des écrans LCD alphanumériques compatibles HD44780 via un expandeur I2C (PCF8574). Elle est conçue pour fonctionner avec les microcontrôleurs STM32 en utilisant la couche HAL.

2. Compatibilité et Prérequis

Compatibilité Matérielle

  • Toutes les familles de microcontrôleurs STM32 supportant HAL et disposant d'un périphérique I2C.
  • Écran LCD I2C 16x2 ou 20x4.

Prérequis Logiciels

  • Un microcontrôleur STM32.
  • STM32CubeIDE.
  • Le bus I2C sur lequel se troue votre capteur doit être configuré et initialisé dans votre projet.
  • La librairie HAL STM32_I2C_LCD présente dans le répertoire STM32_Libraries.

3. Fichiers de la librairie

  • STM32_I2C_LCD.h : Fichier d'en-tête contenant les déclarations des fonctions et constantes.
  • STM32_I2C_LCD.c : Fichier source contenant l'implémentation des fonctions.

n'oubliez pas de modifier le fichier STM32_I2C_LCD.h pour l'adapter à votre configuration matérielle #include "stm32l0xx_hal.h" // Remplacez stm32l0xx_hal.h si vous utilisez une autre série de carte ex : stm32f4xx_hal.h.

4. Installation et Configuration

Pour installer la bibliothèque dans votre projet STM32 :

  1. Créez un dossier nommé STM32_I2C_LCD dans le répertoire Drivers de votre projet STM32 et copiez y les fichiers STM32_I2C_LCD.h et STM32_I2C_LCD.c.
  2. Ajoutez les chemins d'inclusion : dans les propriétés de votre projet STM32CubeIDE, dans C/C++ General, > Paths and Symbols > Onglet Includes, dans GNU ajoutez le chemin vers le dossier STM32_I2C_LCD.

N'oublier pas d'activer le float dans les propriétés du projet pour afficher le nombres flottants dans le printf.

5. Fonctionnalités

  • Initialisation de l'écran LCD via I2C.
  • Écriture de chaînes de caractères et de caractères ASCII.
  • Gestion du curseur : positionnement, affichage, clignotement.
  • Effacement de l'écran et retour à la position d'origine.
  • Création et affichage de caractères personnalisés.
  • Défilement de texte vers la gauche ou la droite.
  • Contrôle du rétroéclairage.

6. Connexions Matérielles

Connectez le module LCD à votre microcontrôleur STM32 via un expandeur I2C (PCF8574) :

  • VCC -> 3.3V ou 5V (selon votre module).
  • GND -> GND.
  • SCL -> Broche SCL I2C du STM32 (ex: PB6, PB8, PB10 selon le MCU et la configuration I2C).
  • SDA -> Broche SDA I2C du STM32 (ex: PB7, PB9, PB11 selon le MCU et la configuration I2C).

Assurez-vous d'activer le périphérique I2C approprié dans STM32CubeMX ou manuellement. Des résistances de pull-up (généralement 4.7kΩ) sont nécessaires sur les lignes SCL et SDA si elles ne sont pas déjà présentes sur le module ou la carte STM32.

7. Installation et Configuration

  1. Copiez les fichiers STM32_I2C_LCD.c et STM32_I2C_LCD.h dans votre projet.
  2. Ajoutez-les à votre environnement de développement.
  3. Configurez l'I2C dans STM32CubeMX et notez l'adresse I2C de votre expandeur (par exemple, 0x27).

8. Utilisation de la Bibliothèque

8.1 Inclusion des En-Têtes

Incluez les fichiers d'en-tête nécessaires dans votre code :


/* USER CODE BEGIN Includes */
#include <stdio.h>      	  // Inclut la bibliothèque standard d'entrée-sortie pour utiliser printf
#include <string.h>     	  // Inclut la bibliothèque de manipulation de chaînes de caractères pour utiliser strlen
#include "STM32_I2C_LCD.h" 	// Inclut le fichier d'en-tête pour la gestion de l'écran LCD via I2C
/* USER CODE END Includes */
        

8.2 Déclarer les constantes préprocesseur

Déclarez les constantes préprocesseur pour la configuration de l'écran LCD :


/* USER CODE BEGIN PD */
#define COLUMNS     20       // Nombre de colonnes du LCD
#define ROWS        4        // Nombre de lignes du LCD
#define LCD_I2C_ADDRESS 0x27 // Adresse I2C de l'écran LCD (peut varier selon le module 0x3f ou 0x27)    
/* USER CODE END PD */    
        

8.3 Redirection `printf` pour l'affichage et fonction de démonstration pour l'écran.

Redirigez la sortie de printf vers l'UART et fonction de demo pour l'écran LCD :


/* USER CODE BEGIN 0 */
/**
    * @brief  Cette fonction est utilisée pour rediriger la sortie standard (printf) vers l'UART.
    * @param  ch: Caractère à transmettre.
    * @retval Le caractère transmis.
    */
int __io_putchar(int ch) {
    HAL_UART_Transmit(&huart2, (uint8_t*) &ch, 1, 0xFFFF); // Envoi du caractère via UART
    return ch;
}

/**
    * @brief  Fonction de démonstration pour le LCD.
    * @note   Cette fonction teste diverses fonctionnalités du LCD, y compris l'effacement,
    *         l'écriture de texte, le contrôle du rétroéclairage, et plus encore.
    */
void lcd_demo(void) {
    printf("--- Starting LCD Demonstration ---\r\n");
    printf("LCD Config: %dx%d @ I2C Address 0x%02X\r\n", COLUMNS, ROWS, I2C_ADDRESS);
    char line_buffer[COLUMNS + 1];      // Buffer pour construire les lignes
    lcd_clear();                        // Efface l'écran LCD
    snprintf(line_buffer, sizeof(line_buffer), "LCD Config: %dx%d", COLUMNS, ROWS); // Construit la configuration
    lcd_write_string(line_buffer);     // Écrit la configuration sur la première ligne du LCD
    lcd_set_cursor(1, 0);              // Positionne le curseur sur la deuxième ligne
    snprintf(line_buffer, sizeof(line_buffer), "Address 0x%02X", I2C_ADDRESS);
    lcd_write_string(line_buffer);     // Écrit l'adresse I2C sur la deuxième ligne
    HAL_Delay(2000);                   // Pause de 2 secondes

    // 1. Effacer l'écran
    printf("Demo: lcd_clear()...\r\n");
    lcd_clear();                        // Efface l'écran
    lcd_write_string("Demo: lcd_clear"); // Écrit un message de démonstration
    HAL_Delay(2000);                    // Pause de 2 secondes
    lcd_clear();                        // Efface à nouveau l'écran
    HAL_Delay(2000);                    // Pause de 2 secondes

    // 2. Test d'écriture sur plusieurs lignes
    printf("Demo: Multi-line text writing...\r\n");
    lcd_clear();                        // Efface l'écran
    lcd_write_string("Demo: Lines");    // Écrit un message sur la première ligne
    HAL_Delay(2000);                    // Pause de 2 secondes

    // Ligne 0
    lcd_clear();                        // Efface l'écran et positionne le curseur sur la première ligne
    snprintf(line_buffer, sizeof(line_buffer), "L0 Demo: Lines"); // Construit le message
    lcd_write_string(line_buffer);     // Écrit un message sur la première ligne
    HAL_Delay(1000);                   // Pause de 1 seconde

    // Ligne 1
    if (ROWS > 1) {                    // Vérifie si l'écran a au moins 2 lignes
        lcd_set_cursor(1, 0);          // Positionne le curseur sur la deuxième ligne
        snprintf(line_buffer, sizeof(line_buffer), "L1"); // Construit le message
        lcd_write_string(line_buffer); // Écrit "L1" sur la deuxième ligne
        HAL_Delay(1000);               // Pause de 1 seconde
    }

    // Ligne 2
    if (ROWS > 2) {                    // Vérifie si l'écran a au moins 3 lignes
        lcd_set_cursor(2, 0);          // Positionne le curseur sur la troisième ligne
        snprintf(line_buffer, sizeof(line_buffer), "L2"); // Construit le message
        lcd_write_string(line_buffer); // Écrit "L2" sur la troisième ligne
        HAL_Delay(1000);               // Pause de 1 seconde
    }

    // Ligne 3
    if (ROWS > 3) {                    // Vérifie si l'écran a au moins 4 lignes
        lcd_set_cursor(3, 0);          // Positionne le curseur sur la quatrième ligne
        snprintf(line_buffer, sizeof(line_buffer), "L3"); // Construit le message
        lcd_write_string(line_buffer); // Écrit "L3" sur la quatrième ligne
        HAL_Delay(1000);               // Pause de 1 seconde
    }
    HAL_Delay(2000);                   // Pause de 2 secondes

    // 3. Test du rétroéclairage
    printf("Demo: lcd_backlight()...\r\n");
    lcd_clear();                        // Efface l'écran
    lcd_write_string("Demo: Backlight"); // Écrit un message de démonstration
    HAL_Delay(2000);                    // Pause de 2 secondes
    lcd_backlight(0);                   // Éteint le rétroéclairage
    HAL_Delay(1000);                    // Pause de 1 seconde
    lcd_backlight(1);                   // Allume le rétroéclairage
    HAL_Delay(1000);                    // Pause de 1 seconde

    // 4. Test Display On/Off
    printf("Demo: lcd_display_off() / lcd_display_on()...\r\n");
    lcd_clear();                        // Efface l'écran
    lcd_write_string("display on/off"); // Écrit un message de démonstration
    HAL_Delay(2000);                    // Pause de 2 secondes
    lcd_display_off();                  // Éteint l'affichage
    HAL_Delay(1000);                    // Pause de 1 seconde
    lcd_display_on();                   // Rallume l'affichage
    HAL_Delay(1000);                    // Pause de 1 seconde

    // 5. Test du curseur
    printf("Demo: lcd_cursor_on() / lcd_cursor_off()...\r\n");
    lcd_clear();                        // Efface l'écran
    lcd_write_string("cursor on/off");  // Écrit un message de démonstration
    lcd_set_cursor(1, 5);               // Positionne le curseur sur la deuxième ligne, colonne 5
    HAL_Delay(2000);                    // Pause de 2 secondes
    lcd_cursor_on();                    // Active le curseur
    HAL_Delay(1500);                    // Pause de 1,5 seconde
    lcd_cursor_off();                   // Désactive le curseur
    HAL_Delay(500);                     // Pause de 0,5 seconde

    // 6. Test des caractères personnalisés
    printf("Demo: Custom Characters...\r\n");
    lcd_clear();                        // Efface l'écran
    lcd_write_string("Custom Chars");   // Écrit un message de démonstration
    uint8_t smiley[8] = {0x00, 0x0A, 0x00, 0x04, 0x11, 0x0E, 0x00, 0x00}; // Définition d'un smiley
    lcd_create_char(0, smiley);         // Crée un caractère personnalisé à l'emplacement 0
    lcd_set_cursor(1, 5);               // Positionne le curseur pour afficher le smiley
    lcd_put_custom_char(0);             // Affiche le smiley
    HAL_Delay(2000);                    // Pause de 2 secondes

    // 7. Test de défilement à gauche
    printf("Demo: Scrolling Left ...\r\n");
    lcd_clear();                        // Efface l'écran
    lcd_write_string("Scroll Left <<<");// Écrit un message pour le défilement
    for (int i = 0; i < COLUMNS; i++) { // Boucle pour défilement à gauche
        lcd_scroll_display_left();      // Défile l'affichage vers la gauche
        HAL_Delay(500);                 // Pause de 0,5 seconde
    }
    HAL_Delay(2000);                    // Pause de 2 secondes

    // 8. Test de défilement à droite
    printf("Demo: Scrolling right...\r\n");
    lcd_clear();                        // Efface l'écran
    lcd_write_string("Scroll right >>>");// Écrit un message pour le défilement
    for (int i = 0; i < COLUMNS; i++) { // Boucle pour défilement à droite
        lcd_scroll_display_right();     // Défile l'affichage vers la droite
        HAL_Delay(500);                 // Pause de 0,5 seconde
    }
    HAL_Delay(2000);                    // Pause de 2 secondes

    // Message final
    printf("--- LCD Demonstration Finished ---\r\n");
    lcd_clear();                        // Efface l'écran
    lcd_write_string("Demo Finished!"); // Écrit un message final
    HAL_Delay(3000);                    // Pause de 3 secondes
}
/* USER CODE END 0 */
        

Cette fonction de démonstration teste diverses fonctionnalités de la bibliothèque STM32_I2C_LCD, y compris l'effacement de l'écran, l'écriture de texte sur plusieurs lignes, le contrôle du rétroéclairage, et plus encore.

8.4 Initialiser l'écran LCD et lancer la fonction de demonstration.

Initialisez l'écran LCD et lancez la fonction de démonstration dans votre fonction principale :


/* USER CODE BEGIN 2 */
HAL_Delay(250);                         // Délai pour les initialisations
printf("Test LIB LCD\n\r");                       // Écriture dans la console série

// Initialisation de l'écran LCD
HAL_StatusTypeDef lcd_status = lcd_init(&hi2c1, COLUMNS, ROWS, I2C_ADDRESS); // Initialisation de l'écran

if (lcd_status != HAL_OK) {
    printf("LCD Init Failed! Status: %d\r\n", lcd_status);
    Error_Handler(); // Bloquer si l'initialisation du LCD échoue
} else {
    printf("LCD Init OK!\r\n");
    lcd_backlight(1); // Allumer le rétroéclairage (ne retourne pas de statut, s'applique à la prochaine commande)

    // Exécuter la séquence de démonstration simplifiée
    lcd_demo(); // Appel de la fonction de démonstration LCD
}
/* USER CODE END 2 */
        

Cette partie du code initialise l'écran LCD et lance la fonction

9. Dépannage

Si l'écran ne fonctionne pas :

  • Vérifiez les connexions I2C.
  • Assurez-vous que l'adresse I2C est correcte.
  • Ajoutez des résistances pull-up sur les lignes SDA et SCL si nécessaire.

10. Conclusion

La bibliothèque STM32_I2C_LCD vise à simplifier l'utilisation des écrans LCD I2C avec les microcontrôleurs STM32 en encapsulant la complexité de la communication I2C. En suivant ce tutoriel, vous devriez être en mesure de configurer et d'utiliser un écran LCD dans vos projets STM32.