Skip to content

Programmation sur carte embaquée MSP432

Sujet inspiré de sujets préparés par Yves Blanchard

Environnement Code Composer Studio

Les TP se feront sous Windows dans l'environnement de Code Composer Studio, outil de développement gratuit fournit par Texas Instrument et basé sur la plateforme ECLIPSE.

Ouvrir Code Composer Studio (icone sur le bureau ou menu programme de Windows). L'outil va commencer par vous demander l'emplacement de son répertoire de travail (Select a directory as workspace). Choisir un emplacement (répertoire au départ vide) sur votre compte ou sur le disque local, mais ne pas oublier dans ce cas de faire une copie sur votre disque réseau à la fin de la séance de TP.

Lors de la première utilisation l'outil va s'ouvrir sur un environnement vide de tout projet. La création d'un nouveau projet se fait en utilisant l'icône New Project ou par le menu File / New / CCS Project.

Choisir les paramètres suivants :

  • Target : MSP432 family
  • Circuit : MSP432P401R
  • Connection : Texas Instrument XDS 110
  • Project name : 3ELE1TP5
  • Use default location : oui
  • Compiler version : TI v20.2.4.LTS (ou version plus récente)
  • Empty Project (sans main)

Il faut ensuite créer un premier fichier source en faisant un clic droit sur le nom du projet et en sélectionnant New / Source File

Prendre comme nom de fichier source main.c et prendre le <None> comme Template. Le microcontrôleur est utilisé avec ses réglages par défaut, pour se focaliser sur l'utilisation des ports d'entrées sorties numériques.

Allumage de la led rouge

L'objectif dans un premier temps va être de réussir à configurer un port en sortie pour faire clignoter une des leds de la carte qui sera le premier signe que votre programme tourne effectivement sur la cible embarquée.

La documentation de la carte de développement MSP432P401R simplelink launchpad permet de savoir que les boutons et leds de la carte sont connectés sur les ports suivants du MSP432P401R :

  • Bouton 1 : Port 1, bit 1
  • Bouton 2 : Port1, bit 4
  • Led rouge : Port 1, bit 0
  • Led colorée
    • Rouge : Port 2, bit 0
    • Vert : Port 2, bit 1
    • Bleu : Port 2, bit 2

Pour allumer la led, en partant d’un microcontrôleur ayant une configuration par défaut il faut donc :

  1. Définir des variables globales (pour une utilisation simplifiée dans toutes les fonctions) pointant sur les registres du port numérique d’E/S ;
  2. Utiliser, dans le main(), ces variables pour initialiser avec les bonnes valeurs les registres pour configurer le bit 0 du port 1 en sortie ;
  3. Initialiser le bit 0 du registre du port 1 de sortie avec la valeur que l’on veut mettre sur la led (1/0 allumage/extinction).

Cette configuration ayant été expliquée dans le cours.

Vous pouvez vous baser sur le code suivant (chaque ligne doit être comprise) :

/* Clignotement de la led à la fréquence par defaut apres reset
Carte Simple link MSP432
28/02/2022 - Y. Blanchard
*/

#include <stdint.h>

/* delai pour temps d'allumage/extinction led */
const unsigned int tempo = 256000;

/* GPIO */
#define PIO_BASE 0x40004C00

volatile uint8_t * const P1_OUT = (uint8_t *) (PIO_BASE + 0x02);
volatile uint8_t * const P1_DIR = (uint8_t *) (PIO_BASE + 0x04);
volatile uint8_t * const P1_SEL0 = (uint8_t *) (PIO_BASE + 0x0A);
volatile uint8_t * const P1_SEL1 = (uint8_t *) (PIO_BASE + 0x0C);

#define LEDR 0
const uint8_t LEDR_mask = 1 << LEDR;

int main()
{
    /*
        GPIO Port1
        Red led P1 bit 0
    */
    *P1_DIR |= LEDR_mask;  /* Configuration en sortie */
    *P1_SEL1 &= ~LEDR_mask;  /* SEL1=SEL2=0 : choix de sortie venant de P1_OUT */
    *P1_SEL0 &= ~LEDR_mask;

    /* Clignotement de la led */
    while (1)
    {
        unsigned int i;
        *P1_OUT &=  ~LEDR_mask; /* Extinction */
        for (i = 0; i < tempo ; i++) {  }
        *P1_OUT |= LEDR_mask; /* Allumage */
        for (i = 0; i < tempo; i++)  {  }
    }

    return 0;
}
  • Une fois le fichier source écrit, la génération de l'exécutable se fait par clic droit sur le projet puis Build Project. Les messages liés à la compilation vont s'afficher dans la console, y compris les avertissements et erreurs. Il est possible d'avoir spécifiquement la liste des erreurs et avertissement dans une fenêtre récapitulant les problèmes. Si celle-ci n'apparait pas, il faut aller dans le menu View et sélectionner Problems.

  • Lorsqu'il n'y a plus d'erreurs de compilation, la mise au point sur le microcontrôleur peut démarrer : Dans la fenêtre projet, clic droit sur le projet à tester puis Debug as -> Code Composer Debug Session. Ou utiliser l'icône avec un insecte (remarque : si la carte MSP432 n'est pas connectée cela a peu de chance de fonctionner).

  • Si tout se passe bien, l'environnement de mise au point s'ouvre. Le programme exécutable est téléchargé sur le circuit mais pas démarré. Pour le démarrer il faut cliquer sur la flèche verte qui se trouve dans la barre d'icone (commande resume, touche de fonction F8).

  • Le programme s'exécute et la led clignote. Débranchez la carte et rebranchez là. Que constatez-vous ? Qu'en déduisez- vous sur la zone mémoire ou a été chargé le programme lors du téléchargement ? Faite quelques essais pour avoir un clignotement avec une période de 1 seconde, puis 2 secondes, 3 secondes. Est-ce un réglage très précis ?

Contrôle par les boutons

En vous basant sur le template de code ci dessous, compléter le programme pour que la ledr soit par défaut éteinte et s'allume uniquement quand le bouton 1 (connecté sur P1.1) est appuyé. Pour l'instant, le programme lit les valeurs des boutons par scrutation.

/*
 * TP1 Ex. 2 - A finaliser
 *
 *  Created on: 28/01/2021
 *      Author: Y. Blanchard
 */

#include <stdint.h>

#define PIO_BASE 0x40004C00
const volatile uint8_t * const P1_IN = (uint8_t *)(PIO_BASE + 0x0);
volatile uint8_t * const P1_OUT = (uint8_t*)(PIO_BASE + 2);
volatile uint8_t * const P1_DIR = (uint8_t*)(PIO_BASE + 4);
volatile uint8_t * const P1_SEL0 = (uint8_t*)(PIO_BASE + 0xA);
volatile uint8_t * const P1_SEL1 = (uint8_t*)(PIO_BASE + 0xC);
volatile uint8_t * const P1_REN = (uint8_t*)(PIO_BASE + 0x6);

/* Masque pour la ledr et le bouton 1 */
#define LEDR 0
#define PB1 1
const uint8_t LEDR_mask = 1 << LEDR;
const uint8_t PB1_mask = 1 << PB1;

int main() {
/* Configuration pour la  LEDR */
    *P1_DIR = *P1_DIR | LEDR_mask;
    *P1_SEL1 = *P1_SEL1 & (~LEDR_mask);
    *P1_SEL0 = *P1_SEL0 & (~LEDR_mask);
/* Configuration a rajouter pour l'interrupteur 1     */
/*   Modification a faire : P1_DIR, P1_SEL1, P1_SEL0  */
/*   Configuration a faire : P1_REN, P1_OUT           */


    while (1) {
        /* Lire port 1 et tester bit du bouton poussoir
        Si bit a 1 alors le bouton n'est pas appuye et il faut eteindre la led, sinon bouton appuye et led doit etre allume
        Allumer/eteindre la led : ecriture du bit correspondant du port1 à 1 ou 0
        */
        if ()
        else
    }

    return 0;
}

Afin d'avoir un code propre et évolutif, il faut bien décomposer l'initialisation correspondant à chaque périphérique. D'abord initialisation pour la led, puis initialisation pour le bouton. Il est possible de faire les deux initialisations à la fois, c'est ce qui fait le code le plus compact et performant, mais il est cependant préférable de commencer en préservant la lisibilité, quitte à revenir pour optimiser les parties critiques par la suite.

  • Modifiez votre programme pour qu'un appui allume la led, et un second appui l'éteigne, et ainsi de suite.
  • Ajoutez à ce qu'il faut pour l'utilisation du bouton 2, qui est un périphérique toujours du port 1, mais sur la ligne 4
    • la led s'allume pour un appui sur le bouton 1, et s'éteind par un appui sur le bouton 1

Code plus propre avec une bibliothèque réutilisable

Ajoutez un fichier msp432.h à votre projet à partir du code ci dessous fournit :

#ifndef _MSP432_H
#define _MSP432_H

#include <stdint.h>

/* macros : le compilateur fera des chercher / remplacer, ce ne sont pas des fonctions ! */
#define set_bit(X,Y) (X|=(uintmax_t)1<<Y)
#define clr_bit(X,Y) (X &= ~((uintmax_t)1<<Y))
#define tog_bit(X,Y) (X ^= (uintmax_t)1<<Y)
#define rd_bit(X,Y) ((X >> Y) &1)

/* extern car les pointeurs seront définis dans msp432.c */
extern volatile const uint8_t * const P1_IN;
extern volatile uint8_t * const P1_OUT   ;
extern volatile uint8_t * const P1_DIR   ;
extern volatile uint8_t * const P1_SEL0  ;
extern volatile uint8_t * const P1_SEL1  ;
extern volatile uint8_t * const P1_REN   ;

#define LEDR  0
#define PB1  1
#define PB2 4

/* si v vaut 1, la led est init on, sinon init off */
void init_ledr(unsigned char v);

/* init les deux bouttons */
void init_PB(void);

#endif

Expliquez le fonctionnement des macros (lignes 3-6). Transformez votre main.c pour implémenter les deux fonctions déclarées dans le .h, et pour utiliser les macros et ces fonctions. Tout ce qui n'est plus utile doit disparaitre du .c.