Mise en oeuvre de la carte STM32 NUCLEO (F401RE)

L’objectif est de mettre en oeuvre la carte STM32 NUCLEO (F401RE) et l’environnement de développement mbed.

La carte STM32 NUCLEO (F401RE)

La carte STM32 NUCLEO-F401RE est une carte de développement fabriquée par STMicroelectronics autour d’un micro-contrôleur ARM Cortex 32 bits STM32. Toutes les cartes Nucleo de STMicroelectronics sont prises en charge par la plateforme de développement mbed. Elle est commercialisée pour un prix d’environ 10 euros !

Quelques caractéristiques :

  • Micro-contrôleur : ARM Cortex 32 bits STM32 84 MHz
  • Mémoire flash : 512 KB octets (et 96 KB SRAM)
  • 2 types d’extensions disponibles : Arduino Uno V3 et ST Morpho
  • ST-LINK/V2-1 (débogage/programmation)
  • Alimentation : 3.3V, 5V, 7 - 12V
  • Trois Leds : communication USB (LD1), libre pour l’utilisateur (LD2), alimentation (LD3)
  • Deux boutons : libre pour l’utilisateur, RESET
  • USB : port COM virtuel, stockage de masse (mass storage) et débogage

Et aussi :

  • 12-bit ADC with 16 channels
  • RTC
  • USART/UART (3)
  • I2C (3)
  • SPI (4)

La carte Nucleo propose de 2 types d’extensions :

  • Arduino Uno V3

  • ST Morpho

Site officiel : www.st.com

Documentation : nucleo-f401re.pdf

La plateforme de développement mbed

mbed est un IDE (Integrated Development Environment) ou EDI (Environnement de Développement Intégré) en ligne. Il nécessite donc une connexion Internet et un navigateur web.

Site : https://developer.mbed.org/

Rapide tour d’horizon :

  • Hardware : Boards (liste toutes les cartes compatibles) et Components (base de données des composants existants par catégorie)
  • Documentation (évidemment la doc sur l’API) et Cookbook (livre de recettes)
  • Code (partage de code par la communauté)
  • Questions (FAQ) et Forum
  • Log In/Signup
  • Compiler (espace de travail de développement)

La première étape pour pouvoir utiliser mbed consiste à s’enregistrer (Log In/Signup).

Pour développer avec la carte Nucleo, il y a 2 façons de procéder :

  • Cliquez sur Hardware puis Boards. Sélectionnez STMicroelectronics puis sur NUCLEO-F401RE. Pour finir cliquez sur Add to your mbed Compiler :

  • Ou branchez votre carte sur un port USB. Aller dans le dossier NUCLEO (comme une clef USB) et ouvrir le fichier mbed.htm dans un navigateur.

Premier programme : led clignotante

Objectifs :

  • prendre en main l’environnement mbed
  • créer et compiler un programme
  • déployer et tester le programme

Étapes par étapes :

Créer une nouvelle application en cliquant sur New puis choisir comme modèle (template) “Blinky LED …” et donner un nom à votre projet :

Vous pouvez modifier le code dans l’éditeur :

Pour tester, il suffit de compiler … d’enregistrer le binaire fourni (extension .bin) et de le copier dans le dossier NUCLEO.

Bonus : Essayez maintenant de créer un programme pour tester le bouton USER (bleu sur la carte) à partir du modèle “Read the board user button state”.

Nouveau programme : SOS (morse)

Objectifs :

  • créer un programme vierge
  • importer et exploiter des bibliothèques

Étapes par étapes :

Créer une nouvelle application en cliquant sur New puis choisir comme modèle (template) “Empty Program” et donner un nom à votre projet :

Ajouter un nouveau fichier avec New File :

Puis éditez le programme suivant :

On obtient une erreur à la compilation (ce qui est normal car la bibliothèque mbed n’a pas été intégrée au projet et donc le fichier mbed.h est introuvable) :

On peut la corriger en cliquant sur “Fix it!” ce qui va nous permettre d’importer la bibliothèque mbed :

Maintenant, on peut compiler avec succès.

On va maintenant importer une nouvelle bibliothèque à notre projet en cliquant sur Import, puis on recherche “morse” :

On séléctionne la bibliothèque MorseGenerator, on clique sur Import! et on importe :

La classe MorseGenerator a été ajoutée au projet et on peut accéder directement à sa documentation :

En utilisant la documentation (on peut utiliser le copier/coller), on édite le programme suivant :

On compile et on teste sur la carte !

Travail demandé : communiquer avec le port série

Introduction

La transmission série est un mode de transmission de données dans lequel les éléments d’information se succèdent les uns après les autres sur une seule voie entre deux points. Elle s’oppose à la transmission parallèle, qui transmet simultanément les éléments d’information sur plusieurs voies.

La transmission série domine dès que les composants ou périphériques à relier sont à quelque distance. L’ensemble des télécommunications s’établit sur des liaisons série.

La transmission série est très présente dans le monde industriel :

  • pour relier des capteurs/actionneurs (sensor bus) ou des composants de bas niveau, on utilise des technologies comme le bus TWI/I2C, 1-Wire, AS-i, …

  • pour relier des périphériques (appareils divers, système de commande, …), on utilise des bus de terrain (field bus) comme le bus CAN, DMX, les liaisons RS232 ou RS485, …

La transmission série se fait généralement par trames et nécessite la mise en oeuvre de protocole.

Remarque : Communiquer consiste à transmettre des informations, mais tant que les interlocuteurs ne lui ont pas attribué un sens, il ne s’agit que de données et pas d’information. Les interlocuteurs doivent donc non seulement parler un langage commun mais aussi maîtriser des règles minimales d’émission et de réception des données. C’est le rôle d’un protocole de s’assurer de tout cela.

Mise en oeuvre

La carte Nucleo dispose de 3 ports série UART (Universal Asynchronous Receiver Transmitter) : Serial1, Serial2 et Serial 6. Le port Serial2 est déjà utilisé par ST-LINK. On va donc utiliser le port Serial1 :

  • Serial1 RX : broche D2 (Arduino Headers)
  • Serial1 TX : broche D8 ou D10 (Arduino Headers)

On va utiliser un adaptateur USB/RS232 (TTL) pour relier la carte Nucleo et le PC. La prise USB contient un convertisseur USB <-> Série (pl2303) avec un cable terminé par 4 fils :

  • Rouge : Alimentation (+5V) fourni par le port USB (non utilisé)
  • Noir : Masse (GND)
  • Blanc : TX
  • Green : RX

On va donc réaliser le cablage suivant :

Remarque : détection sous Linux.

Côté PC, on utilisera un émulateur de terminal comme cutecomm ou minicom sous Linux ou HyperTerminal ou Teraterm sous Windows.

Pour accèder au port série, on utilise la classe Serial à laquelle on précise en paramètre les broches utilisées pour les lignes TX et RX :

Il est possible de paramètrer le port série :

Pour émettre des données, il existe plusieurs méthodes : putc(), puts(), printf(), write().

Pour recevoir des données, il existe aussi plusieurs méthodes : getc(), read(). On vérifiera préalablement la présence d’octets à lire avec readable().

A vous de jouer

Vous devez écrire un programme qui communique avec votre PC par une liaison USB/RS232. Le programme doit :

  • envoyer une chaîne de caractère “Appui bouton” à chaque fois que le bouton USER est pressé. On ajoutera dans la chaîne l’état de led : “Appui bouton - Led x”.
  • recevoir un caractère de commande de la led (‘a’ pour l’allumer et ‘e’ pour l’éteindre)

Remarque : il vous est possible d’exporter votre projet ou tout simplement un fichier (main.cpp par exemple) en cliquant avec le bouton droit :

La plateforme de développement PlatformIO

Liens tutoriels :

La carte STM32 NUCLEO (F401RE) est supportée par PlatformIO avec le modèle STM32F401RE (96k RAM. 512k Flash). Différents frameworks sont disponibles dont Arduino.

Le fichier platformio.ini sera alors :

La carte étant branchée sur le port USB ST-LINK, on utilisera le protocole stlink et PlatformIO sélectionnera alors OpenOCD :

Processing genericSTM32F401RE (platform: ststm32; board: genericSTM32F401RE; framework: arduino)
------------------------------------------------------------------------------------------------
CONFIGURATION: https://docs.platformio.org/page/boards/ststm32/genericSTM32F401RE.html
PLATFORM: ST STM32 (15.1.0) > STM32F401RE (96k RAM. 512k Flash)
HARDWARE: STM32F401RET6 84MHz, 96KB RAM, 512KB Flash
...
Building in release mode
Compiling .pio/build/genericSTM32F401RE/src/main.cpp.o
Linking .pio/build/genericSTM32F401RE/firmware.elf
Checking size .pio/build/genericSTM32F401RE/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [          ]   0.9% (used 856 bytes from 98304 bytes)
Flash: [          ]   2.6% (used 13736 bytes from 524288 bytes)
Configuring upload protocol...
AVAILABLE: blackmagic, dfu, jlink, serial, stlink
CURRENT: upload_protocol = stlink
Uploading .pio/build/genericSTM32F401RE/firmware.elf
xPack OpenOCD x86_64 Open On-Chip Debugger 0.11.0+dev (2021-10-16-21:15)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
debug_level: 1

hla_swd
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08000060 msp: 0x20018000
** Programming Started **
** Programming Finished **
** Verify Started **
** Verified OK **
** Resetting Target **
shutdown command invoked
==== [SUCCESS] Took 2.64 seconds ===

Le programme peut aussi être fabriqué en ligne de commande (CLI) à partir du terminal :

On obtient alors :

Le firmware obtenu peut être directement copié dans le dossier NUCLEO (l’espace flash est monté comme une clé USB) :

Remarque : sous GNU/Linux, il est probablement nécessaire de configurer udev pour les droits d’accès au périphérique (99-platformio-udev.rules).

Exemple mettant en oeuvre la LED et le bouton embarqués sur la carte STM32 NUCLEO :

  • LED verte LD2 : connecteur ARDUINO (signal D13) -> PA5 (broche 21) des E/S du microcontrôleur STM32
  • Bouton B1 : PC13 (broche 2) des E/S du microcontrôleur STM32

Dans PlatformIO, il existe aussi la carte ST Nucleo F401RE qui supporte en plus le framework Mbed.

Le fichier platformio.ini sera alors :

Exemples avec mbed :

  • Clignotement de la LED
  • Avec le bouton
  • Interruption sur le bouton
  • Timer, Timeout et Ticker
#include "mbed.h"

using namespace std::chrono;

InterruptIn mybutton(USER_BUTTON);
DigitalOut myled(LED1);

Timer timer;
Timeout timeout;
Ticker ticker;

std::chrono::microseconds t(3000000);

typedef std::chrono::duration<int,std::milli> millisecondes;
//std::chrono::duration<uint32_t, std::milli> tempo(200);
millisecondes tempo(200);

// Pour Ticker
void periode()
{
  tempo = std::chrono::milliseconds(500);
}

// Pour Timeout
void change()
{
  tempo = std::chrono::milliseconds(1000); // 1 sec
}

// Bouton
void pressed()
{
  if(tempo == std::chrono::milliseconds(200))
  {
    tempo = std::chrono::milliseconds(1000); // 1 sec
  }
  else
  {
    tempo = std::chrono::milliseconds(200); // 200 ms
  }
}

int main()
{
    mybutton.fall(&pressed);
    timeout.attach(&change, 3s); // au bout de 3s, passe en clignotement lent
    ticker.attach(&periode, 5s); // toutes les 5s, cf. detach()

    timer.start();
    ThisThread::sleep_for(100ms);
    timer.stop();
    printf("timer = %llu secondes\n", duration_cast<seconds>(timer.elapsed_time()).count());
    printf("timer = %llu millisecondes\n", duration_cast<milliseconds>(timer.elapsed_time()).count());
    //printf("timer = %d millisecondes\n\r", timer.read_ms()); // obsolete
    printf("timer = %llu microsecondes\n", duration_cast<microseconds>(timer.elapsed_time()).count());
    //printf("timer = %d microsecondes\n\r", timer.read_us()); // obsolete

    timer.start();
    ThisThread::sleep_for(50ms);
    timer.stop();
    printf("timer = %llu millisecondes\n", duration_cast<milliseconds>(timer.elapsed_time()).count());

    timer.reset();
    timer.start();
    ThisThread::sleep_for(100ms);
    timer.stop();
    printf("timer = %llu millisecondes\n", duration_cast<milliseconds>(timer.elapsed_time()).count());

    while (1)
    {
      myled = !myled;
      ThisThread::sleep_for(tempo);
    }
}

Glossaire

MCU
MCU (MicroController Unit) est un microcontrôleur (µc ou uc). C’est un circuit intégré qui rassemble les éléments essentiels d’un ordinateur : processeur, mémoires (mémoire morte pour le programme, mémoire vive pour les données), unités périphériques et interfaces d’entrées-sorties. Les microcontrôleurs se caractérisent par un plus haut degré d’intégration, une plus faible consommation électrique, une vitesse de fonctionnement plus faible et un coût réduit par rapport aux microprocesseurs polyvalents utilisés dans les ordinateurs personnels. Les microcontrôleurs sont fréquemment utilisés dans les systèmes embarqués. Lire : https://fr.wikipedia.org/wiki/Microcontr%C3%B4leur.
Système embarqué
Un système embarqué est défini comme un système électronique et informatique autonome, souvent temps réel, spécialisé dans une tâche bien précise. Le terme désigne aussi bien le matériel informatique que le logiciel utilisé. Ses ressources sont généralement limitées. Cette limitation est généralement d’ordre spatial (encombrement réduit) et énergétique (consommation restreinte).
ARM
ARM est une société britannique spécialisée dans le développement d’architectures 32 bits de type RISC. Fondée sous la forme d’une coentreprise par Acorn Computers, Apple Computer (maintenant Apple Inc.) et VLSI Technology, ARM développe également un grand nombre de blocs de propriété intellectuelle (IP). Elle est basée sur un modèle économique particulier de la microélectronique : la conception de propriétés intellectuelles (Intellectual Properties). Ainsi il n’est pas possible d’acheter un processeur ARM comme c’est le cas pour Intel. Les cœurs ARM sont intégrés au sein de systèmes sur puces (SoC) complets. Les cœurs de processeurs ARM sont très présents dans les systèmes embarqués (téléphone mobile, console portable, tablette électronique).
Architecture ARM
Les architectures ARM sont des architectures matérielles RISC 32 bits (ARMv1 à ARMv7) et 64 bits (ARMv8)1 développées par ARM Ltd depuis 1990 et introduites à partir de 1983 par Acorn Computers. Dotés d’une architecture relativement plus simple que d’autres familles de processeurs, et bénéficiant d’une faible consommation, les processeurs ARM sont devenus dominants dans le domaine de l’informatique embarquée, en particulier la téléphonie mobile et les tablettes. Ces processeurs sont fabriqués sous licence par un grand nombre de constructeurs.
Mémoire Flash
La mémoire flash est une mémoire de masse à semi-conducteurs ré-inscriptible, c’est-à-dire une mémoire possédant les caractéristiques d’une mémoire vive mais dont les données ne disparaissent pas lors d’une mise hors tension. Ainsi, la mémoire flash stocke les bits de données dans des cellules de mémoire, mais les données sont conservées en mémoire lorsque l’alimentation électrique est coupée. La technique flash se décline sous deux principales formes : flash NOR et NAND, selon le type de porte logique utilisée pour chaque cellule de stockage. Sa durée de vie est limitée par le nombre de cycles d’écriture.
EDI
Un EDI (ou IDE pour Integrated Development Environment) est un environnement de développement pouvant contenir de nombreux outils comme : un éditeur de texte, une chaîne de compilation, la documentation en ligne, la gestion de version et un débogueur (debugger) qui permet de trouver des erreurs et de les éliminer. Il existe de nombreux EDI (ou IDE) pour le langage C/C++ : Visual C++, Builder, Qt Creator, Code::Blocks, devcpp, eclipse, etc… Ils peuvent être très pratique en améliorant surtout la productivité dans un cadre professionnel.
Morse
L’alphabet morse ou code morse, est un code (inventé en 1832) permettant de transmettre un texte à l’aide de séries d’impulsions courtes et longues, qu’elles soient produites par des signes, une lumière, un son ou un geste. Le code morse est considéré comme le précurseur des communications numériques.
Terminal
Un terminal est le nom d’un logiciel d’émulation de terminal. Un émulateur de terminal, aussi appelé console virtuelle ou terminal virtuel, est un logiciel qui émule le fonctionnement d’un terminal informatique ce qui permet d’interagir avec les commandes Unix lorsqu’on utilise un environnement graphique.
UART
UART (Universal Asynchronous Receiver Transmitter) est le composant utilisé pour faire la liaison entre l’ordinateur et le port série. L’ordinateur envoie les données en parallèle (autant de fils que de bits de données). Il faut donc transformer ces données pour les faire passer à travers une liaison série qui utilise un seul fil pour faire passer tous les bits de données.
Trame UART
Une trame UART est constituée des bits suivants : un bit de start toujours à 0 (servant à la synchronisation du récepteur), les données (la taille peut varier généralement entre 5 et 9 bits), éventuellement un bit de parité paire ou impaire et un bit de stop toujours à 1 (la durée peut varier entre 1, 1,5 et 2 temps bit). Les vitesses de transmission sont normalisées par multiples et sous-multiples de 9600 bauds, l’unité baud correspondant à un bit par seconde.

RS232
RS-232 (ou RS-232) est une norme standardisant une voie de communication de type série. Disponible sur presque tous les PC depuis 1981 jusqu’au milieu des années 2000, il est communément appelé le « port série ». Sur les systèmes d’exploitation MS-DOS et Windows, les ports RS-232 sont désignés par les noms COM1, COM2, etc. Cela leur a valu le surnom de « ports COM », encore utilisé de nos jours. Les liaisons RS-232 sont fréquemment utilisées dans l’industrie pour connecter différents appareils électroniques (automate, appareil de mesure, etc.).
RS485
RS485 (ou RS-485) est une norme qui définit les caractéristiques électriques de la couche physique d’une interface numérique sérielle utilisée dans de nombreux réseaux industriels (Modbus, Profibus, …). Ses caractéristiques essentielles sont : liaison multi-point permettant d’interconnecter plusieurs dispositifs (jusqu’à 32 émetteurs et 32 récepteurs), bus informatique cablé avec 2 fils (en half duplex) ou 4 fils (full duplex), distance maximale de l’ordre du kilomètre en mode différentiel (qui permet d’obtenir une meilleur tolérance aux perturbations) et débit élévé jusqu’à 10Mbits/s.
Parité
Le bit de PARITÉ (facultatif) est un bit généré lors de l’émission et testé lors de la réception pour détecter une erreur de transmission. La parité est paire (even) lorsque le nombre de bits (donnée + parité) est pair. La parité est impaire (odd) lorsque le nombre de bits (donnée + parité) est impair.
Simplex
L’exploitation de la ligne se fait en mode unidirectionnel.
Half Duplex
La transmission est possible dans les deux sens mais pas simultanément.
Full Duplex
L’exploitation de la ligne se fait en mode bidirectionnel simultané sur le même support physique.

Annexe : Détection USB/RS232

  • Sous Linux :
$ dmesg
...
[85318.556891] usb 3-14: new full-speed USB device number 21 using xhci_hcd
[85318.573600] usb 3-14: New USB device found, idVendor=067b, idProduct=2303
[85318.573610] usb 3-14: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[85318.573615] usb 3-14: Product: USB-Serial Controller
[85318.573619] usb 3-14: Manufacturer: Prolific Technology Inc.
[85318.574320] pl2303 3-14:1.0: pl2303 converter detected
[85318.575054] usb 3-14: pl2303 converter now attached to ttyUSB0

$ lsusb
...
Bus 003 Device 021: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port

$ ls -l /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 0 mai   27 10:01 /dev/ttyUSB0

$ sudo chmod 666 /dev/ttyUSB0

$ sudo vim /etc/udev/rules.d/51-usb.rules
SUBSYSTEMS=="usb", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", MODE:="0666"

Retour au sommaire